]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
Make add privilege smarter
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr / src / main / java / org / argeo / jcr / JcrUtils.java
index 442e70d777577aa19403064f6f8b1780f7ad3696..5afebcee4811073514c498b064e525b0450ace5b 100644 (file)
@@ -286,6 +286,30 @@ public class JcrUtils implements ArgeoJcrConstants {
                return path.substring(index + 1);
        }
 
+       /**
+        * Call {@link Node#getName()} without exceptions (useful in super
+        * constructors).
+        */
+       public static String getNameQuietly(Node node) {
+               try {
+                       return node.getName();
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot get name from " + node, e);
+               }
+       }
+
+       /**
+        * Call {@link Node#getProperty(String)} without exceptions (useful in super
+        * constructors).
+        */
+       public static String getStringPropertyQuietly(Node node, String propertyName) {
+               try {
+                       return node.getProperty(propertyName).getString();
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot get name from " + node, e);
+               }
+       }
+
        /**
         * Routine that get the child with this name, adding id it does not already
         * exist
@@ -1205,7 +1229,7 @@ public class JcrUtils implements ArgeoJcrConstants {
         * Convenience method for adding a single privilege to a principal (user or
         * role), typically jcr:all
         */
-       public static void addPrivilege(Session session, String path,
+       public synchronized static void addPrivilege(Session session, String path,
                        String principal, String privilege) throws RepositoryException {
                List<Privilege> privileges = new ArrayList<Privilege>();
                privileges.add(session.getAccessControlManager().privilegeFromName(
@@ -1215,28 +1239,53 @@ public class JcrUtils implements ArgeoJcrConstants {
 
        /**
         * Add privileges on a path to a {@link Principal}. The path must already
-        * exist. Session is saved.
+        * exist. Session is saved. Synchronized to prevent concurrent modifications
+        * of the same node.
         */
-       public static void addPrivileges(Session session, String path,
-                       Principal principal, List<Privilege> privs)
+       public synchronized static Boolean addPrivileges(Session session,
+                       String path, Principal principal, List<Privilege> privs)
                        throws RepositoryException {
+               // make sure the session is in line with the persisted state
+               session.refresh(false);
                AccessControlManager acm = session.getAccessControlManager();
                AccessControlList acl = getAccessControlList(acm, path);
-               acl.addAccessControlEntry(principal,
-                               privs.toArray(new Privilege[privs.size()]));
+
+               accessControlEntries: for (AccessControlEntry ace : acl
+                               .getAccessControlEntries()) {
+                       Principal currentPrincipal = ace.getPrincipal();
+                       if (currentPrincipal.getName().equals(principal.getName())) {
+                               Privilege[] currentPrivileges = ace.getPrivileges();
+                               if (currentPrivileges.length != privs.size())
+                                       break accessControlEntries;
+                               for (int i = 0; i < currentPrivileges.length; i++) {
+                                       Privilege currP = currentPrivileges[i];
+                                       Privilege p = privs.get(i);
+                                       if (!currP.getName().equals(p.getName())) {
+                                               break accessControlEntries;
+                                       }
+                               }
+                               return false;
+                       }
+               }
+
+               Privilege[] privileges = privs.toArray(new Privilege[privs.size()]);
+               acl.addAccessControlEntry(principal, privileges);
                acm.setPolicy(path, acl);
                if (log.isDebugEnabled()) {
                        StringBuffer privBuf = new StringBuffer();
                        for (Privilege priv : privs)
                                privBuf.append(priv.getName());
-                       log.debug("Added privileges " + privBuf + " to " + principal
-                                       + " on " + path);
+                       log.debug("Added privileges " + privBuf + " to "
+                                       + principal.getName() + " on " + path + " in '"
+                                       + session.getWorkspace().getName() + "'");
                }
+               session.refresh(true);
                session.save();
+               return true;
        }
 
        /** Gets access control list for this path, throws exception if not found */
-       public static AccessControlList getAccessControlList(
+       public synchronized static AccessControlList getAccessControlList(
                        AccessControlManager acm, String path) throws RepositoryException {
                // search for an access control list
                AccessControlList acl = null;
@@ -1263,8 +1312,8 @@ public class JcrUtils implements ArgeoJcrConstants {
        }
 
        /** Clear authorizations for a user at this path */
-       public static void clearAccessControList(Session session, String path,
-                       String username) throws RepositoryException {
+       public synchronized static void clearAccessControList(Session session,
+                       String path, String username) throws RepositoryException {
                AccessControlManager acm = session.getAccessControlManager();
                AccessControlList acl = getAccessControlList(acm, path);
                for (AccessControlEntry ace : acl.getAccessControlEntries()) {