    001/*
    002    Licensed to the Apache Software Foundation (ASF) under one
    003    or more contributor license agreements.  See the NOTICE file
    004    distributed with this work for additional information
    005    regarding copyright ownership.  The ASF licenses this file
    006    to you under the Apache License, Version 2.0 (the
    007    "License"); you may not use this file except in compliance
    008    with the License.  You may obtain a copy of the License at
    009
    010       http://www.apache.org/licenses/LICENSE-2.0
    011
    012    Unless required by applicable law or agreed to in writing,
    013    software distributed under the License is distributed on an
    014    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015    KIND, either express or implied.  See the License for the
    016    specific language governing permissions and limitations
    017    under the License.
    018 */
    019package org.apache.wiki.auth.acl;
    020
    021import org.apache.wiki.api.core.AclEntry;
    022
    023import java.io.Serializable;
    024import java.security.Permission;
    025import java.security.Principal;
    026import java.util.ArrayList;
    027import java.util.Enumeration;
    028import java.util.List;
    029import java.util.Vector;
    030
    031
    032/**
    033 * JSPWiki implementation of an Access Control List.
    034 *
    035 * @since 2.3
    036 */
    037public class AclImpl implements Acl, Serializable {
    038
    039    private static final long serialVersionUID = 1L;
    040    private final Vector< AclEntry > m_entries = new Vector<>();
    041
    042    /**
    043     * Constructs a new AclImpl instance.
    044     */
    045    public AclImpl() {
    046    }
    047
    048    /** {@inheritDoc} */
    049    @Override
    050    public Principal[] findPrincipals( final Permission permission ) {
    051        final List< Principal > principals = new ArrayList<>();
    052        final Enumeration< AclEntry > entries = aclEntries();
    053        while( entries.hasMoreElements() ) {
    054            final AclEntry entry = entries.nextElement();
    055            final Enumeration< Permission > permissions = entry.permissions();
    056            while( permissions.hasMoreElements() ) {
    057                final Permission perm = permissions.nextElement();
    058                if( perm.implies( permission ) ) {
    059                    principals.add( entry.getPrincipal() );
    060                }
    061            }
    062        }
    063        return principals.toArray( new Principal[0] );
    064    }
    065
    066    private boolean hasEntry( final AclEntry entry ) {
    067        if( entry == null ) {
    068            return false;
    069        }
    070
    071        for( final AclEntry e : m_entries ) {
    072            final Principal ep = e.getPrincipal();
    073            final Principal entryp = entry.getPrincipal();
    074
    075            if( ep == null || entryp == null ) {
    076                throw new IllegalArgumentException( "Entry is null; check code, please (entry=" + entry + "; e=" + e + ")" );
    077            }
    078
    079            if( ep.getName().equals( entryp.getName() ) ) {
    080                return true;
    081            }
    082        }
    083
    084        return false;
    085    }
    086
    087    /** {@inheritDoc} */
    088    @Override
    089    public synchronized boolean addEntry( final AclEntry entry ) {
    090        if( entry.getPrincipal() == null ) {
    091            throw new IllegalArgumentException( "Entry principal cannot be null" );
    092        }
    093
    094        if( hasEntry( entry ) ) {
    095            return false;
    096        }
    097
    098        m_entries.add( entry );
    099
    100        return true;
    101    }
    102
    103    /** {@inheritDoc} */
    104    @Override
    105    public synchronized boolean removeEntry( final AclEntry entry ) {
    106        return m_entries.remove( entry );
    107    }
    108
    109    /** {@inheritDoc} */
    110    @Override
    111    public Enumeration< AclEntry > aclEntries() {
    112        return m_entries.elements();
    113    }
    114
    115    /** {@inheritDoc} */
    116    @Override
    117    public AclEntry getAclEntry( final Principal principal ) {
    118        return m_entries.stream().filter(entry -> entry.getPrincipal().getName().equals(principal.getName())).findFirst().orElse(null);
    119
    120    }
    121
    122    /** {@inheritDoc} */
    123    @Override
    124    public boolean isEmpty() {
    125        return m_entries.isEmpty();
    126    }
    127
    128    /** {@inheritDoc} */
    129    @Override
    130    public String toString() {
    131        final StringBuilder sb = new StringBuilder();
    132        for( final AclEntry entry : m_entries ) {
    133            final Principal pal = entry.getPrincipal();
    134            if( pal != null ) {
    135                sb.append( "  user = " ).append( pal.getName() ).append( ": " );
    136            } else {
    137                sb.append( "  user = null: " );
    138            }
    139            sb.append( "(" );
    140            for( final Enumeration< Permission > perms = entry.permissions(); perms.hasMoreElements(); ) {
    141                final Permission perm = perms.nextElement();
    142                sb.append( perm.toString() );
    143            }
    144            sb.append( ")\n" );
    145        }
    146        return sb.toString();
    147    }
    148
    149}
    150