]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
cd777062fac709394b6c5688f6319e02431bd33d
[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 2009 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 import java.util.UUID;
29
30 import org.collectionspace.services.authorization.PermissionRole;
31 import org.collectionspace.services.authorization.PermissionRoleSubResource;
32 import org.collectionspace.services.authorization.PermissionValue;
33 import org.collectionspace.services.authorization.Role;
34 import org.collectionspace.services.authorization.RoleValue;
35 import org.collectionspace.services.authorization.RolesList;
36 import org.collectionspace.services.authorization.SubjectType;
37
38 import org.collectionspace.services.client.PermissionRoleFactory;
39 import org.collectionspace.services.client.RoleClient;
40 import org.collectionspace.services.client.RoleFactory;
41 import org.collectionspace.services.common.api.Tools;
42 import org.collectionspace.services.common.context.ServiceContext;
43 import org.collectionspace.services.common.document.BadRequestException;
44 import org.collectionspace.services.common.document.DocumentFilter;
45 import org.collectionspace.services.common.document.DocumentWrapper;
46 import org.collectionspace.services.common.document.JaxbUtils;
47 import org.collectionspace.services.common.security.SecurityUtils;
48 import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler;
49
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 /**
54  * Document handler for Role
55  * @author 
56  */
57 @SuppressWarnings("unchecked")
58 public class RoleDocumentHandler
59                 extends JpaDocumentHandler<Role, RolesList, Role, List<Role>> {
60     private final Logger logger = LoggerFactory.getLogger(RoleDocumentHandler.class);
61     private Role role;
62     private RolesList rolesList;
63
64     @Override
65     public void handleCreate(DocumentWrapper<Role> wrapDoc) throws Exception {
66         String id = UUID.randomUUID().toString();
67         Role role = wrapDoc.getWrappedObject();
68         
69         // Synthesize the display name if it was not passed in.
70         String displayName = role.getDisplayName();
71         boolean displayNameEmpty = true;
72         if (displayName != null) {
73                 displayNameEmpty = displayName.trim().isEmpty();        
74         }
75         if (displayNameEmpty == true) {
76                 role.setDisplayName(role.getRoleName());
77         }
78         
79         setTenant(role);
80         role.setRoleName(RoleClient.getBackendRoleName(role.getRoleName(), role.getTenantId()));
81         role.setCsid(id);
82         // We do not allow creation of locked roles through the services.
83         role.setMetadataProtection(null);
84         role.setPermsProtection(null);        
85     }
86     
87     @SuppressWarnings("rawtypes")
88         @Override
89         public void handleUpdate(DocumentWrapper<Role> wrapDoc) throws Exception {
90                 Role roleFound = wrapDoc.getWrappedObject();
91                 Role roleReceived = getCommonPart();
92                 // If marked as metadata immutable, do not do update
93                 if (!RoleClient.IMMUTABLE.equals(roleFound.getMetadataProtection())) {
94                         roleReceived
95                                         .setRoleName(RoleClient.getBackendRoleName(roleReceived.getRoleName(), roleFound.getTenantId()));
96                         merge(roleReceived, roleFound);
97                 }
98                 //
99                 // Update perms is supplied.
100                 //
101                 ServiceContext ctx = this.getServiceContext();
102                 List<PermissionValue> permValueList = roleReceived.getPermission();
103                 if (permValueList != null && permValueList.size() > 0) {
104             PermissionRoleSubResource subResource =
105                     new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
106             //
107             // First, delete the existing permroles
108             //
109             subResource.deletePermissionRole(ctx, roleFound.getCsid(), SubjectType.PERMISSION);
110             //
111             // Next, create the new permroles
112             //
113                 RoleValue roleValue = RoleFactory.createRoleValueInstance(roleFound);
114                 PermissionRole permRole = PermissionRoleFactory.createPermissionRoleInstance(SubjectType.PERMISSION, roleValue,
115                                 permValueList, true, true);            
116             subResource.createPermissionRole(ctx, permRole, SubjectType.PERMISSION);
117             //
118             // Finally, set the updated perm list in the result
119             //
120             PermissionRole newPermRole = subResource.getPermissionRole(ctx, roleFound.getCsid(), SubjectType.PERMISSION);
121             roleFound.setPermission(newPermRole.getPermission());
122                 }
123         }
124
125     /**
126      * Merge fields manually from 'from' to the 'to' role
127      * -this method is created due to inefficiency of JPA EM merge
128      * @param from
129      * @param to
130      * @return merged role
131      */
132     private Role merge(Role from, Role to) throws Exception {
133         // A role's name cannot be changed
134         if (!(from.getRoleName().equalsIgnoreCase(to.getRoleName()))) {
135             String msg = "Role name cannot be changed " + to.getRoleName();
136             logger.error(msg);
137             throw new BadRequestException(msg);
138         }
139         
140         if (from.getDisplayName() != null && !from.getDisplayName().trim().isEmpty() ) {
141                 to.setDisplayName(from.getDisplayName());
142         }
143         if (from.getRoleGroup() != null && !from.getRoleGroup().trim().isEmpty()) {
144             to.setRoleGroup(from.getRoleGroup());
145         }
146         if (from.getDescription() != null && !from.getDescription().trim().isEmpty()) {
147             to.setDescription(from.getDescription());
148         }
149
150         if (logger.isDebugEnabled()) {
151                 org.collectionspace.services.authorization.ObjectFactory objectFactory =
152                         new org.collectionspace.services.authorization.ObjectFactory();
153             logger.debug("Merged role on update=" + JaxbUtils.toString(objectFactory.createRole(to), Role.class));
154         }
155         
156         return to;
157     }
158     
159     @Override
160     public void completeCreate(DocumentWrapper<Role> wrapDoc) throws Exception {
161         Role role = wrapDoc.getWrappedObject();
162         //
163         // If there are perms in the payload, create the required role/perm relationships.
164         //
165         List<PermissionValue> permValueList = role.getPermission();
166         if (permValueList != null && permValueList.size() > 0) {
167                 // create and persist a permrole instance
168                 // The caller of this method needs to ensure a valid and active EM (EntityManager) instance is in the Service context
169                 RoleValue roleValue = RoleFactory.createRoleValueInstance(role);
170                 PermissionRole permRole = PermissionRoleFactory.createPermissionRoleInstance(SubjectType.PERMISSION, roleValue,
171                                 permValueList, true, true);
172             PermissionRoleSubResource subResource =
173                     new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
174             subResource.createPermissionRole(getServiceContext(), permRole, SubjectType.PERMISSION);
175         }
176
177     }
178
179     @Override
180     public void completeUpdate(DocumentWrapper<Role> wrapDoc) throws Exception {
181         Role updatedRole = wrapDoc.getWrappedObject();
182         getServiceContext().setOutput(updatedRole);
183         sanitize(updatedRole);
184     }
185
186     @Override
187     public void handleGet(DocumentWrapper<Role> wrapDoc) throws Exception {
188         setCommonPart(extractCommonPart(wrapDoc));
189         sanitize(getCommonPart());
190         getServiceContext().setOutput(role);
191     }
192
193     @Override
194     public void handleGetAll(DocumentWrapper<List<Role>> wrapDoc) throws Exception {
195         RolesList rolesList = extractCommonPartList(wrapDoc);
196         setCommonPartList(rolesList);
197         getServiceContext().setOutput(getCommonPartList());
198     }
199
200         @Override
201     public Role extractCommonPart(
202             DocumentWrapper<Role> wrapDoc)
203             throws Exception {
204         Role role = wrapDoc.getWrappedObject();
205         
206         String includePermsQueryParamValue = (String) getServiceContext().getQueryParams().getFirst(RoleClient.INCLUDE_PERMS_QP);
207         boolean includePerms = Tools.isTrue(includePermsQueryParamValue);
208         if (includePerms) {
209                 PermissionRoleSubResource permRoleResource =
210                         new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
211                 PermissionRole permRole = permRoleResource.getPermissionRole(getServiceContext(), role.getCsid(), SubjectType.PERMISSION);
212                 role.setPermission(permRole.getPermission());
213         }
214     
215         return role;
216     }
217
218     @Override
219     public void fillCommonPart(Role obj, DocumentWrapper<Role> wrapDoc)
220             throws Exception {
221         throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler");
222     }
223
224     /*
225      * See https://issues.collectionspace.org/browse/DRYD-181
226      * 
227      * For backward compatibility, we could not change the role list to be a child class of AbstractCommonList.  This
228      * would have change the result payload and would break existing API clients.  So the best we can do, it treat
229      * the role list payload as a special case and return the paging information.
230      * 
231      */
232         protected RolesList extractPagingInfoForRoles(RolesList roleList, DocumentWrapper<List<Role>> wrapDoc)
233             throws Exception {
234
235         DocumentFilter docFilter = this.getDocumentFilter();
236         long pageSize = docFilter.getPageSize();
237         long pageNum = pageSize != 0 ? docFilter.getOffset() / pageSize : pageSize;
238         // set the page size and page number
239         roleList.setPageNum(pageNum);
240         roleList.setPageSize(pageSize);
241         List<Role> docList = wrapDoc.getWrappedObject();
242         // Set num of items in list. this is useful to our testing framework.
243         roleList.setItemsInPage(docList.size());
244         // set the total result size
245         roleList.setTotalItems(docFilter.getTotalItemsResult());
246
247         return roleList;
248     }
249         
250     @Override
251     public RolesList extractCommonPartList(
252             DocumentWrapper<List<Role>> wrapDoc) throws Exception {
253
254         RolesList rolesList = extractPagingInfoForRoles(new RolesList(), wrapDoc);        
255         List<Role> list = new ArrayList<Role>();
256         rolesList.setRole(list);
257         for (Role role : wrapDoc.getWrappedObject()) {
258             sanitize(role);
259             list.add(role);
260         }
261         
262         return rolesList;
263     }
264
265     @Override
266     public Role getCommonPart() {
267         return role;
268     }
269
270     @Override
271     public void setCommonPart(Role role) {
272         this.role = role;
273     }
274
275     @Override
276     public RolesList getCommonPartList() {
277         return rolesList;
278     }
279
280     @Override
281     public void setCommonPartList(RolesList rolesList) {
282         this.rolesList = rolesList;
283     }
284
285     @Override
286     public String getQProperty(
287             String prop) {
288         return null;
289     }
290
291     @Override
292     public DocumentFilter createDocumentFilter() {
293         DocumentFilter filter = new RoleJpaFilter(this.getServiceContext());
294         return filter;
295     }
296
297     /**
298      * sanitize removes data not needed to be sent to the consumer
299      * @param roleFound
300      */
301     private void sanitize(Role role) {
302         if (!SecurityUtils.isCSpaceAdmin()) {
303             // role.setTenantId(null); // REM - There's no reason for hiding the tenant ID is there?
304         }
305     }
306
307     private void setTenant(Role role) {
308         //set tenant only if not available from input
309         if (role.getTenantId() == null || role.getTenantId().isEmpty()) {
310             role.setTenantId(getServiceContext().getTenantId());
311         }
312     }
313 }