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[ principals.size() ] );
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        for( final AclEntry entry : m_entries ) {
119            if( entry.getPrincipal().getName().equals( principal.getName() ) ) {
120                return entry;
121            }
122        }
123
124        return null;
125    }
126
127    /** {@inheritDoc} */
128    @Override
129    public boolean isEmpty() {
130        return m_entries.isEmpty();
131    }
132
133    /** {@inheritDoc} */
134    @Override
135    public String toString() {
136        final StringBuilder sb = new StringBuilder();
137        for( final AclEntry entry : m_entries ) {
138            final Principal pal = entry.getPrincipal();
139            if( pal != null ) {
140                sb.append( "  user = " ).append( pal.getName() ).append( ": " );
141            } else {
142                sb.append( "  user = null: " );
143            }
144            sb.append( "(" );
145            for( final Enumeration< Permission > perms = entry.permissions(); perms.hasMoreElements(); ) {
146                final Permission perm = perms.nextElement();
147                sb.append( perm.toString() );
148            }
149            sb.append( ")\n" );
150        }
151        return sb.toString();
152    }
153
154}
155