]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
0adcb0186b07de5b02679f68755e165cf34f437b
[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.JPATransactionContext;
48 import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 /**
53  * AuthorizationDelegate delegates permissions management to the underlying authorization
54  * service from the RESTful service layer. The authorization service for example
55  * might manage permissions with the help of a provider (e.g. Spring Security ACL)
56  * @author
57  */
58 public class AuthorizationDelegate {
59
60     private static final Logger logger = LoggerFactory.getLogger(AuthorizationDelegate.class);
61
62     /**
63      * addPermissions add permissions represented given PermissionRole
64      * @param ctx
65      * @param pr permission role
66      * @throws Exception
67      * @see PermissionRole
68      */
69     public static void addPermissions(ServiceContext ctx, PermissionRole pr) throws Exception {
70         JPATransactionContext jpaTransactionContext = (JPATransactionContext) ctx.getCurrentTransactionContext();
71         
72         SubjectType subject = PermissionRoleUtil.getRelationSubject(ctx, pr);
73         AuthZ authz = AuthZ.get();
74         if (subject.equals(SubjectType.ROLE)) {
75             PermissionValue pv = pr.getPermission().get(0);
76             Permission p = getPermission(jpaTransactionContext, pv.getPermissionId());
77             if (p == null) {
78                 String msg = "addPermissions: No permission found for id=" + pv.getPermissionId();
79                 logger.error(msg);
80                 throw new DocumentNotFoundException(msg);
81             }
82             CSpaceResource[] resources = getResources(p);
83             String[] roles = getRoles(jpaTransactionContext, pr.getRole());
84             for (CSpaceResource res : resources) {
85                 boolean grant = p.getEffect().equals(EffectType.PERMIT) ? true : false;
86                 authz.addPermissions(res, roles, grant);
87             }
88         } else if (SubjectType.PERMISSION.equals(subject)) {
89             RoleValue rv = pr.getRole().get(0);
90             Role r = getRole(jpaTransactionContext, rv.getRoleId());
91             if (r == null) {
92                 String msg = "addPermissions: No role found for id=" + rv.getRoleId();
93                 logger.error(msg);
94                 throw new DocumentNotFoundException(msg);
95             }
96             //using r not rv ensures we're getting the "ROLE" prefix/qualified name
97             // This needs to use the qualified name, not the display name
98             String[] roles = {r.getRoleName()};
99             for (PermissionValue pv : pr.getPermission()) {
100                 Permission p = getPermission(jpaTransactionContext, pv.getPermissionId());
101                 if (p == null) {
102                     String msg = "addPermissions: No permission found for id=" + pv.getPermissionId();
103                     logger.error(msg);
104                     //TODO: would be nice contiue to still send 400 back
105                     continue;
106                 }
107                 CSpaceResource[] resources = getResources(p);
108                 for (CSpaceResource res : resources) {
109                     boolean grant = p.getEffect().equals(EffectType.PERMIT) ? true : false;
110                     authz.addPermissions(res, roles, grant);
111                 }
112             }
113         }
114     }
115
116     /**
117      * deletePermissions delete all permissions associated with given permission role
118      * @param ctx
119      * @param pr permissionrole
120      * @throws Exception
121      */
122     public static void deletePermissions(ServiceContext ctx, PermissionRole pr)
123             throws Exception {
124         JPATransactionContext jpaTransactionContext = (JPATransactionContext) ctx.getCurrentTransactionContext();
125
126         SubjectType subject = PermissionRoleUtil.getRelationSubject(ctx, pr);
127         AuthZ authz = AuthZ.get();
128         if (subject.equals(SubjectType.ROLE)) {
129                 List<PermissionValue> permissionValues = pr.getPermission();
130                 if (permissionValues != null & permissionValues.size() > 0) {
131                     PermissionValue pv = permissionValues.get(0);
132                     Permission p = getPermission(jpaTransactionContext, pv.getPermissionId());
133                     if (p == null) {
134                         String msg = "deletePermissions: No permission found for id=" + pv.getPermissionId();
135                         logger.error(msg);
136                         throw new DocumentNotFoundException(msg);
137                     }
138                     CSpaceResource[] resources = getResources(p);
139                     String[] roles = getRoles(jpaTransactionContext, pr.getRole());
140                     for (CSpaceResource res : resources) {
141                         authz.deletePermissions(res, roles);
142                     }
143                 }
144         } else if (SubjectType.PERMISSION.equals(subject)) {
145                 List<RoleValue> roleValues = pr.getRole();
146                 if (roleValues != null && roleValues.size() > 0) {
147                     RoleValue rv = roleValues.get(0);
148                     Role r = getRole(jpaTransactionContext, rv.getRoleId());
149                     if (r == null) {
150                         String msg = "deletePermissions: No role found for id=" + rv.getRoleId();
151                         logger.error(msg);
152                         throw new DocumentNotFoundException(msg);
153                     }
154                     //using r not rv ensures we're getting the "ROLE" prefix/qualified name
155                     // This needs to use the qualified name, not the display name
156                     String[] roles = {r.getRoleName()}; 
157                     for (PermissionValue pv : pr.getPermission()) {
158                         Permission p = getPermission(jpaTransactionContext, pv.getPermissionId());
159                         if (p == null) {
160                             String msg = "deletePermissions: No permission found for id=" + pv.getPermissionId();
161                             logger.error(msg);
162                             //TODO: would be nice contiue to still send 400 back
163                             continue;
164                         }
165                         CSpaceResource[] resources = getResources(p);
166                         for (CSpaceResource res : resources) {
167                             authz.deletePermissions(res, roles);
168                         }
169                     }
170                 }
171         }
172     }
173
174     /**
175      * deletePermissions delete permissions associated with given permission id
176      * @param permCsid
177      * @throws Exception
178      */
179     //Non-javadoc comment : this is a very dangerous operation as it deletes
180     //the Spring ACL instead of ACE(s) that is associated with each role
181     //the ACL might be needed for other ACEs (including those for ROLE_ADMINISTRATOR,
182     //ROLE_TENANT_ADMINISTRATOR, etc.)...
183     static public void deletePermissions(JPATransactionContext jpaTransactionContext, String permCsid) throws Exception {
184         Permission p = getPermission(jpaTransactionContext, permCsid);
185         if (p == null) {
186             String msg = "deletePermissions: No permission found for id=" + permCsid;
187             logger.error(msg);
188             throw new DocumentNotFoundException(msg);
189         }
190         CSpaceResource[] resources = getResources(p);
191         AuthZ authz = AuthZ.get();
192
193         for (CSpaceResource res : resources) {
194             try {
195                 authz.deletePermissions(res);
196             } catch (PermissionException pe) {
197                 //perms are created downthere only if roles are related to the permissions
198                 logger.info("no permissions found in authz service provider for "
199                         + "permCsid=" + permCsid + " res=" + res.getId());
200             }
201         }
202     }
203
204     /**
205      * getRoles get roles (string) array from given RoleValue list
206      * @param rvl rolevalue list
207      * @return string array with role names
208      * @see RoleValue
209      */
210     private static String[] getRoles(JPATransactionContext jpaTransactionContext, List<RoleValue> rvl)
211                 throws DocumentNotFoundException {
212         List<String> rvls = new ArrayList<String>();
213         for (RoleValue rv : rvl) {
214             Role r = getRole(jpaTransactionContext, rv.getRoleId());
215             if (r == null) {
216                 String msg = "getRoles: No role found for id=" + rv.getRoleId();
217                 logger.error(msg);
218                 //TODO: would be nice contiue to still send 400 back
219                 continue;
220             }
221             rvls.add(r.getRoleName());
222         }
223         
224         return rvls.toArray(new String[0]);
225     }
226
227     /**
228      * getResources from given PermissionValue
229      * @param permisison csid
230      * @return array of CSpaceResource
231      * @see PermissionValue
232      * @see CSpaceResource
233      */
234     private static CSpaceResource[] getResources(Permission p) { // REM - We could use PermissionValue instead -would save the caller from needing to go to the DB for the Permission instance
235         List<CSpaceResource> rl = new ArrayList<CSpaceResource>();
236
237         for (PermissionAction pa : p.getAction()) {
238             CSpaceResource res = null;
239             if (p.getTenantId() == null) {
240                 res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), p.getResourceName(),
241                         getAction(pa.getName()));
242             } else {
243                 res = new URIResourceImpl(p.getTenantId(), p.getResourceName(),
244                         getAction(pa.getName()));
245             }
246             rl.add(res);
247         }
248         return rl.toArray(new CSpaceResource[0]);
249     }
250
251     private static Permission getPermission(JPATransactionContext jpaTransactionContext, String permCsid)
252                 throws DocumentNotFoundException {
253         Permission p = (Permission) JpaStorageUtils.getEntity(jpaTransactionContext, permCsid,
254                 Permission.class);
255         return p;
256     }
257
258     private static Role getRole(JPATransactionContext jpaTransactionContext, String roleCsid) throws DocumentNotFoundException {
259         Role r = (Role) JpaStorageUtils.getEntity(jpaTransactionContext, roleCsid, Role.class);
260         return r;
261     }
262
263     /**
264      * getAction is a convenience method to get corresponding action for
265      * given ActionType
266      * @param action
267      * @return
268      */
269     public static CSpaceAction getAction(ActionType action) {
270         if (ActionType.CREATE.equals(action)) {
271             return CSpaceAction.CREATE;
272         } else if (ActionType.READ.equals(action)) {
273             return CSpaceAction.READ;
274         } else if (ActionType.UPDATE.equals(action)) {
275             return CSpaceAction.UPDATE;
276         } else if (ActionType.DELETE.equals(action)) {
277             return CSpaceAction.DELETE;
278         } else if (ActionType.SEARCH.equals(action)) {
279             return CSpaceAction.SEARCH;
280         } else if (ActionType.ADMIN.equals(action)) {
281             return CSpaceAction.ADMIN;
282         } else if (ActionType.START.equals(action)) {
283             return CSpaceAction.START;
284         } else if (ActionType.STOP.equals(action)) {
285             return CSpaceAction.STOP;
286         }
287         throw new IllegalArgumentException("action = " + action.toString());
288     }
289 }