From: Sanjay Dalal Date: Thu, 6 May 2010 00:03:53 +0000 (+0000) Subject: CSPACE-1482 wired create of permissionrole to spring acl X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=56650156cf09d6317db3a8e1146283a2f8bb1c1c;p=tmp%2Fjakarta-migration.git CSPACE-1482 wired create of permissionrole to spring acl disabled authz seed test temporarily test: authz-mgt all service tests M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java M services/authorization-mgt/service/pom.xml M services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java M services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionManager.java M services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringAuthorizationProvider.java M services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java M services/authorization/service/src/main/java/org/collectionspace/services/authorization/CSpaceResourceImpl.java M services/authorization/service/src/main/java/org/collectionspace/services/authorization/URIResourceImpl.java M services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java M services/authorization/service/src/main/java/org/collectionspace/services/authorization/spi/CSpacePermissionManager.java M services/authorization/service/src/main/resources/applicationContext-authorization.xml M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java --- diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java index f2714520b..55f2bad8a 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java @@ -26,7 +26,6 @@ package org.collectionspace.services.account.storage; import java.util.Date; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; -import javax.persistence.Query; import org.collectionspace.services.account.AccountsCommon; import org.collectionspace.services.account.storage.csidp.UserStorageClient; import org.collectionspace.services.authentication.User; @@ -39,7 +38,6 @@ import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.DocumentWrapperImpl; import org.collectionspace.services.common.document.JaxbUtils; -import org.collectionspace.services.common.security.SecurityUtils; import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl; import org.collectionspace.services.common.storage.jpa.JpaStorageUtils; @@ -86,7 +84,8 @@ public class AccountStorageClient extends JpaStorageClientImpl { em = emf.createEntityManager(); em.getTransaction().begin(); //if userid and password are given, add to default id provider - if (account.getUserId() != null && isForCSIdP(account.getPassword())) { + if (account.getUserId() != null && + isForCSIdP(account.getPassword())) { User user = userStorageClient.create(account.getUserId(), account.getPassword()); em.persist(user); diff --git a/services/authorization-mgt/service/pom.xml b/services/authorization-mgt/service/pom.xml index 6f72ad1b4..9a4ae736d 100644 --- a/services/authorization-mgt/service/pom.xml +++ b/services/authorization-mgt/service/pom.xml @@ -164,6 +164,7 @@ org.collectionspace.services org.collectionspace.services.authorization.jaxb ${project.version} + provided org.collectionspace.services diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java new file mode 100644 index 000000000..47aa54670 --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java @@ -0,0 +1,186 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2010 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.authorization.storage; + +import java.util.ArrayList; +import java.util.List; +import org.collectionspace.services.authorization.ActionType; +import org.collectionspace.services.authorization.AuthZ; +import org.collectionspace.services.authorization.CSpaceAction; +import org.collectionspace.services.authorization.CSpaceResource; +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.authorization.PermissionAction; +import org.collectionspace.services.authorization.PermissionException; +import org.collectionspace.services.authorization.PermissionRole; +import org.collectionspace.services.authorization.PermissionValue; +import org.collectionspace.services.authorization.RoleValue; +import org.collectionspace.services.authorization.SubjectType; +import org.collectionspace.services.authorization.URIResourceImpl; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.storage.jpa.JpaStorageUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * AuthorizationDelegate delegates permissions management to the authorization + * service from the RESTful service + * @author + */ +public class AuthorizationDelegate { + + private final Logger logger = LoggerFactory.getLogger(AuthorizationDelegate.class); + + static void addPermissions(ServiceContext ctx, PermissionRole pr) throws Exception { + SubjectType subject = PermissionRoleUtil.getRelationSubject(ctx, pr); + AuthZ authz = AuthZ.get(); + if (subject.equals(SubjectType.ROLE)) { + PermissionValue pv = pr.getPermissions().get(0); + CSpaceResource[] resources = getResources(pv); + String[] roles = getRoles(pr.getRoles()); + for (CSpaceResource res : resources) { + authz.addPermissions(res, roles); + } + } else if (SubjectType.PERMISSION.equals(subject)) { + RoleValue rv = pr.getRoles().get(0); + String[] roles = {rv.getRoleName()}; + for (PermissionValue pv : pr.getPermissions()) { + CSpaceResource[] resources = getResources(pv); + for (CSpaceResource res : resources) { + authz.addPermissions(res, roles); + } + } + } + } + + static void deletePermissions(ServiceContext ctx, PermissionRole pr) + throws Exception { + PermissionValue pv = pr.getPermissions().get(0); + deletePermissions(pv); + } + + static void deletePermissions(PermissionValue pv) + throws Exception { + CSpaceResource[] resources = getResources(pv); + AuthZ authz = AuthZ.get(); + for (CSpaceResource res : resources) { + authz.deletePermissions(res); + } + } + + + /** + * addPermissionsForUri add permissions from given permission configuration + * with assumption that resource is of type URI + * @param permission configuration + */ + //FIXME this method should be in the restful web service resource of authz + public void addPermissionsForUri(Permission perm, + PermissionRole permRole) throws PermissionException { + List principals = new ArrayList(); + if (!perm.getCsid().equals(permRole.getPermissions().get(0).getPermissionId())) { + throw new IllegalArgumentException("permission ids do not" + + " match for role=" + permRole.getRoles().get(0).getRoleName() + + " with permissionId=" + permRole.getPermissions().get(0).getPermissionId() + + " for permission with csid=" + perm.getCsid()); + } + for (RoleValue roleValue : permRole.getRoles()) { + principals.add(roleValue.getRoleName()); + } + List permActions = perm.getActions(); + for (PermissionAction permAction : permActions) { + CSpaceAction action = getAction(permAction.getName()); + URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(), + perm.getResourceName(), action); + AuthZ.get().addPermissions(uriRes, principals.toArray(new String[0])); + } + } + + /** + * getRoles get roles (string) array from given RoleValue list + * @param rvl rolevalue list + * @return string array with role names + * @see RoleValue + */ + private static String[] getRoles(List rvl) { + List rvls = new ArrayList(); + for (RoleValue rv : rvl) { + //assumption: rolename is relationship metadata is mandatory + if (rv.getRoleName() != null) { + rvls.add(rv.getRoleName()); + } + } + return rvls.toArray(new String[0]); + } + + /** + * getResources from given PermissionValue + * @param pv permission value + * @return array of CSpaceResource + * @see PermissionValue + * @see CSpaceResource + */ + private static CSpaceResource[] getResources(PermissionValue pv) { + List rl = new ArrayList(); + Permission p = (Permission) JpaStorageUtils.getEntity(pv.getPermissionId(), + Permission.class); + if (p != null) { + for (PermissionAction pa : p.getActions()) { + + CSpaceResource res = new URIResourceImpl(pv.getResourceName(), + getAction(pa.getName())); + rl.add(res); + } + } + return rl.toArray(new CSpaceResource[0]); + } + + + /** + * getAction is a convenience method to get corresponding action for + * given ActionType + * @param action + * @return + */ + public static CSpaceAction getAction(ActionType action) { + if (ActionType.CREATE.equals(action)) { + return CSpaceAction.CREATE; + } else if (ActionType.READ.equals(action)) { + return CSpaceAction.READ; + } else if (ActionType.UPDATE.equals(action)) { + return CSpaceAction.UPDATE; + } else if (ActionType.DELETE.equals(action)) { + return CSpaceAction.DELETE; + } else if (ActionType.SEARCH.equals(action)) { + return CSpaceAction.SEARCH; + } else if (ActionType.ADMIN.equals(action)) { + return CSpaceAction.ADMIN; + } else if (ActionType.START.equals(action)) { + return CSpaceAction.START; + } else if (ActionType.STOP.equals(action)) { + return CSpaceAction.STOP; + } + throw new IllegalArgumentException("action = " + action.toString()); + } + +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java index 8a266d0ca..f15f8c877 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java @@ -60,6 +60,10 @@ public class PermissionDocumentHandler permission.setTenantId(getServiceContext().getTenantId()); } + @Override + public void completeCreate(DocumentWrapper wrapDoc) throws Exception { + } + @Override public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { Permission permissionFound = wrapDoc.getWrappedObject(); @@ -90,7 +94,7 @@ public class PermissionDocumentHandler to.setEffect(from.getEffect()); } List fromActions = from.getActions(); - if(!fromActions.isEmpty()) { + if (!fromActions.isEmpty()) { //override the whole list, no reconcilliation by design to.setActions(fromActions); } @@ -123,6 +127,10 @@ public class PermissionDocumentHandler getServiceContext().setOutput(getCommonPartList()); } + @Override + public void completeDelete(DocumentWrapper wrapDoc) throws Exception { + } + @Override public Permission extractCommonPart( DocumentWrapper wrapDoc) diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java index 4ac3831ae..25ebb3b80 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java @@ -55,6 +55,12 @@ public class PermissionRoleDocumentHandler fillCommonPart(getCommonPart(), wrapDoc); } + @Override + public void completeCreate(DocumentWrapper> wrapDoc) throws Exception { + PermissionRole pr = getCommonPart(); + AuthorizationDelegate.addPermissions(getServiceContext(), pr); + } + @Override public void handleUpdate(DocumentWrapper> wrapDoc) throws Exception { throw new UnsupportedOperationException("operation not relevant for PermissionRoleDocumentHandler"); @@ -76,13 +82,20 @@ public class PermissionRoleDocumentHandler throw new UnsupportedOperationException("operation not relevant for PermissionRoleDocumentHandler"); } + + @Override + public void completeDelete(DocumentWrapper> wrapDoc) throws Exception { + PermissionRole pr = getCommonPart(); + AuthorizationDelegate.deletePermissions(getServiceContext(), pr); + } + @Override public PermissionRole extractCommonPart( DocumentWrapper> wrapDoc) throws Exception { List prrl = wrapDoc.getWrappedObject(); PermissionRole pr = new PermissionRole(); - SubjectType subject = PermissionRoleUtil.getSubject(getServiceContext()); + SubjectType subject = PermissionRoleUtil.getRelationSubject(getServiceContext()); PermissionRoleRel prr0 = prrl.get(0); if (SubjectType.ROLE.equals(subject)) { @@ -123,7 +136,7 @@ public class PermissionRoleDocumentHandler SubjectType subject = pr.getSubject(); if (subject == null) { //it is not required to give subject as URI determines the subject - subject = PermissionRoleUtil.getSubject(getServiceContext()); + subject = PermissionRoleUtil.getRelationSubject(getServiceContext()); } else { //subject mismatch should have been checked during validation } diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java index 378bdb47a..77e702128 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java @@ -23,6 +23,7 @@ */ package org.collectionspace.services.authorization.storage; +import org.collectionspace.services.authorization.PermissionRole; import org.collectionspace.services.authorization.SubjectType; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.context.ServiceContextProperties; @@ -33,7 +34,7 @@ import org.collectionspace.services.common.context.ServiceContextProperties; */ public class PermissionRoleUtil { - static SubjectType getSubject(ServiceContext ctx) { + static SubjectType getRelationSubject(ServiceContext ctx) { Object o = ctx.getProperty(ServiceContextProperties.SUBJECT); if (o == null) { throw new IllegalArgumentException(ServiceContextProperties.SUBJECT + @@ -42,4 +43,14 @@ public class PermissionRoleUtil { } return (SubjectType) o; } + + + static SubjectType getRelationSubject(ServiceContext ctx, PermissionRole pr) { + SubjectType subject = pr.getSubject(); + if (subject == null) { + //it is not required to give subject as URI determines the subject + subject = getRelationSubject(ctx); + } + return subject; + } } diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java index 059c5e89f..8253d1641 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/AuthZ.java @@ -75,91 +75,102 @@ public class AuthZ { } /** - * addUriPermissions add permissions from given permission configuration - * with assumption that resource is of type URI - * @param permission configuration + * addPermissions add permission for given principals to access given resource + * -action info is retrieved from the resource + * @param res + * @param principals */ - //FIXME this method should be in the restful web service resource of authz - public void addUriPermissions(Permission perm, - PermissionRole permRole) throws PermissionException { - List principals = new ArrayList(); - if (!perm.getCsid().equals(permRole.getPermissions().get(0).getPermissionId())) { - throw new IllegalArgumentException("permission ids do not" - + " match for role=" + permRole.getRoles().get(0).getRoleName() - + " with permissionId=" + permRole.getPermissions().get(0).getPermissionId() - + " for permission with csid=" + perm.getCsid()); - } - for (RoleValue roleValue : permRole.getRoles()) { - principals.add(roleValue.getRoleName()); - } - List permActions = perm.getActions(); - for (PermissionAction permAction : permActions) { - URIResourceImpl uriRes = new URIResourceImpl(perm.getTenantId(), - perm.getResourceName(), - permAction.getName()); - addPermission(uriRes, principals.toArray(new String[0])); - } + public void addPermissions(CSpaceResource res, String[] principals) throws PermissionException { + CSpaceAction action = res.getAction(); + addPermissions(res, action, principals); + } + + /** + * addPermissions add permission for given principals to invoke given action on given resource + * @param res + * @parm action + * @param principals + */ + public void addPermissions(CSpaceResource res, CSpaceAction action, String[] principals) + throws PermissionException { + provider.getPermissionManager().addPermissions(res, action, principals); } /** - * addPermission for given principals to access given resource - * -permission is retrieved from the resource + * deletePermissions delete permission(s) for given resource involving given + * principals + * - action is retrieved from the resource * @param res * @param principals */ - public void addPermission(CSpaceResource res, String[] principals) throws PermissionException { + public void deletePermissions(CSpaceResource res, String[] principals) + throws PermissionNotFoundException, PermissionException { CSpaceAction action = res.getAction(); - addPermission(res, principals, action); + deletePermissions(res, action, principals); } /** - * addPermission add given permission for given principals to access given resource + * deletePermissions delete permission(s) for given action on given resource + * involving given principals * @param res + * @param action * @param principals - * @param perm */ - public void addPermission(CSpaceResource res, String[] principals, CSpaceAction action) - throws PermissionException { - provider.getPermissionManager().addPermission(res, principals, action); - if (log.isDebugEnabled()) { - log.debug("added permission resource=" + res.getId() + " action=" + action.name()); - } + public void deletePermissions(CSpaceResource res, CSpaceAction action, String[] principals) + throws PermissionNotFoundException, PermissionException { + provider.getPermissionManager().deletePermissions(res, action, principals); } /** - * deletePermission for given principals for given resource - * permission is retrieve from the resource + * deletePermissions delete permission(s) for given resource involving any + * principal + * - action is retrieved from the resource if available else applicable to + * all actions associated with the resource * @param res * @param principals */ - public void deletePermission(CSpaceResource res, String[] principals) + public void deletePermissions(CSpaceResource res) throws PermissionNotFoundException, PermissionException { CSpaceAction action = res.getAction(); - deletePermission(res, principals, action); + if (action != null) { + deletePermissions(res, action); + } else { + provider.getPermissionManager().deletePermissions(res); + } } /** - * deletePermission given permission for given principals for given resource + * deletePermissions delete permission(s) for given action on given resource + * involving given principals * @param res + * @param action * @param principals - * @param perm */ - public void deletePermission(CSpaceResource res, String[] principals, CSpaceAction action) + public void deletePermissions(CSpaceResource res, CSpaceAction action) throws PermissionNotFoundException, PermissionException { - provider.getPermissionManager().deletePermission(res, principals, action); - if (log.isDebugEnabled()) { - log.debug("removed permission resource=" + res.getId() + " action=" + action.name()); - } + provider.getPermissionManager().deletePermissions(res, action); } /** * isAccessAllowed check if authenticated principal is allowed to access - * given resource, permission is retrieved from the resource + * given resource + * action is retrieved from the resource if available * @param res * @return */ public boolean isAccessAllowed(CSpaceResource res) { CSpaceAction action = res.getAction(); + return isAccessAllowed(res, action); + } + + + /** + * isAccessAllowed check if authenticated principal is allowed to invoke + * given action on given resource + * @param res + * @return + */ + public boolean isAccessAllowed(CSpaceResource res, CSpaceAction action) { return provider.getPermissionEvaluator().hasPermission(res, action); } } diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/CSpaceResourceImpl.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/CSpaceResourceImpl.java index 07d0c04ad..5ebf0ac7c 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/CSpaceResourceImpl.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/CSpaceResourceImpl.java @@ -75,11 +75,11 @@ public abstract class CSpaceResourceImpl implements CSpaceResource { if (type == null) { throw new IllegalArgumentException("type cannot be null"); } - this.action = action; + this.type = type; if (action == null) { throw new IllegalArgumentException("action cannot be null"); } - this.type = type; + this.action = action; } @Override diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/URIResourceImpl.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/URIResourceImpl.java index 4415611d4..793a32696 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/URIResourceImpl.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/URIResourceImpl.java @@ -66,10 +66,10 @@ public class URIResourceImpl extends CSpaceResourceImpl { * @param resourceName * @param actionType */ - public URIResourceImpl(String resourceName, ActionType actionType) { + public URIResourceImpl(String resourceName, CSpaceAction action) { //FIXME more validation might be needed - super(buildId(resourceName, getAction(actionType)), - getAction(actionType), TYPE.URI); + super(buildId(resourceName, action), + action, TYPE.URI); } /** @@ -78,9 +78,9 @@ public class URIResourceImpl extends CSpaceResourceImpl { * @param resourceName * @param actionType */ - public URIResourceImpl(String tenantId, String resourceName, ActionType actionType) { - super(tenantId, buildId(resourceName, getAction(actionType)), - getAction(actionType), TYPE.URI); + public URIResourceImpl(String tenantId, String resourceName, CSpaceAction action) { + super(tenantId, buildId(resourceName, action), + action, TYPE.URI); } /** @@ -127,33 +127,6 @@ public class URIResourceImpl extends CSpaceResourceImpl { throw new IllegalStateException("no method found!"); } - /** - * getAction is a convenience method to get corresponding action for - * given ActionType - * @param action - * @return - */ - public static CSpaceAction getAction(ActionType action) { - if (ActionType.CREATE.equals(action)) { - return CSpaceAction.CREATE; - } else if (ActionType.READ.equals(action)) { - return CSpaceAction.READ; - } else if (ActionType.UPDATE.equals(action)) { - return CSpaceAction.UPDATE; - } else if (ActionType.DELETE.equals(action)) { - return CSpaceAction.DELETE; - } else if (ActionType.SEARCH.equals(action)) { - return CSpaceAction.SEARCH; - } else if (ActionType.ADMIN.equals(action)) { - return CSpaceAction.ADMIN; - } else if (ActionType.START.equals(action)) { - return CSpaceAction.START; - } else if (ActionType.STOP.equals(action)) { - return CSpaceAction.STOP; - } - throw new IllegalArgumentException("action = " + action.toString()); - } - @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spi/CSpacePermissionManager.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spi/CSpacePermissionManager.java index 5133c3d65..f281f4c6d 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spi/CSpacePermissionManager.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spi/CSpacePermissionManager.java @@ -34,9 +34,50 @@ import org.collectionspace.services.authorization.PermissionNotFoundException; */ public interface CSpacePermissionManager { - public void addPermission(CSpaceResource res, String[] principals, CSpaceAction perm) + /** + * addPermisison adds permission for given action on given resource for given principals + * @param res resource + * @param principals an array of principal names + * @action action on the resource + * @throws PermissionException + * @see CSpaceResource + * @see CSpaceAction + */ + public void addPermissions(CSpaceResource res, CSpaceAction action, String[] principals) throws PermissionException; - public void deletePermission(CSpaceResource res, String[] principals, CSpaceAction perm) + /** + * removePermission removes permission(s) for given action on given resource involving given principals + * @param res + * @param action + * @param principals + * @throws PermissionNotFoundException + * @throws PermissionException + * @see CSpaceResource + * @see CSpaceAction + */ + public void deletePermissions(CSpaceResource res, CSpaceAction action, String[] principals) + throws PermissionNotFoundException, PermissionException; + + /** + * deletePermissions delete all permissions for given action on given resource + * @param res + * @param action + * @throws PermissionNotFoundException + * @throws PermissionException + * @see CSpaceResource + * @see CSpaceAction + */ + public void deletePermissions(CSpaceResource res, CSpaceAction action) + throws PermissionNotFoundException, PermissionException; + + /** + * deletePermissions delete all permissions for given resource + * @param res + * @throws PermissionNotFoundException + * @throws PermissionException + * @see CSpaceResource + */ + public void deletePermissions(CSpaceResource res) throws PermissionNotFoundException, PermissionException; } diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringAuthorizationProvider.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringAuthorizationProvider.java index 6d7bbe70b..8c53fd96c 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringAuthorizationProvider.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringAuthorizationProvider.java @@ -32,6 +32,7 @@ import org.collectionspace.services.authorization.spi.CSpaceAuthorizationProvide import org.collectionspace.services.authorization.spi.CSpacePermissionEvaluator; import org.collectionspace.services.authorization.spi.CSpacePermissionManager; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.acls.domain.BasePermission; import org.springframework.security.acls.domain.GrantedAuthoritySid; @@ -40,6 +41,9 @@ import org.springframework.security.acls.model.MutableAclService; import org.springframework.security.acls.model.ObjectIdentity; import org.springframework.security.acls.model.Permission; import org.springframework.security.acls.model.Sid; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionDefinition; /** * SpringAuthorizationProvider Spring Security provider @@ -52,6 +56,8 @@ public class SpringAuthorizationProvider implements CSpaceAuthorizationProvider private MutableAclService providerAclService; @Autowired private PermissionEvaluator providerPermissionEvaluator; + @Autowired + private DataSourceTransactionManager txManager; private SpringPermissionEvaluator permissionEvaluator; private SpringPermissionManager permissionManager; private String version = "1.0"; @@ -66,7 +72,7 @@ public class SpringAuthorizationProvider implements CSpaceAuthorizationProvider } public void setProviderAclService(MutableAclService mutableAclService) { - this.providerAclService = mutableAclService; + this.providerAclService = mutableAclService; if (log.isDebugEnabled()) { log.debug("mutableAclService set"); } @@ -123,6 +129,7 @@ public class SpringAuthorizationProvider implements CSpaceAuthorizationProvider case CREATE: return BasePermission.CREATE; case READ: + case SEARCH: return BasePermission.READ; case UPDATE: return BasePermission.WRITE; @@ -131,4 +138,34 @@ public class SpringAuthorizationProvider implements CSpaceAuthorizationProvider } return null; } + + /** + * @return the txManager + */ + DataSourceTransactionManager getTxManager() { + return txManager; + } + + /** + * @param txManager the txManager to set + */ + public void setTxManager(DataSourceTransactionManager txManager) { + this.txManager = txManager; + } + + TransactionStatus beginTransaction(String name) { + DefaultTransactionDefinition def = new DefaultTransactionDefinition(); + // explicitly setting the transaction name is something that can only be done programmatically + def.setName(name); + def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); + return getTxManager().getTransaction(def); + } + + void rollbackTransaction(TransactionStatus status) { + getTxManager().rollback(status); + } + + void commitTransaction(TransactionStatus status) { + getTxManager().commit(status); + } } diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java index 2f5b6d030..9b75ef956 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java @@ -52,6 +52,9 @@ public class SpringPermissionEvaluator implements CSpacePermissionEvaluator { PermissionEvaluator eval = provider.getProviderPermissionEvaluator(); Permission p = SpringAuthorizationProvider.mapPermssion(perm); Authentication authToken = SecurityContextHolder.getContext().getAuthentication(); - return eval.hasPermission(authToken, Long.valueOf(res.getId().hashCode()), res.getType().toString(), p); + return eval.hasPermission(authToken, + Long.valueOf(res.getId().hashCode()), + res.getType().toString(), + p); } } diff --git a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionManager.java b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionManager.java index 64a14253f..62e6c1b34 100644 --- a/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionManager.java +++ b/services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionManager.java @@ -31,13 +31,16 @@ import org.collectionspace.services.authorization.spi.CSpacePermissionManager; import org.collectionspace.services.authorization.CSpaceResource; import org.collectionspace.services.authorization.PermissionException; import org.collectionspace.services.authorization.PermissionNotFoundException; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.security.acls.model.AccessControlEntry; import org.springframework.security.acls.model.MutableAcl; -import org.springframework.security.acls.model.MutableAclService; import org.springframework.security.acls.model.NotFoundException; import org.springframework.security.acls.model.ObjectIdentity; import org.springframework.security.acls.model.Permission; import org.springframework.security.acls.model.Sid; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionDefinition; /** * Manages permissions in Spring Security @@ -53,105 +56,180 @@ public class SpringPermissionManager implements CSpacePermissionManager { } @Override - public void addPermission(CSpaceResource res, String[] principals, CSpaceAction perm) + public void addPermissions(CSpaceResource res, CSpaceAction action, String[] principals) throws PermissionException { ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res); Sid[] sids = SpringAuthorizationProvider.mapPrincipal(principals); - Permission p = SpringAuthorizationProvider.mapPermssion(perm); - for (Sid sid : sids) { - addPermission(oid, sid, p); + Permission p = SpringAuthorizationProvider.mapPermssion(action); + TransactionStatus status = provider.beginTransaction("addPermssions"); + try { + for (Sid sid : sids) { + addPermission(oid, p, sid); + if (log.isDebugEnabled()) { + log.debug("added permission " + + " res=" + res.toString() + + " action=" + action.toString() + + " oid=" + oid.toString() + + " perm=" + p.toString() + + " sid=" + sids.toString()); + } + } + } catch (Exception ex) { + provider.rollbackTransaction(status); if (log.isDebugEnabled()) { - log.debug("added permission " - + " res=" + res.toString() - + " cperm=" + perm.toString() - + convertToString(principals) - + " oid=" + oid.toString() - + " perm=" + p.toString() - + " sid=" + sids.toString()); + ex.printStackTrace(); } + throw new PermissionException(ex); } + provider.commitTransaction(status); + } - private void addPermission(ObjectIdentity oid, Sid recipient, Permission permission) { - MutableAcl acl; - MutableAclService mutableAclService = provider.getProviderAclService(); + @Override + public void deletePermissions(CSpaceResource res, CSpaceAction action, String[] principals) + throws PermissionNotFoundException, PermissionException { + ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res); + Sid[] sids = SpringAuthorizationProvider.mapPrincipal(principals); + Permission p = SpringAuthorizationProvider.mapPermssion(action); + TransactionStatus status = provider.beginTransaction("deletePermssions"); try { - acl = (MutableAcl) mutableAclService.readAclById(oid); + for (Sid sid : sids) { + deletePermissions(oid, p, sid); + if (log.isDebugEnabled()) { + log.debug("deleted permission " + + " res=" + res.toString() + + " action=" + action.toString() + + " oid=" + oid.toString() + + " perm=" + p.toString() + + " sid=" + sids.toString()); + } + } + } catch (Exception ex) { + provider.rollbackTransaction(status); if (log.isDebugEnabled()) { - log.debug("addPermission: found acl for oid=" + oid.toString()); + ex.printStackTrace(); } - } catch (NotFoundException nfe) { - acl = mutableAclService.createAcl(oid); - } - - acl.insertAce(acl.getEntries().size(), permission, recipient, true); - mutableAclService.updateAcl(acl); - if (log.isDebugEnabled()) { - log.debug("addPermission: added acl for oid=" + oid.toString() - + " perm=" + permission.toString() - + " sid=" + recipient.toString()); + throw new PermissionException(ex); } + provider.commitTransaction(status); } @Override - public void deletePermission(CSpaceResource res, String[] principals, CSpaceAction perm) + public void deletePermissions(CSpaceResource res, CSpaceAction action) throws PermissionNotFoundException, PermissionException { ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res); - Sid[] sids = SpringAuthorizationProvider.mapPrincipal(principals); - Permission p = SpringAuthorizationProvider.mapPermssion(perm); - for (Sid sid : sids) { - deletePermission(oid, sid, p); + Permission p = SpringAuthorizationProvider.mapPermssion(action); + TransactionStatus status = provider.beginTransaction("deletePermssions"); + try { + deletePermissions(oid, p, null); if (log.isDebugEnabled()) { - log.debug("deleted permission " + log.debug("deleted permissions " + " res=" + res.toString() - + " cperm=" + perm.toString() - + convertToString(principals) + + " action=" + action.toString() + " oid=" + oid.toString() - + " perm=" + p.toString() - + " sid=" + sids.toString()); + + " perm=" + p.toString()); + } + } catch (Exception ex) { + provider.rollbackTransaction(status); + if (log.isDebugEnabled()) { + ex.printStackTrace(); } + throw new PermissionException(ex); } + provider.commitTransaction(status); + + } - private void deletePermission(ObjectIdentity oid, Sid recipient, Permission permission) - throws PermissionException { + @Override + public void deletePermissions(CSpaceResource res) + throws PermissionNotFoundException, PermissionException { + ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res); + TransactionStatus status = provider.beginTransaction("addPermssion"); + try { + provider.getProviderAclService().deleteAcl(oid, true); + } catch (Exception ex) { + provider.rollbackTransaction(status); + if (log.isDebugEnabled()) { + ex.printStackTrace(); + } + throw new PermissionException(ex); + } + provider.commitTransaction(status); - MutableAclService mutableAclService = provider.getProviderAclService(); - MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid); if (log.isDebugEnabled()) { - log.debug("deletePermission: found acl for oid=" + oid.toString()); + log.debug("deleted permissions " + + " res=" + res.toString() + + " oid=" + oid.toString()); } - if (acl == null) { - String msg = "Cound not find acl for oid=" + oid.toString(); - log.error(msg); - throw new PermissionNotFoundException(msg); + } + + private void addPermission(ObjectIdentity oid, Permission permission, + Sid recipient) throws PermissionException { + MutableAcl acl; + + try { + acl = getAcl(oid); + } catch (PermissionException pnfe) { + acl = provider.getProviderAclService().createAcl(oid); + } + acl.insertAce(acl.getEntries().size(), permission, recipient, true); + provider.getProviderAclService().updateAcl(acl); + + if (log.isDebugEnabled()) { + log.debug("addPermission: added acl for oid=" + oid.toString() + + " perm=" + permission.toString() + + " sid=" + recipient.toString()); } - // Remove all permissions associated with this particular recipient (string equality to KISS) + } + + private void deletePermissions(ObjectIdentity oid, Permission permission, Sid recipient) + throws PermissionException { + + int j = 0; + MutableAcl acl = getAcl(oid); List entries = acl.getEntries(); if (log.isDebugEnabled()) { - log.debug("deletePermission: for acl oid=" + oid.toString() + log.debug("deletePermissions: for acl oid=" + oid.toString() + " found " + entries.size() + " aces"); } + for (int i = 0; i < entries.size(); i++) { - if (entries.get(i).getSid().equals(recipient) - && entries.get(i).getPermission().equals(permission)) { - acl.deleteAce(i); + AccessControlEntry ace = entries.get(i); + if (recipient != null) { + if (ace.getSid().equals(recipient) + && ace.getPermission().equals(permission)) { + acl.deleteAce(i); + j++; + } + } else { + if (ace.getPermission().equals(permission)) { + acl.deleteAce(i); + j++; + } } } - mutableAclService.updateAcl(acl); + provider.getProviderAclService().updateAcl(acl); + if (log.isDebugEnabled()) { - log.debug("deletePermission: for acl oid=" + oid.toString() - + " deleted " + entries.size() + " aces"); + log.debug("deletePermissions: for acl oid=" + oid.toString() + + " deleted " + j + " aces"); } } - private String convertToString(String[] stra) { - StringBuilder builder = new StringBuilder(); - for (String s : stra) { - builder.append(s); - builder.append(" "); + private MutableAcl getAcl(ObjectIdentity oid) throws PermissionNotFoundException { + MutableAcl acl = null; + try { + acl = (MutableAcl) provider.getProviderAclService().readAclById(oid); + if (log.isDebugEnabled()) { + log.debug("found acl for oid=" + oid.toString()); + } + } catch (NotFoundException nfe) { + String msg = "Cound not find acl for oid=" + oid.toString(); + log.error(msg); + throw new PermissionNotFoundException(msg); } - return builder.toString(); + return acl; } } diff --git a/services/authorization/service/src/main/resources/applicationContext-authorization.xml b/services/authorization/service/src/main/resources/applicationContext-authorization.xml index cd22bcda6..11f91f71e 100644 --- a/services/authorization/service/src/main/resources/applicationContext-authorization.xml +++ b/services/authorization/service/src/main/resources/applicationContext-authorization.xml @@ -84,5 +84,6 @@ + diff --git a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java index a5660580f..8404f9975 100644 --- a/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java +++ b/services/authorization/service/src/test/java/org/collectionspace/services/authorization/test/AuthorizationSeedTest.java @@ -83,7 +83,7 @@ public class AuthorizationSeedTest extends AbstractAuthorizationTestImpl { } for (PermissionRole pr : pcrList.getPermissionRoles()) { if (pr.getPermissions().get(0).getPermissionId().equals(p.getCsid())) { - authZ.addUriPermissions(p, pr); +// authZ.addPermissionsForUri(p, pr); } } }