]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
ddc9c5584d5d6ec97c611eeffc9d6b4dd4ba4285
[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 addRelationships(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 permission = getPermission(jpaTransactionContext, pv.getPermissionId());
77             if (permission == 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(permission);
83             String[] roles = getRoles(jpaTransactionContext, pr.getRole());
84             boolean grant = permission.getEffect().equals(EffectType.PERMIT) ? true : false;
85             authz.addPermissions(resources, roles, grant);
86         } else if (SubjectType.PERMISSION.equals(subject)) {
87             RoleValue rv = pr.getRole().get(0);
88             Role role = getRole(jpaTransactionContext, rv.getRoleId());
89             if (role == null) {
90                 String msg = "addPermissions: No role found for id=" + rv.getRoleId();
91                 logger.error(msg);
92                 throw new DocumentNotFoundException(msg);
93             }
94             // Using a Role and not RoleValue ensures we're getting the "ROLE" prefix/qualified name
95             // This needs to use the qualified name, not the display name
96             String[] roles = {role.getRoleName()};
97             for (PermissionValue pv : pr.getPermission()) {
98                 Permission p = getPermission(jpaTransactionContext, pv.getPermissionId());
99                 if (p == null) {
100                     String msg = "addPermissions: No permission resource found for csid=" + pv.getPermissionId();
101                     logger.error(msg);
102                     //TODO: would be nice contiue to still send 400 back
103                     continue;
104                 }
105                 CSpaceResource[] resources = getResources(p);
106                 boolean grant = p.getEffect().equals(EffectType.PERMIT) ? true : false;
107                 authz.addPermissions(resources, roles, grant);
108             }
109         }
110     }
111
112     /**
113      * deletePermissions delete all permissions associated with given permission role
114      * @param ctx
115      * @param pr permissionrole
116      * @throws Exception
117      */
118     public static void deletePermissionsFromRoles(ServiceContext ctx, PermissionRole pr)
119             throws Exception {
120         JPATransactionContext jpaTransactionContext = (JPATransactionContext) ctx.getCurrentTransactionContext();
121
122         SubjectType subject = PermissionRoleUtil.getRelationSubject(ctx, pr);
123         AuthZ authz = AuthZ.get();
124         if (subject.equals(SubjectType.ROLE)) {
125                 List<PermissionValue> permissionValues = pr.getPermission();
126                 if (permissionValues != null & permissionValues.size() > 0) {
127                     PermissionValue pv = permissionValues.get(0);
128                     Permission p = getPermission(jpaTransactionContext, pv.getPermissionId());
129                     if (p == null) {
130                         String msg = "deletePermissions: No permission found for id=" + pv.getPermissionId();
131                         logger.error(msg);
132                         throw new DocumentNotFoundException(msg);
133                     }
134                     CSpaceResource[] resources = getResources(p);
135                     String[] roles = getRoles(jpaTransactionContext, pr.getRole());
136                 authz.deletePermissionsFromRoles(resources, roles);
137                 }
138         } else if (SubjectType.PERMISSION.equals(subject)) {
139                 List<RoleValue> roleValues = pr.getRole();
140                 if (roleValues != null && roleValues.size() > 0) {
141                     RoleValue rv = roleValues.get(0);
142                     Role r = getRole(jpaTransactionContext, rv.getRoleId());
143                     if (r == null) {
144                         String msg = "deletePermissions: No role found for id=" + rv.getRoleId();
145                         logger.error(msg);
146                         throw new DocumentNotFoundException(msg);
147                     }
148                     //using r not rv ensures we're getting the "ROLE" prefix/qualified name
149                     // This needs to use the qualified name, not the display name
150                     String[] roles = {r.getRoleName()}; 
151                     for (PermissionValue pv : pr.getPermission()) {
152                         Permission p = getPermission(jpaTransactionContext, pv.getPermissionId());
153                         if (p == null) {
154                             String msg = "deletePermissions: No permission found for id=" + pv.getPermissionId();
155                             logger.error(msg);
156                             //TODO: would be nice contiue to still send 400 back
157                             continue;
158                         }
159                         CSpaceResource[] resources = getResources(p);
160                     authz.deletePermissionsFromRoles(resources, roles);
161                     }
162                 }
163         }
164     }
165
166     /**
167      * deletePermissions delete permissions associated with given permission id
168      * @param permCsid
169      * @throws Exception
170      */
171     //Non-javadoc comment : this is a very dangerous operation as it deletes
172     //the Spring ACL instead of ACE(s) that is associated with each role
173     //the ACL might be needed for other ACEs (including those for ROLE_ADMINISTRATOR,
174     //ROLE_TENANT_ADMINISTRATOR, etc.)...
175     static public void deletePermissions(JPATransactionContext jpaTransactionContext, String permCsid) throws Exception {
176         Permission p = getPermission(jpaTransactionContext, permCsid);
177         if (p == null) {
178             String msg = "deletePermissions: No permission found for id=" + permCsid;
179             logger.error(msg);
180             throw new DocumentNotFoundException(msg);
181         }
182
183         CSpaceResource[] resources = getResources(p);
184         AuthZ.get().deletePermissions(resources);
185     }
186
187     /**
188      * getRoles get roles (string) array from given RoleValue list
189      * @param rvl rolevalue list
190      * @return string array with role names
191      * @see RoleValue
192      */
193     private static String[] getRoles(JPATransactionContext jpaTransactionContext, List<RoleValue> rvl)
194                 throws DocumentNotFoundException {
195         List<String> rvls = new ArrayList<String>();
196         for (RoleValue rv : rvl) {
197             Role r = getRole(jpaTransactionContext, rv.getRoleId());
198             if (r == null) {
199                 String msg = "getRoles: No role found for id=" + rv.getRoleId();
200                 logger.error(msg);
201                 //TODO: would be nice contiue to still send 400 back
202                 continue;
203             }
204             rvls.add(r.getRoleName());
205         }
206         
207         return rvls.toArray(new String[0]);
208     }
209
210     /**
211      * getResources from given PermissionValue
212      * @param permisison csid
213      * @return array of CSpaceResource
214      * @see PermissionValue
215      * @see CSpaceResource
216      */
217     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
218         List<CSpaceResource> rl = new ArrayList<CSpaceResource>();
219
220         for (PermissionAction pa : p.getAction()) {
221             CSpaceResource res = null;
222             if (p.getTenantId() == null) {
223                 res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), p.getResourceName(),
224                         getAction(pa.getName()));
225             } else {
226                 res = new URIResourceImpl(p.getTenantId(), p.getResourceName(),
227                         getAction(pa.getName()));
228             }
229             rl.add(res);
230         }
231         return rl.toArray(new CSpaceResource[0]);
232     }
233
234     private static Permission getPermission(JPATransactionContext jpaTransactionContext, String permCsid)
235                 throws DocumentNotFoundException {
236         Permission p = (Permission) JpaStorageUtils.getEntity(jpaTransactionContext, permCsid,
237                 Permission.class);
238         return p;
239     }
240
241     private static Role getRole(JPATransactionContext jpaTransactionContext, String roleCsid) throws DocumentNotFoundException {
242         Role r = (Role) JpaStorageUtils.getEntity(jpaTransactionContext, roleCsid, Role.class);
243         return r;
244     }
245
246     /**
247      * getAction is a convenience method to get corresponding action for
248      * given ActionType
249      * @param action
250      * @return
251      */
252     public static CSpaceAction getAction(ActionType action) {
253         if (ActionType.CREATE.equals(action)) {
254             return CSpaceAction.CREATE;
255         } else if (ActionType.READ.equals(action)) {
256             return CSpaceAction.READ;
257         } else if (ActionType.UPDATE.equals(action)) {
258             return CSpaceAction.UPDATE;
259         } else if (ActionType.DELETE.equals(action)) {
260             return CSpaceAction.DELETE;
261         } else if (ActionType.SEARCH.equals(action)) {
262             return CSpaceAction.SEARCH;
263         } else if (ActionType.ADMIN.equals(action)) {
264             return CSpaceAction.ADMIN;
265         } else if (ActionType.START.equals(action)) {
266             return CSpaceAction.START;
267         } else if (ActionType.STOP.equals(action)) {
268             return CSpaceAction.STOP;
269         }
270         throw new IllegalArgumentException("action = " + action.toString());
271     }
272 }