001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  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, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.security.jacc;
020    
021    import java.security.Permission;
022    import java.security.PermissionCollection;
023    import java.security.Permissions;
024    import java.security.Principal;
025    import java.security.ProtectionDomain;
026    import java.util.Enumeration;
027    import java.util.HashMap;
028    import java.util.HashSet;
029    import java.util.Iterator;
030    import java.util.Map;
031    
032    import javax.security.jacc.PolicyContextException;
033    
034    
035    /**
036     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
037     */
038    public class PolicyConfigurationGeneric implements GeronimoPolicyConfiguration {
039        final static int OPEN = 1;
040        final static int IN_SERVICE = 2;
041        final static int DELETED = 3;
042    
043        private final String contextID;
044        private int state;
045        private final HashMap rolePermissionsMap = new HashMap();
046        private final HashMap principalRoleMapping = new HashMap();
047        private Permissions unchecked = null;
048        private Permissions excluded = null;
049    
050        private final HashMap principalPermissionsMap = new HashMap();
051    
052        PolicyConfigurationGeneric(String contextID) {
053            this.contextID = contextID;
054            this.state = OPEN;
055        }
056    
057        public String getContextID() throws PolicyContextException {
058            return contextID;
059        }
060    
061        public boolean implies(ProtectionDomain domain, Permission permission) {
062    
063            if (excluded != null && excluded.implies(permission)) return false;
064    
065            if (unchecked != null && unchecked.implies(permission)) return true;
066    
067            Principal[] principals = domain.getPrincipals();
068            if (principals.length == 0) return false;
069    
070            for (int i = 0; i < principals.length; i++) {
071                Principal principal = principals[i];
072    
073                Permissions permissions = (Permissions) principalPermissionsMap.get(principal);
074    
075                if (permissions != null && permissions.implies(permission)) return true;
076            }
077    
078            return false;
079        }
080    
081        public void setPrincipalRoleMapping(Map principalRoleMap) throws PolicyContextException {
082            principalRoleMapping.clear();
083            principalRoleMapping.putAll(principalRoleMap);
084        }
085    
086        public void addToRole(String roleName, PermissionCollection permissions) throws PolicyContextException {
087            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
088    
089            Enumeration e = permissions.elements();
090            while (e.hasMoreElements()) {
091                addToRole(roleName, (Permission) e.nextElement());
092            }
093        }
094    
095        public void addToRole(String roleName, Permission permission) throws PolicyContextException {
096            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
097    
098            Permissions permissions = (Permissions) rolePermissionsMap.get(roleName);
099            if (permissions == null) {
100                permissions = new Permissions();
101                rolePermissionsMap.put(roleName, permissions);
102            }
103            permissions.add(permission);
104        }
105    
106        public void addToUncheckedPolicy(PermissionCollection permissions) throws PolicyContextException {
107            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
108    
109            Enumeration e = permissions.elements();
110            while (e.hasMoreElements()) {
111                addToUncheckedPolicy((Permission) e.nextElement());
112            }
113        }
114    
115        public void addToUncheckedPolicy(Permission permission) throws PolicyContextException {
116            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
117    
118            if (unchecked == null) unchecked = new Permissions();
119    
120            unchecked.add(permission);
121        }
122    
123        public void addToExcludedPolicy(PermissionCollection permissions) throws PolicyContextException {
124            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
125    
126            Enumeration e = permissions.elements();
127            while (e.hasMoreElements()) {
128                addToExcludedPolicy((Permission) e.nextElement());
129            }
130        }
131    
132        public void addToExcludedPolicy(Permission permission) throws PolicyContextException {
133            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
134    
135            if (excluded == null) excluded = new Permissions();
136    
137            excluded.add(permission);
138        }
139    
140        public void removeRole(String roleName) throws PolicyContextException {
141            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
142    
143            rolePermissionsMap.remove(roleName);
144        }
145    
146        public void removeUncheckedPolicy() throws PolicyContextException {
147            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
148    
149            unchecked = null;
150        }
151    
152        public void removeExcludedPolicy() throws PolicyContextException {
153            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
154    
155            excluded = null;
156        }
157    
158        public void linkConfiguration(javax.security.jacc.PolicyConfiguration link) throws PolicyContextException {
159            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
160        }
161    
162        public void delete() throws PolicyContextException {
163            state = DELETED;
164        }
165    
166        public void commit() throws PolicyContextException {
167            if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
168    
169            for (Iterator principalEntries = principalRoleMapping.entrySet().iterator(); principalEntries.hasNext(); ) {
170                Map.Entry principalEntry = (Map.Entry) principalEntries.next();
171                Principal principal = (Principal) principalEntry.getKey();
172                Permissions principalPermissions = (Permissions) principalPermissionsMap.get(principal);
173    
174                if (principalPermissions == null) {
175                    principalPermissions = new Permissions();
176                    principalPermissionsMap.put(principal, principalPermissions);
177                }
178    
179                HashSet roleSet = (HashSet) principalEntry.getValue();
180                for (Iterator roles = roleSet.iterator(); roles.hasNext(); ) {
181                    Permissions permissions = (Permissions) rolePermissionsMap.get(roles.next());
182                    if (permissions == null) continue;
183                    for (Enumeration rolePermissions = permissions.elements(); rolePermissions.hasMoreElements(); ) {
184                        principalPermissions.add((Permission) rolePermissions.nextElement());
185                    }
186                }
187    
188            }
189            state = IN_SERVICE;
190        }
191    
192        public boolean inService() throws PolicyContextException {
193            return (state == IN_SERVICE);
194        }
195    
196        //TODO I have no idea what side effects this might have, but it's needed in some form from GeronimoPolicyConfigurationFactory.
197        //see JACC spec 1.0 section 3.1.1.1 discussion of in service and deleted.
198        //spec p. 31 3.1.7 on the effects of remove:
199        //If the getPolicyConfiguration method  is used, the value true should be passed as the second
200        //  argument to cause the  corresponding policy statements to be deleted from the context.
201        public void open(boolean remove) {
202            if (remove) {
203                rolePermissionsMap.clear();
204                principalRoleMapping.clear();
205                unchecked = null;
206                excluded = null;
207                principalPermissionsMap.clear();
208            }
209            state = OPEN;
210        }
211    
212        int getState() {
213            return state;
214        }
215    }