    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.permissions;
    020
    021import java.security.Permission;
    022import java.security.PermissionCollection;
    023import java.util.Enumeration;
    024import java.util.Hashtable;
    025
    026/**
    027 * A collection of AllPermission objects.
    028 */
    029public class AllPermissionCollection extends PermissionCollection
    030{
    031
    032    private static final long serialVersionUID = 1L;
    033
    034    private boolean           m_notEmpty;
    035
    036    private boolean           m_readOnly;
    037
    038    protected final Hashtable<Permission, Permission> m_permissions    = new Hashtable<>();
    039
    040    /**
    041     * Adds an AllPermission object to this AllPermissionCollection. If this
    042     * collection was previously marked read-only, or if the permission supplied
    043     * is not of type {@link AllPermission}, a {@link SecurityException} is
    044     * thrown.
    045     * @see java.security.PermissionCollection#add(java.security.Permission)
    046     *
    047     * @param permission {@inheritDoc}
    048     */
    049    @Override
    050    public void add( final Permission permission )
    051    {
    052        if ( !PermissionChecks.isJSPWikiPermission( permission ) )
    053        {
    054            throw new IllegalArgumentException(
    055                    "Permission must be of type org.apache.wiki.permissions.*Permission." );
    056        }
    057
    058        if ( m_readOnly )
    059        {
    060            throw new SecurityException( "attempt to add a Permission to a readonly PermissionCollection" );
    061        }
    062
    063        m_notEmpty = true;
    064
    065        // This is a filthy hack, but it keeps us from having to write our own
    066        // Enumeration implementation
    067        m_permissions.put( permission, permission );
    068    }
    069
    070    /**
    071     * Returns an enumeration of all AllPermission objects stored in this
    072     * collection.
    073     * @see java.security.PermissionCollection#elements()
    074     *
    075     * @return {@inheritDoc}
    076     */
    077    @Override
    078    public Enumeration<Permission> elements()
    079    {
    080        return m_permissions.elements();
    081    }
    082
    083    /**
    084     * Iterates through the AllPermission objects stored by this
    085     * AllPermissionCollection and determines if any of them imply a supplied
    086     * Permission. If the Permission is not of type {@link AllPermission},
    087     * {@link PagePermission} or {@link WikiPermission}, this method will
    088     * return <code>false</code>. If none of the AllPermissions stored in
    089     * this collection imply the permission, the method returns
    090     * <code>false</code>; conversely, if one of the AllPermission objects
    091     * implies the permission, the method returns <code>true</code>.
    092     * @param permission the Permission to test. It may be any Permission type,
    093     * but only the AllPermission, PagePermission or WikiPermission types are
    094     * actually evaluated.
    095     * @see java.security.PermissionCollection#implies(java.security.Permission)
    096     *
    097     * @return {@inheritDoc}
    098     */
    099    @Override
    100    public boolean implies(final Permission permission )
    101    {
    102        // If nothing in the collection yet, fail fast
    103        if ( !m_notEmpty )
    104        {
    105            return false;
    106        }
    107
    108        // If not one of our permission types, it's not implied
    109        if ( !PermissionChecks.isJSPWikiPermission( permission ) )
    110        {
    111            return false;
    112        }
    113
    114        // Step through each AllPermission
    115        final Enumeration<Permission> permEnum = m_permissions.elements();
    116        while( permEnum.hasMoreElements() )
    117        {
    118            final Permission storedPermission = permEnum.nextElement();
    119            if ( storedPermission.implies( permission ) )
    120            {
    121                return true;
    122            }
    123        }
    124        return false;
    125    }
    126
    127    /**
    128     * {@inheritDoc}
    129     */
    130    @Override
    131    public boolean isReadOnly()
    132    {
    133        return m_readOnly;
    134    }
    135
    136    /**
    137     * @see java.security.PermissionCollection#setReadOnly()
    138     */
    139    @Override
    140    public void setReadOnly()
    141    {
    142        m_readOnly = true;
    143    }
    144}