]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5741 - Fixed bugs in import that were not correcting detecting existing entrie...
authorPatrick Schmitz <pschmitz@berkeley.edu>
Fri, 1 Feb 2013 21:47:09 +0000 (13:47 -0800)
committerPatrick Schmitz <pschmitz@berkeley.edu>
Fri, 1 Feb 2013 21:47:09 +0000 (13:47 -0800)
Fix another bug in the SpringPermissionManager.java that was not checking for existing ace's before adding new ones. This led to duplicate entries (not an error, but inefficient) when ant import was run multiple times.

services/authentication/service/src/main/java/org/collectionspace/authentication/spring/SpringAuthNContext.java
services/authorization-mgt/import/src/main/resources/log4j.properties
services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionManager.java
services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationStore.java
services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/RoleStorageConstants.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java

index 27801a2b41f4882ded1549618334b6ca9c5d1a8f..17b59baa635777d23a28f20f3666349790238688 100644 (file)
@@ -78,6 +78,7 @@ final public class SpringAuthNContext extends AuthNContext {
         if (caller == null) {
             String msg = "Could not find Subject!";
             //TODO: find out why subject is not null
+            // Can happen during ant import, when there is no session/user.
             //FIXME: if logger is loaded when authn comes up, use it
             //logger.warn(msg);
             System.err.println(msg);
index b245250850b79708ee89cc34b42e397cae92f98d..79746b946e6dc75107dd034e868491cfcd7fe78a 100644 (file)
@@ -19,6 +19,7 @@ log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n
 #packages\r
 log4j.logger.org.collectionspace=DEBUG\r
 log4j.logger.org.collectionspace.services.authorization.spring=INFO\r
+# log4j.logger.org.collectionspace.services.common.authorization_mgt.AuthorizationStore=TRACE\r
 log4j.logger.org.apache=INFO\r
 log4j.logger.httpclient=INFO\r
 log4j.logger.org.jboss.resteasy=INFO\r
@@ -29,3 +30,4 @@ log4j.logger.org.springframework=INFO
 log4j.logger.ch.elca.el4j.services.xmlmerge=INFO\r
 log4j.logger.com.sun.xml.bind.v2.runtime=DEBUG\r
 log4j.logger.javax.persistence.PersistenceException=TRACE\r
+\r
index 8518a92db0c8033831f8da903ff8b8c2eafa4809..81324bc135c2589e9630dc9e0952adf1a2104dd8 100644 (file)
@@ -320,16 +320,41 @@ public class SpringPermissionManager implements CSpacePermissionManager {
             }
             acl = provider.getProviderAclService().createAcl(oid);
         }
-        acl.insertAce(acl.getEntries().size(), permission, sid, grant);
-        provider.getProviderAclService().updateAcl(acl);
+        // Need to see if there is already an entry, so we do not duplicate (e.g., 
+        // when we run our permission-roles init more than once.
+        List<AccessControlEntry> aceEntries = acl.getEntries();
+        if(aceListHasEntry(aceEntries, permission, sid, grant)) {
+            if (log.isDebugEnabled()) {
+                log.debug("addPermission: Pre-existing acl for oid=" + oid.toString()
+                        + " perm=" + permission.toString()
+                        + " sid=" + sid.toString()
+                        + " grant=" + grant);
+            }
+               
+        } else {
+            acl.insertAce(acl.getEntries().size(), permission, sid, grant);
+            provider.getProviderAclService().updateAcl(acl);
 
-        if (log.isDebugEnabled()) {
-            log.debug("addPermission: added acl for oid=" + oid.toString()
-                    + " perm=" + permission.toString()
-                    + " sid=" + sid.toString()
-                    + " grant=" + grant);
+            if (log.isDebugEnabled()) {
+                log.debug("addPermission: added acl for oid=" + oid.toString()
+                        + " perm=" + permission.toString()
+                        + " sid=" + sid.toString()
+                        + " grant=" + grant);
+            }
         }
     }
+    
+    private boolean aceListHasEntry(List<AccessControlEntry> aceEntries, Permission permission,
+            Sid sid, boolean grant) {
+       for(AccessControlEntry entry : aceEntries) {
+               if(permission.equals(entry.getPermission())
+                       && sid.equals(entry.getSid())
+                       && grant == entry.isGranting()) {
+                       return true;
+               }
+       }
+       return false;
+    }
 
     /**
      * deletePermissions deletes given permission on given object id for given sid
index 3ff03ee6db34aed43787e40b44ad0737756cf1e9..7aff76a86e1e1414d02ae0a193e8339620d77dc5 100644 (file)
@@ -32,6 +32,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 
 import org.collectionspace.services.authorization.Role;
+import org.collectionspace.services.authorization.PermissionRoleRel;
 import org.collectionspace.services.authorization.perms.Permission;
 import org.collectionspace.services.common.authorization_mgt.RoleStorageConstants;
 import org.collectionspace.services.common.document.JaxbUtils;
@@ -79,6 +80,25 @@ public class AuthorizationStore {
     }
     
     
+    static public PermissionRoleRel getPermRoleRel(EntityManager em, String permId, String roleId) {
+       PermissionRoleRel permRoleRel = null;
+       
+       try {
+               permRoleRel = (PermissionRoleRel)JpaStorageUtils.getEntityByDualKeys(em, 
+                               PermissionRoleRel.class.getName(),
+                               RoleStorageConstants.PERM_ROLE_REL_PERM_ID, permId, 
+                               RoleStorageConstants.PERM_ROLE_REL_ROLE_ID, roleId);
+       } catch (Throwable e) {
+               if (logger.isTraceEnabled()) {
+                       logger.trace("Could not retrieve permissionRoleRel with permId =" + permId 
+                                       +" and roleId="+roleId, e);
+               }
+       }
+       
+       return permRoleRel;
+    }
+    
+    
     static public Permission getPermission(Permission permission) {
        Permission result = null;
        //
@@ -138,10 +158,37 @@ public class AuthorizationStore {
        boolean result = false;
        
        try {
-               String csid = (String)JaxbUtils.getValue(entity, "getCsid");
-               Object existingEntity = em.find(entity.getClass(), csid);
-               if (existingEntity != null) {
-                       result = true;
+               if(entity instanceof Role) {
+                       // If find by name, exists
+                       Role roleEntity = (Role)entity;
+                       String roleName = roleEntity.getRoleName();
+                       String tenantId = roleEntity.getTenantId();
+                       if(getRoleByName(em, roleName, tenantId)!=null) {
+                               result = true;
+                       logger.trace("Role {} already exists in tenant {}.", roleName, tenantId);
+                       } else {
+                       logger.trace("Role {} does not exist in tenant {}.", roleName, tenantId);
+                       }
+               } else if(entity instanceof PermissionRoleRel) {
+                       // If find by name, exists
+                       PermissionRoleRel permRoleEntity = (PermissionRoleRel)entity;
+                       String roleId = permRoleEntity.getRoleId();
+                       String permId = permRoleEntity.getPermissionId();
+                       if(getPermRoleRel(em, permId, roleId)!=null) {
+                               result = true;
+                       logger.trace("PermRoleRel for {}, {} already exists.", permId, roleId);
+                       } else {
+                       logger.trace("PermRoleRel for {}, {} does not exist.", permId, roleId);
+                       }
+               } else {        // Default case; also best test for Permission
+                       String csid = (String)JaxbUtils.getValue(entity, "getCsid");
+                       Object existingEntity = em.find(entity.getClass(), csid);
+                       if (existingEntity != null) {
+                               result = true;
+                       logger.trace("Entity with csid {} already exists.", csid);
+                       } else {
+                       logger.trace("Entity with csid {} does not exist.", csid);
+                       }
                }
        } catch (Exception e) {
                //NOTE: Not all entities have a CSID attribute
@@ -154,15 +201,20 @@ public class AuthorizationStore {
      */
     public String store(EntityManager em, Object entity) throws Exception {
        boolean entityExists = exists(em, entity);
+       /* 
+        * Logging moved to exists, for better detail
        if (entityExists == true) {
-               logger.debug("Entity to persist already exists.");
+               logger.trace("Entity to persist already exists.");
        }
+        */
         if (JaxbUtils.getValue(entity, "getCreatedAt") == null) {
             JaxbUtils.setValue(entity, "setCreatedAtItem", Date.class, new Date());
         }
         
         if (entityExists == true) {
                //em.merge(entity); FIXME: Leave commented out until we address CSPACE-5031
+               // PLS: Question: why merge? what might be new to change, and is this really a good idea?
+               // Shouldn't we define them once and leave them alone?
         } else {
                em.persist(entity);
         }
index c8812ee337ddfcdcdb856e939015fa499b56cc27..7a1b47157efc4341e6fbb06b3d2d4d4d77e584d5 100644 (file)
@@ -34,4 +34,7 @@ public class RoleStorageConstants {
 
     final public static String ROLE_NAME = "roleName";
 
+    final public static String PERM_ROLE_REL_ROLE_ID = "roleId";
+    final public static String PERM_ROLE_REL_PERM_ID = "permissionId";
+
 }
index b15f910c76737c284782949c1ec298ee6a62ef00..7a737a35bb4c2f0edddae19e9de734a173e9cda0 100644 (file)
@@ -324,6 +324,46 @@ public class JpaStorageUtils {
         return result;
     }
     
+    public static Object getEntityByDualKeys(EntityManager em, String entityName, 
+               String key1, String value1,
+               String key2, String value2) {
+       return getEntityByDualKeys(em, entityName, key1, value1, key2, value2, null);
+    }
+    
+    public static Object getEntityByDualKeys(EntityManager em, String entityName, 
+               String key1, String value1,
+               String key2, String value2,
+            String tenantId) {
+       Object result = null;
+       
+        if (entityName == null) {
+            throw new IllegalArgumentException("entityName is required");
+        }
+        if (key1 == null || key2 == null) {
+            throw new IllegalArgumentException("key names are required");
+        }
+        
+        StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM ");
+        queryStrBldr.append(entityName);
+        queryStrBldr.append(" a");
+        queryStrBldr.append(" WHERE " + key1 + " = :" + key1);
+        queryStrBldr.append(" AND " + key2 + " = :" + key2);
+        boolean csAdmin = SecurityUtils.isCSpaceAdmin();
+        if (!csAdmin && tenantId != null) {
+            queryStrBldr.append(" AND tenantId = :tenantId");
+        }
+        String queryStr = queryStrBldr.toString(); //for debugging
+        Query q = em.createQuery(queryStr);
+        q.setParameter(key1, value1);
+        q.setParameter(key2, value2);
+        if (!csAdmin) {
+            q.setParameter("tenantId", tenantId);
+        }
+        result = q.getSingleResult();
+
+        return result;
+    }
+    
     public static Object getEnityByKey(String entityName, String key, String value,
             String tenantId) {
         EntityManagerFactory emf = null;