]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
2f97a8a4cb02e1a3d7bc537e94eb2c66691c3691
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2010 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 package org.collectionspace.services.authorization.storage;
25
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import org.collectionspace.authentication.AuthN;
30 import org.collectionspace.services.authorization.perms.ActionType;
31 import org.collectionspace.services.authorization.AuthZ;
32 import org.collectionspace.services.authorization.CSpaceAction;
33 import org.collectionspace.services.authorization.CSpaceResource;
34 import org.collectionspace.services.authorization.perms.EffectType;
35 import org.collectionspace.services.authorization.perms.Permission;
36 import org.collectionspace.services.authorization.perms.PermissionAction;
37 import org.collectionspace.services.authorization.PermissionException;
38 import org.collectionspace.services.authorization.PermissionRole;
39 import org.collectionspace.services.authorization.PermissionValue;
40 import org.collectionspace.services.authorization.Role;
41 import org.collectionspace.services.authorization.RoleValue;
42 import org.collectionspace.services.authorization.SubjectType;
43 import org.collectionspace.services.authorization.URIResourceImpl;
44 import org.collectionspace.services.common.authorization_mgt.PermissionRoleUtil;
45 import org.collectionspace.services.common.context.ServiceContext;
46 import org.collectionspace.services.common.document.DocumentNotFoundException;
47 import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 /**
52  * AuthorizationDelegate delegates permissions management to the underlying authorization
53  * service from the RESTful service layer. The authorization service for example
54  * might manage permissions with the help of a provider (e.g. Spring Security ACL)
55  * @author
56  */
57 public class AuthorizationDelegate {
58
59     private static final Logger logger = LoggerFactory.getLogger(AuthorizationDelegate.class);
60
61     /**
62      * addPermissions add permissions represented given PermissionRole
63      * @param ctx
64      * @param pr permission role
65      * @throws Exception
66      * @see PermissionRole
67      */
68     static void addPermissions(ServiceContext ctx, PermissionRole pr) throws Exception {
69         SubjectType subject = PermissionRoleUtil.getRelationSubject(ctx, pr);
70         AuthZ authz = AuthZ.get();
71         if (subject.equals(SubjectType.ROLE)) {
72             PermissionValue pv = pr.getPermission().get(0);
73             Permission p = getPermission(pv.getPermissionId());
74             if (p == null) {
75                 String msg = "addPermissions: No permission found for id=" + pv.getPermissionId();
76                 logger.error(msg);
77                 throw new DocumentNotFoundException(msg);
78             }
79             CSpaceResource[] resources = getResources(p);
80             String[] roles = getRoles(pr.getRole());
81             for (CSpaceResource res : resources) {
82                 boolean grant = p.getEffect().equals(EffectType.PERMIT) ? true : false;
83                 authz.addPermissions(res, roles, grant);
84             }
85         } else if (SubjectType.PERMISSION.equals(subject)) {
86             RoleValue rv = pr.getRole().get(0);
87             Role r = getRole(rv.getRoleId());
88             if (r == null) {
89                 String msg = "addPermissions: No role found for id=" + rv.getRoleId();
90                 logger.error(msg);
91                 throw new DocumentNotFoundException(msg);
92             }
93             //using r not rv ensures we're getting the "ROLE" prefix/qualified name
94             // This needs to use the qualified name, not the display name
95             String[] roles = {r.getRoleName()};
96             for (PermissionValue pv : pr.getPermission()) {
97                 Permission p = getPermission(pv.getPermissionId());
98                 if (p == null) {
99                     String msg = "addPermissions: No permission found for id=" + pv.getPermissionId();
100                     logger.error(msg);
101                     //TODO: would be nice contiue to still send 400 back
102                     continue;
103                 }
104                 CSpaceResource[] resources = getResources(p);
105                 for (CSpaceResource res : resources) {
106                     boolean grant = p.getEffect().equals(EffectType.PERMIT) ? true : false;
107                     authz.addPermissions(res, roles, grant);
108                 }
109             }
110         }
111     }
112
113     /**
114      * deletePermissions delete all permissions associated with given permission role
115      * @param ctx
116      * @param pr permissionrole
117      * @throws Exception
118      */
119     static void deletePermissions(ServiceContext ctx, PermissionRole pr)
120             throws Exception {
121         SubjectType subject = PermissionRoleUtil.getRelationSubject(ctx, pr);
122         AuthZ authz = AuthZ.get();
123         if (subject.equals(SubjectType.ROLE)) {
124                 List<PermissionValue> permissionValues = pr.getPermission();
125                 if (permissionValues != null & permissionValues.size() > 0) {
126                     PermissionValue pv = permissionValues.get(0);
127                     Permission p = getPermission(pv.getPermissionId());
128                     if (p == null) {
129                         String msg = "deletePermissions: No permission found for id=" + pv.getPermissionId();
130                         logger.error(msg);
131                         throw new DocumentNotFoundException(msg);
132                     }
133                     CSpaceResource[] resources = getResources(p);
134                     String[] roles = getRoles(pr.getRole());
135                     for (CSpaceResource res : resources) {
136                         authz.deletePermissions(res, roles);
137                     }
138                 }
139         } else if (SubjectType.PERMISSION.equals(subject)) {
140                 List<RoleValue> roleValues = pr.getRole();
141                 if (roleValues != null && roleValues.size() > 0) {
142                     RoleValue rv = roleValues.get(0);
143                     Role r = getRole(rv.getRoleId());
144                     if (r == null) {
145                         String msg = "deletePermissions: No role found for id=" + rv.getRoleId();
146                         logger.error(msg);
147                         throw new DocumentNotFoundException(msg);
148                     }
149                     //using r not rv ensures we're getting the "ROLE" prefix/qualified name
150                     // This needs to use the qualified name, not the display name
151                     String[] roles = {r.getRoleName()}; 
152                     for (PermissionValue pv : pr.getPermission()) {
153                         Permission p = getPermission(pv.getPermissionId());
154                         if (p == null) {
155                             String msg = "deletePermissions: No permission found for id=" + pv.getPermissionId();
156                             logger.error(msg);
157                             //TODO: would be nice contiue to still send 400 back
158                             continue;
159                         }
160                         CSpaceResource[] resources = getResources(p);
161                         for (CSpaceResource res : resources) {
162                             authz.deletePermissions(res, roles);
163                         }
164                     }
165                 }
166         }
167     }
168
169     /**
170      * deletePermissions delete permissions associated with given permission id
171      * @param permCsid
172      * @throws Exception
173      */
174     //Non-javadoc comment : this is a very dangerous operation as it deletes
175     //the Spring ACL instead of ACE(s) that is associated with each role
176     //the ACL might be needed for other ACEs (including those for ROLE_ADMINISTRATOR,
177     //ROLE_TENANT_ADMINISTRATOR, etc.)...
178     static public void deletePermissions(String permCsid) throws Exception {
179         Permission p = getPermission(permCsid);
180         if (p == null) {
181             String msg = "deletePermissions: No permission found for id=" + permCsid;
182             logger.error(msg);
183             throw new DocumentNotFoundException(msg);
184         }
185         CSpaceResource[] resources = getResources(p);
186         AuthZ authz = AuthZ.get();
187
188         for (CSpaceResource res : resources) {
189             try {
190                 authz.deletePermissions(res);
191             } catch (PermissionException pe) {
192                 //perms are created downthere only if roles are related to the permissions
193                 logger.info("no permissions found in authz service provider for "
194                         + "permCsid=" + permCsid + " res=" + res.getId());
195             }
196         }
197     }
198
199     /**
200      * getRoles get roles (string) array from given RoleValue list
201      * @param rvl rolevalue list
202      * @return string array with role names
203      * @see RoleValue
204      */
205     private static String[] getRoles(List<RoleValue> rvl)
206                 throws DocumentNotFoundException {
207         List<String> rvls = new ArrayList<String>();
208         for (RoleValue rv : rvl) {
209             Role r = getRole(rv.getRoleId());
210             if (r == null) {
211                 String msg = "getRoles: No role found for id=" + rv.getRoleId();
212                 logger.error(msg);
213                 //TODO: would be nice contiue to still send 400 back
214                 continue;
215             }
216             rvls.add(r.getRoleName());
217         }
218         return rvls.toArray(new String[0]);
219     }
220
221     /**
222      * getResources from given PermissionValue
223      * @param permisison csid
224      * @return array of CSpaceResource
225      * @see PermissionValue
226      * @see CSpaceResource
227      */
228     private static CSpaceResource[] getResources(Permission p) {
229         List<CSpaceResource> rl = new ArrayList<CSpaceResource>();
230
231         for (PermissionAction pa : p.getAction()) {
232             CSpaceResource res = null;
233             if (p.getTenantId() == null) {
234                 res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), p.getResourceName(),
235                         getAction(pa.getName()));
236             } else {
237                 res = new URIResourceImpl(p.getTenantId(), p.getResourceName(),
238                         getAction(pa.getName()));
239             }
240             rl.add(res);
241         }
242         return rl.toArray(new CSpaceResource[0]);
243     }
244
245     private static Permission getPermission(String permCsid)
246                 throws DocumentNotFoundException {
247         Permission p = (Permission) JpaStorageUtils.getEntity(permCsid,
248                 Permission.class);
249         return p;
250     }
251
252     private static Role getRole(String roleCsid)
253                 throws DocumentNotFoundException {
254         Role r = (Role) JpaStorageUtils.getEntity(roleCsid,
255                 Role.class);
256         return r;
257     }
258
259     /**
260      * getAction is a convenience method to get corresponding action for
261      * given ActionType
262      * @param action
263      * @return
264      */
265     public static CSpaceAction getAction(ActionType action) {
266         if (ActionType.CREATE.equals(action)) {
267             return CSpaceAction.CREATE;
268         } else if (ActionType.READ.equals(action)) {
269             return CSpaceAction.READ;
270         } else if (ActionType.UPDATE.equals(action)) {
271             return CSpaceAction.UPDATE;
272         } else if (ActionType.DELETE.equals(action)) {
273             return CSpaceAction.DELETE;
274         } else if (ActionType.SEARCH.equals(action)) {
275             return CSpaceAction.SEARCH;
276         } else if (ActionType.ADMIN.equals(action)) {
277             return CSpaceAction.ADMIN;
278         } else if (ActionType.START.equals(action)) {
279             return CSpaceAction.START;
280         } else if (ActionType.STOP.equals(action)) {
281             return CSpaceAction.STOP;
282         }
283         throw new IllegalArgumentException("action = " + action.toString());
284     }
285 }