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;
26 import org.collectionspace.services.account.AccountRoleSubResource;
27 import org.collectionspace.services.client.RoleClient;
28 import org.collectionspace.services.common.SecurityResourceBase;
29 import org.collectionspace.services.common.ServiceMessages;
30 import org.collectionspace.services.common.context.RemoteServiceContextFactory;
31 import org.collectionspace.services.common.context.ServiceContext;
32 import org.collectionspace.services.common.context.ServiceContextFactory;
33 import org.collectionspace.services.common.document.DocumentNotFoundException;
34 import org.collectionspace.services.common.storage.StorageClient;
35 import org.collectionspace.services.common.storage.TransactionContext;
36 import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl;
37 import org.collectionspace.services.common.CSWebApplicationException;
39 import org.jboss.resteasy.util.HttpResponseCodes;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import javax.ws.rs.Consumes;
44 import javax.ws.rs.DELETE;
45 import javax.ws.rs.GET;
46 import javax.ws.rs.POST;
47 import javax.ws.rs.PUT;
48 import javax.ws.rs.Path;
49 import javax.ws.rs.PathParam;
50 import javax.ws.rs.Produces;
51 import javax.ws.rs.QueryParam;
52 import javax.ws.rs.core.Context;
53 import javax.ws.rs.core.Response;
54 import javax.ws.rs.core.UriBuilder;
55 import javax.ws.rs.core.UriInfo;
57 @Path(RoleClient.SERVICE_PATH)
58 @Consumes("application/xml")
59 @Produces("application/xml")
60 @SuppressWarnings("unchecked")
61 public class RoleResource extends SecurityResourceBase<Role, Role> {
63 final Logger logger = LoggerFactory.getLogger(RoleResource.class);
64 final StorageClient storageClient = new JpaStorageClientImpl();
67 protected String getVersionString() {
68 return "$LastChangedRevision: 1165 $";
72 public String getServiceName() {
73 return RoleClient.SERVICE_NAME;
77 public Class<RoleResource> getCommonPartClass() {
78 return RoleResource.class;
82 public ServiceContextFactory<Role, Role> getServiceContextFactory() {
83 return RemoteServiceContextFactory.get();
87 public StorageClient getStorageClient(ServiceContext<Role, Role> ctx) {
88 //FIXME use ctx to identify storage client
93 public Response createRole(Role input) {
99 public Role getRole(@PathParam("csid") String csid, @Context UriInfo ui) {
100 return (Role)get(ui, csid, Role.class);
104 * Get a list of accounts associated with this role.
107 @Path("{csid}/accountroles")
108 public AccountRole getRoleAccounts(
109 @PathParam("csid") String accCsid) {
110 logger.debug("getAccountRole with accCsid=" + accCsid);
111 ensureCSID(accCsid, ServiceMessages.GET_FAILED+ "accountroles role ");
113 AccountRole result = null;
115 AccountRoleSubResource subResource =
116 new AccountRoleSubResource(AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
117 //get relationships for a role
118 result = subResource.getAccountRole((ServiceContext<Role, Role>)null, accCsid, SubjectType.ACCOUNT);
119 } catch (Exception e) {
120 throw bigReThrow(e, ServiceMessages.GET_FAILED, accCsid);
122 checkResult(result, accCsid, ServiceMessages.GET_FAILED);
128 @Produces("application/xml")
129 public RolesList getRoleList(@Context UriInfo ui) {
130 return (RolesList)getList(ui, Role.class);
135 public Role updateRole(@PathParam("csid") String csid, Role theUpdate) {
139 Role role = (Role)get(csid, Role.class);
140 // If marked as metadata immutable, do not update
141 if (RoleClient.IMMUTABLE.equals(role.getMetadataProtection())) {
143 Response.status(Response.Status.FORBIDDEN).entity("Role: "+csid+" is immutable.").type("text/plain").build();
144 throw new CSWebApplicationException(response);
146 result = (Role)update(csid, theUpdate, Role.class);
147 } catch (Exception e) {
148 throw bigReThrow(e, ServiceMessages.UPDATE_FAILED, csid);
156 public Response deleteRole(@PathParam("csid") String csid, @Context UriInfo ui) throws Exception {
157 logger.debug("deleteRole with csid=" + csid);
158 ensureCSID(csid, ServiceMessages.DELETE_FAILED + "deleteRole ");
160 ServiceContext<Role, Role> ctx = createServiceContext((Role) null, Role.class);
161 TransactionContext transactionContext = ctx.openConnection(); // ensure we do all this in one transaction
163 transactionContext.beginTransaction();
164 Role role = (Role)get(csid, Role.class);
165 // If marked as metadata immutable, do not delete
166 if (RoleClient.IMMUTABLE.equals(role.getMetadataProtection())) {
168 Response.status(Response.Status.FORBIDDEN).entity("Role: "+csid+" is immutable.").type("text/plain").build(); // FIXME: Should be status code 423 (resource locked)
172 // delete all the permission/role relationships (if any)
174 PermissionRoleSubResource permRoleResource =
175 new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
177 permRoleResource.deletePermissionRole(ctx, csid, SubjectType.PERMISSION);
178 } catch (DocumentNotFoundException dnf) {
179 // consume exception, not a problem. Just means no relationships exist
182 //delete all the account/role relationships associate with this role
184 AccountRoleSubResource accountRoleResource =
185 new AccountRoleSubResource(AccountRoleSubResource.ROLE_ACCOUNTROLE_SERVICE);
186 accountRoleResource.deleteAccountRole(ctx, csid, SubjectType.ACCOUNT);
188 //finally, delete the role itself
190 ((JpaStorageClientImpl) getStorageClient(ctx)).deleteWhere(ctx, csid); // FIXME: We should/could get rid the SID in Spring Security table as well
191 transactionContext.commitTransaction();
192 } catch(Exception e) {
193 transactionContext.markForRollback();
194 throw bigReThrow(e, ServiceMessages.DELETE_FAILED, csid);
196 ctx.closeConnection();
199 return Response.status(HttpResponseCodes.SC_OK).build();
203 @Path("{csid}/permroles")
204 public Response createRolePermission(@QueryParam("_method") String method, @PathParam("csid") String roleCsid,
205 PermissionRole input) {
206 if (method != null) { // FIXME: Not sure how method could every be "delete"
207 if ("delete".equalsIgnoreCase(method)) {
208 return deleteRolePermission(roleCsid, input);
212 logger.debug("createRolePermission with roleCsid=" + roleCsid);
213 ensureCSID(roleCsid, ServiceMessages.PUT_FAILED + "permroles role ");
214 Response response = null;
216 Role role = (Role)get(roleCsid, Role.class);
218 // If marked as metadata immutable, do not change
220 if (RoleClient.IMMUTABLE.equals(role.getPermsProtection())) {
222 Response.status(Response.Status.FORBIDDEN).entity("Role: "+roleCsid+" is immutable.").type("text/plain").build();
226 // Create new role-permission relationships
228 PermissionRoleSubResource subResource =
229 new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
230 String permrolecsid = subResource.createPermissionRole((ServiceContext<Role, Role>)null, input, SubjectType.PERMISSION);
231 UriBuilder path = UriBuilder.fromResource(RoleResource.class);
232 path.path(roleCsid + "/permroles/" + permrolecsid);
233 response = Response.created(path.build()).build();
234 } catch (Exception e) {
235 throw bigReThrow(e, ServiceMessages.DELETE_FAILED, roleCsid);
242 @Path("{csid}/permroles")
243 public PermissionRole getRolePermission(
244 @PathParam("csid") String roleCsid) {
245 logger.debug("getRolePermission with roleCsid=" + roleCsid);
246 ensureCSID(roleCsid, ServiceMessages.GET_FAILED + "permroles role ");
248 PermissionRole result = null;
250 PermissionRoleSubResource subResource =
251 new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
252 //get relationships for a role
253 result = subResource.getPermissionRole((ServiceContext<Role, Role>)null, roleCsid, SubjectType.PERMISSION);
254 } catch (Exception e) {
255 throw bigReThrow(e, ServiceMessages.GET_FAILED, roleCsid);
257 checkResult(result, roleCsid, ServiceMessages.GET_FAILED);
263 @Path("{csid}/permroles/{id}")
264 public PermissionRoleRel getRolePermission(
265 @PathParam("csid") String roleCsid,
266 @PathParam("id") String permrolecsid) {
267 logger.debug("getRolePermission with roleCsid=" + roleCsid);
268 ensureCSID(roleCsid, ServiceMessages.GET_FAILED + "permroles role ");
270 PermissionRoleRel result = null;
272 PermissionRoleSubResource subResource =
273 new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
274 //get relationships for a role
275 result = subResource.getPermissionRoleRel((ServiceContext<Role, Role>)null, roleCsid, SubjectType.PERMISSION, permrolecsid);
276 } catch (Exception e) {
277 throw bigReThrow(e, ServiceMessages.GET_FAILED, roleCsid);
279 checkResult(result, roleCsid, ServiceMessages.GET_FAILED);
284 public Response deleteRolePermission(String roleCsid, PermissionRole input) {
285 logger.debug("deleteRolePermission with roleCsid=" + roleCsid);
286 ensureCSID(roleCsid, ServiceMessages.DELETE_FAILED + "permroles role ");
288 Response result = null;
290 Role role = (Role)get(roleCsid, Role.class);
291 // If marked as metadata immutable, do not delete
292 if (RoleClient.IMMUTABLE.equals(role.getPermsProtection())) {
293 Response response = Response.status(Response.Status.FORBIDDEN).entity(
294 "Role: "+roleCsid+" is immutable.").type("text/plain").build();
297 PermissionRoleSubResource subResource =
298 new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
299 //delete all relationships for a permission
300 subResource.deletePermissionRole((ServiceContext<Role, Role>)null, roleCsid, SubjectType.PERMISSION, input);
301 result = Response.status(HttpResponseCodes.SC_OK).build();
302 } catch (Exception e) {
303 throw bigReThrow(e, ServiceMessages.DELETE_FAILED, roleCsid);
310 @Path("{csid}/permroles")
311 public Response deleteRolePermission(
312 @PathParam("csid") String roleCsid) {
313 logger.debug("deleteRolePermission with roleCsid=" + roleCsid);
314 ensureCSID(roleCsid, ServiceMessages.DELETE_FAILED + "permroles role ");
317 Role role = (Role)get(roleCsid, Role.class);
318 // If marked as metadata immutable, do not delete
319 if (RoleClient.IMMUTABLE.equals(role.getPermsProtection())) {
321 Response.status(Response.Status.FORBIDDEN).entity("Role: "+roleCsid+" is immutable.").type("text/plain").build();
324 PermissionRoleSubResource subResource =
325 new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
326 //delete all relationships for a permission
327 subResource.deletePermissionRole((ServiceContext<Role, Role>)null, roleCsid, SubjectType.PERMISSION);
328 } catch (Exception e) {
329 throw bigReThrow(e, ServiceMessages.DELETE_FAILED, roleCsid);
332 return Response.status(HttpResponseCodes.SC_OK).build();