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