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