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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.authorization.storage;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.UUID;
30 import org.collectionspace.services.authorization.perms.ActionType;
31 import org.collectionspace.services.authorization.CSpaceAction;
32 import org.collectionspace.services.authorization.perms.Permission;
33 import org.collectionspace.services.authorization.perms.PermissionAction;
34 import org.collectionspace.services.authorization.perms.PermissionsList;
35 import org.collectionspace.services.authorization.URIResourceImpl;
37 import org.collectionspace.services.common.document.BadRequestException;
38 import org.collectionspace.services.common.document.DocumentFilter;
39 import org.collectionspace.services.common.document.DocumentWrapper;
40 import org.collectionspace.services.common.document.JaxbUtils;
41 import org.collectionspace.services.common.security.SecurityUtils;
42 import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * Document handler for Permission
50 public class PermissionDocumentHandler
51 extends JpaDocumentHandler<Permission, PermissionsList, Permission, List> {
53 private final Logger logger = LoggerFactory.getLogger(PermissionDocumentHandler.class);
54 private Permission permission;
55 private PermissionsList permissionsList;
57 public CSpaceAction getAction(ActionType action) {
58 if (ActionType.CREATE.name().equals(action.name())) {
59 return CSpaceAction.CREATE;
60 } else if (ActionType.READ.equals(action)) {
61 return CSpaceAction.READ;
62 } else if (ActionType.UPDATE.equals(action)) {
63 return CSpaceAction.UPDATE;
64 } else if (ActionType.DELETE.equals(action)) {
65 return CSpaceAction.DELETE;
66 } else if (ActionType.SEARCH.equals(action)) {
67 return CSpaceAction.SEARCH;
68 } else if (ActionType.ADMIN.equals(action)) {
69 return CSpaceAction.ADMIN;
70 } else if (ActionType.START.equals(action)) {
71 return CSpaceAction.START;
72 } else if (ActionType.STOP.equals(action)) {
73 return CSpaceAction.STOP;
76 // We could not find a match, so we need to throw an exception.
78 throw new IllegalArgumentException("action = " + action.toString());
82 * Add the ACE hashed ID to the permission action so we can map the permission to the Spring Security
85 private void handlePermissionActions(Permission perm) {
86 //FIXME: REM - Having Java class loader issues with ActionType class. Not sure of the cause.
88 List<PermissionAction> permActions = perm.getAction();
89 for (PermissionAction permAction : permActions) {
90 CSpaceAction action = getAction(permAction.getName());
91 URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(),
92 perm.getResourceName(), action);
93 permAction.setObjectIdentity(uriRes.getHashedId().toString());
94 permAction.setObjectIdentityResource(uriRes.getId());
95 //PermissionActionUtil.update(perm, permAction);
97 } catch (Exception x) {
103 public void handleCreate(DocumentWrapper<Permission> wrapDoc) throws Exception {
104 String id = UUID.randomUUID().toString();
105 Permission permission = wrapDoc.getWrappedObject();
106 permission.setCsid(id);
107 setTenant(permission);
108 handlePermissionActions(permission);
112 public void completeCreate(DocumentWrapper<Permission> wrapDoc) throws Exception {
116 public void handleUpdate(DocumentWrapper<Permission> wrapDoc) throws Exception {
117 Permission permissionFound = wrapDoc.getWrappedObject();
118 Permission permissionReceived = getCommonPart();
119 merge(permissionReceived, permissionFound);
123 * merge manually merges the from from to the to permission
124 * -this method is created due to inefficiency of JPA EM merge
127 * @return merged permission
129 private Permission merge(Permission from, Permission to) throws Exception {
130 if (!(from.getResourceName().equalsIgnoreCase(to.getResourceName()))) {
131 String msg = "Resource name cannot be changed " + to.getResourceName();
133 throw new BadRequestException(msg);
135 //resource name, attribute cannot be changed
137 if (from.getDescription() != null) {
138 to.setDescription(from.getDescription());
140 if (from.getEffect() != null) {
141 to.setEffect(from.getEffect());
143 List<PermissionAction> fromActions = from.getAction();
144 if (!fromActions.isEmpty()) {
145 //override the whole list, no reconcilliation by design
146 to.setAction(fromActions);
149 if (logger.isDebugEnabled()) {
150 logger.debug("merged permission=" + JaxbUtils.toString(to, Permission.class));
153 handlePermissionActions(to);
158 public void completeUpdate(DocumentWrapper<Permission> wrapDoc) throws Exception {
159 Permission upAcc = wrapDoc.getWrappedObject();
160 getServiceContext().setOutput(upAcc);
162 //FIXME update lower-layer authorization (acls)
163 //will require deleting old permissions for this resource and adding
164 //new based on new actions and effect
168 public void handleGet(DocumentWrapper<Permission> wrapDoc) throws Exception {
169 setCommonPart(extractCommonPart(wrapDoc));
170 sanitize(getCommonPart());
171 getServiceContext().setOutput(permission);
175 public void handleGetAll(DocumentWrapper<List> wrapDoc) throws Exception {
176 PermissionsList permissionsList = extractCommonPartList(wrapDoc);
177 setCommonPartList(permissionsList);
178 getServiceContext().setOutput(getCommonPartList());
182 public void completeDelete(DocumentWrapper<Permission> wrapDoc) throws Exception {
186 public Permission extractCommonPart(
187 DocumentWrapper<Permission> wrapDoc)
189 return wrapDoc.getWrappedObject();
193 public void fillCommonPart(Permission obj, DocumentWrapper<Permission> wrapDoc)
195 throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler");
199 public PermissionsList extractCommonPartList(
200 DocumentWrapper<List> wrapDoc)
203 PermissionsList permissionsList = new PermissionsList();
204 List<Permission> list = new ArrayList<Permission>();
205 permissionsList.setPermission(list);
206 for (Object obj : wrapDoc.getWrappedObject()) {
207 Permission permission = (Permission) obj;
208 sanitize(permission);
209 list.add(permission);
211 return permissionsList;
215 public Permission getCommonPart() {
220 public void setCommonPart(Permission permission) {
221 this.permission = permission;
225 public PermissionsList getCommonPartList() {
226 return permissionsList;
230 public void setCommonPartList(PermissionsList permissionsList) {
231 this.permissionsList = permissionsList;
235 public String getQProperty(
241 public DocumentFilter createDocumentFilter() {
242 DocumentFilter filter = new PermissionJpaFilter(this.getServiceContext());
247 * sanitize removes data not needed to be sent to the consumer
250 private void sanitize(Permission permission) {
251 if (!SecurityUtils.isCSpaceAdmin()) {
252 permission.setTenantId(null);
256 private void setTenant(Permission permission) {
257 //set tenant only if not available from input
258 if (permission.getTenantId() == null || permission.getTenantId().isEmpty()) {
259 permission.setTenantId(getServiceContext().getTenantId());