001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.authroles.authorization.strategies.role.metadata;
018
019import java.util.HashMap;
020import java.util.Map;
021
022import org.apache.wicket.authorization.Action;
023import org.apache.wicket.authroles.authorization.strategies.role.Roles;
024import org.apache.wicket.util.io.IClusterable;
025
026
027/**
028 * For each Action, holds a set of roles that can perform that action. Roles can be granted access
029 * to a given action via authorize(Action, String role) and denied access via unauthorize(Action,
030 * String role). All permissions can be removed for a given action via authorizeAll(Action).
031 * 
032 * @author Eelco Hillenius
033 * @author Jonathan Locke
034 */
035public final class ActionPermissions implements IClusterable
036{
037        private static final long serialVersionUID = 1L;
038
039        /** Map from an action to a set of role strings */
040        private final Map<Action, Roles> rolesForAction = new HashMap<>();
041
042        /**
043         * Gives permission for the given roles to perform the given action
044         * 
045         * @param action
046         *            The action
047         * @param rolesToAdd
048         *            The roles
049         */
050        public final void authorize(final Action action, final Roles rolesToAdd)
051        {
052                if (action == null)
053                {
054                        throw new IllegalArgumentException("Argument action cannot be null");
055                }
056
057                if (rolesToAdd == null)
058                {
059                        throw new IllegalArgumentException("Argument rolesToAdd cannot be null");
060                }
061
062                Roles roles = rolesForAction.get(action);
063                if (roles == null)
064                {
065                        roles = new Roles();
066                        rolesForAction.put(action, roles);
067                }
068                roles.addAll(rolesToAdd);
069        }
070
071        /**
072         * Remove all authorization for the given action.
073         * 
074         * @param action
075         *            The action to clear
076         */
077        public final void authorizeAll(final Action action)
078        {
079                if (action == null)
080                {
081                        throw new IllegalArgumentException("Argument action cannot be null");
082                }
083
084                rolesForAction.remove(action);
085        }
086
087        /**
088         * Gets the roles that have a binding for the given action.
089         * 
090         * @param action
091         *            The action
092         * @return The roles authorized for the given action
093         */
094        public final Roles rolesFor(final Action action)
095        {
096                if (action == null)
097                {
098                        throw new IllegalArgumentException("Argument action cannot be null");
099                }
100
101                return rolesForAction.get(action);
102        }
103
104        /**
105         * Remove the given authorized role from an action. Note that this is only relevant if a role
106         * was previously authorized for that action. If no roles where previously authorized the effect
107         * of the unauthorize call is that no roles at all will be authorized for that action.
108         * 
109         * @param action
110         *            The action
111         * @param rolesToRemove
112         *            The comma separated list of roles to remove
113         */
114        public final void unauthorize(final Action action, final Roles rolesToRemove)
115        {
116                if (action == null)
117                {
118                        throw new IllegalArgumentException("Argument action cannot be null");
119                }
120
121                if (rolesToRemove == null)
122                {
123                        throw new IllegalArgumentException("Argument rolesToRemove cannot be null");
124                }
125
126                Roles roles = rolesForAction.get(action);
127                if (roles != null)
128                {
129                        roles.removeAll(rolesToRemove);
130                }
131                else
132                {
133                        roles = new Roles();
134                        rolesForAction.put(action, roles);
135                }
136
137                // If we removed the last authorized role, we authorize the empty role
138                // so that removing authorization can't suddenly open something up to
139                // everyone.
140                if (roles.size() == 0)
141                {
142                        roles.add(MetaDataRoleAuthorizationStrategy.NO_ROLE);
143                }
144        }
145}