Add authorizations to JCR
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 23 Mar 2011 16:25:01 +0000 (16:25 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 23 Mar 2011 16:25:01 +0000 (16:25 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4343 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

14 files changed:
security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/SecureThreadBoundSession.java
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoAccessManager.java
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoLoginModule.java
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/GrantedAuthorityPrincipal.java
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java
server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/editors.xml
server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/osgi.xml
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java [new file with mode: 0644]
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java

index c25be6afbdf46b845adc37c083065a3c2d095be5..716cb6d855afa8eb5a2486d2657b278daa4a6077 100644 (file)
@@ -53,6 +53,16 @@ public class SpringLoginModule extends SecurityContextLoginModule {
                if (SecurityContextHolder.getContext().getAuthentication() != null)
                        return super.login();
 
+               // reset all principals and credentials
+               if (log.isTraceEnabled())
+                       log.trace("Resetting all principals and credentials of " + subject);
+               if (subject.getPrincipals() != null)
+                       subject.getPrincipals().clear();
+               if (subject.getPrivateCredentials() != null)
+                       subject.getPrivateCredentials().clear();
+               if (subject.getPublicCredentials() != null)
+                       subject.getPublicCredentials().clear();
+
                // ask for username and password
                Callback label = new TextOutputCallback(TextOutputCallback.INFORMATION,
                                "Required login");
@@ -109,8 +119,8 @@ public class SpringLoginModule extends SecurityContextLoginModule {
 
        @Override
        public boolean logout() throws LoginException {
-//             if (log.isDebugEnabled())
-//                     log.debug("logout subject=" + subject);
+               // if (log.isDebugEnabled())
+               // log.debug("logout subject=" + subject);
                return super.logout();
        }
 
index 5fc482f903fdb4028c2698232b56f1a9124e61de..4babb87a03c7c40e687802412cc2956fa0402de6 100644 (file)
@@ -42,6 +42,9 @@ public interface UserAdminService {
 
        public void deleteUser(String username);
 
+       /** Synchronize with the underlying DAO. */
+       public void synchronize();
+
        /*
         * ROLES
         */
index e744dd0e73f0a70cb6b134b93c325e37ce104787..e823124d7c690bf387bdcf5ee6dc3ab1a00daa58 100644 (file)
@@ -57,6 +57,13 @@ public class DefaultUserAdminService implements UserAdminService {
 
                userAdminDao.createUser(user);
        }
+       
+       
+
+       public void synchronize() {
+               // TODO Auto-generated method stub
+               
+       }
 
        public ArgeoUser getUser(String username) {
                return userAdminDao.getUser(username);
index c83f3b5943d862b5b1d6a9f1481ec28aac95acb0..aa3b156795f0796b351cd06d8d4015c8ed364548 100644 (file)
@@ -7,6 +7,7 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.jcr.ThreadBoundJcrSessionFactory;
 import org.springframework.security.Authentication;
 import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.userdetails.UserDetails;
 
 public class SecureThreadBoundSession extends ThreadBoundJcrSessionFactory {
        private final static Log log = LogFactory
@@ -17,12 +18,17 @@ public class SecureThreadBoundSession extends ThreadBoundJcrSessionFactory {
                Authentication authentication = SecurityContextHolder.getContext()
                                .getAuthentication();
                if (authentication != null) {
-                       if (!session.getUserID().equals(
-                                       authentication.getPrincipal().toString())) {
-                               log.warn("Current session has user ID " + session.getUserID()
-                                               + " while authentication is " + authentication
-                                               + ". Re-login.");
-                               return login();
+                       String userID = session.getUserID();
+                       UserDetails userDetails = (UserDetails) authentication.getDetails();
+                       if (userDetails != null) {
+                               String currentUserName = userDetails.getUsername();
+                               if (!userID.equals(currentUserName)) {
+                                       log.warn("Current session has user ID " + userID
+                                                       + " while logged is user is " + currentUserName
+                                                       + "(authentication=" + authentication + ")"
+                                                       + ". Re-login.");
+                                       return login();
+                               }
                        }
                }
                return super.preCall(session);
index b29606318297750081356bb6f679e215262f6b48..bb1fe060e390c7a9f229d69117b51faa3b55a4d1 100644 (file)
@@ -1,16 +1,35 @@
 package org.argeo.security.jackrabbit;
 
+import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
+import javax.jcr.security.Privilege;
 
+import org.apache.jackrabbit.core.id.ItemId;
 import org.apache.jackrabbit.core.security.DefaultAccessManager;
+import org.apache.jackrabbit.spi.Path;
 
 /** Intermediary class in order to have a consistent naming in config files. */
 public class ArgeoAccessManager extends DefaultAccessManager {
 
        @Override
-       public boolean canAccess(String workspaceName) throws RepositoryException {
+       public boolean canRead(Path itemPath, ItemId itemId)
+                       throws RepositoryException {
                // TODO Auto-generated method stub
-               return super.canAccess(workspaceName);
+               return super.canRead(itemPath, itemId);
+       }
+
+       @Override
+       public Privilege[] getPrivileges(String absPath)
+                       throws PathNotFoundException, RepositoryException {
+               // TODO Auto-generated method stub
+               return super.getPrivileges(absPath);
+       }
+
+       @Override
+       public boolean hasPrivileges(String absPath, Privilege[] privileges)
+                       throws PathNotFoundException, RepositoryException {
+               // TODO Auto-generated method stub
+               return super.hasPrivileges(absPath, privileges);
        }
 
 }
index 73ec76a8f7c72b83c18a1de5b7390fa6a7b68bd9..a83b6d56b4e9a5708925d5d1ffec302b4dfec958 100644 (file)
@@ -50,6 +50,7 @@ public class ArgeoLoginModule extends AbstractLoginModule {
                        principals.add(new AnonymousPrincipal());
                else
                        for (GrantedAuthority ga : authen.getAuthorities()) {
+                               principals.add(new GrantedAuthorityPrincipal(ga));
                                // FIXME: make it more generic
                                if (adminRole.equals(ga.getAuthority()))
                                        principals.add(new AdminPrincipal(authen.getName()));
@@ -69,21 +70,22 @@ public class ArgeoLoginModule extends AbstractLoginModule {
         */
        @Override
        public boolean logout() throws LoginException {
-               Set<AdminPrincipal> adminPrincipals = subject
-                               .getPrincipals(AdminPrincipal.class);
-               Set<AnonymousPrincipal> anonymousPrincipals = subject
-                               .getPrincipals(AnonymousPrincipal.class);
+               clearPrincipals(AdminPrincipal.class);
+               clearPrincipals(AnonymousPrincipal.class);
+               clearPrincipals(GrantedAuthorityPrincipal.class);
                Set<SimpleCredentials> thisCredentials = subject
                                .getPublicCredentials(SimpleCredentials.class);
                if (thisCredentials != null)
                        thisCredentials.clear();
-               if (adminPrincipals != null)
-                       adminPrincipals.clear();
-               if (anonymousPrincipals != null)
-                       anonymousPrincipals.clear();
                return true;
        }
 
+       private <T extends Principal> void clearPrincipals(Class<T> clss) {
+               Set<T> principals = subject.getPrincipals(clss);
+               if (principals != null)
+                       principals.clear();
+       }
+
        @SuppressWarnings("rawtypes")
        @Override
        protected void doInit(CallbackHandler callbackHandler, Session session,
index 72479128c4daab4b4ebef81c397e611653f4df57..6b58c6f6903fcec70f7b0e5d8174d4f45be264e3 100644 (file)
@@ -6,8 +6,20 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.lock.LockException;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+import javax.jcr.version.VersionException;
 import javax.security.auth.Subject;
 
 import org.apache.commons.logging.Log;
@@ -20,6 +32,7 @@ import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.core.security.SystemPrincipal;
 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
 import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
 import org.springframework.security.Authentication;
 import org.springframework.security.GrantedAuthority;
 
@@ -54,18 +67,21 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                                        .toString(), authen, null);
                        log.info(userId + " added as " + user);
                }
+               
+               setHomeNodeAuthorizations(user);
 
+               // process groups
                List<String> userGroupIds = new ArrayList<String>();
                for (GrantedAuthority ga : authen.getAuthorities()) {
                        Group group = (Group) systemUm.getAuthorizable(ga.getAuthority());
                        if (group == null) {
-                               group = systemUm.createGroup(ga.getAuthority(),
-                                               new GrantedAuthorityPrincipal(ga), null);
+                               group = systemUm.createGroup(ga.getAuthority());
                                log.info(ga.getAuthority() + " added as " + group);
                        }
                        if (!group.isMember(user))
                                group.addMember(user);
                        userGroupIds.add(ga.getAuthority());
+
                }
 
                // check if user has not been removed from some groups
@@ -82,6 +98,42 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                return userId;
        }
 
+       protected void setHomeNodeAuthorizations(User user) {
+               // give all privileges on user home
+               // FIXME: fails on an empty repo
+               String userId = "<not yet set>";
+               try {
+                       userId = user.getID();
+                       Node userHome = JcrUtils.getUserHome(getSystemSession(), userId);
+                       if (userHome != null) {
+                               String path = userHome.getPath();
+                               AccessControlPolicy policy = null;
+                               AccessControlManager acm = getSystemSession()
+                                               .getAccessControlManager();
+                               AccessControlPolicyIterator policyIterator = acm
+                                               .getApplicablePolicies(path);
+                               if (policyIterator.hasNext()) {
+                                       policy = policyIterator.nextAccessControlPolicy();
+                               } else {
+                                       AccessControlPolicy[] existingPolicies = acm
+                                                       .getPolicies(path);
+                                       policy = existingPolicies[0];
+                               }
+                               if (policy instanceof AccessControlList) {
+                                       Privilege[] privileges = { acm
+                                                       .privilegeFromName(Privilege.JCR_ALL) };
+                                       ((AccessControlList) policy).addAccessControlEntry(
+                                                       user.getPrincipal(), privileges);
+                                       acm.setPolicy(path, policy);
+                               }
+                       }
+               } catch (Exception e) {
+                       log.warn("Cannot set authorization on user node for " + userId
+                                       + ": " + e.getMessage());
+               }
+
+       }
+
        @Override
        protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
                WorkspaceAccessManager wam = super
@@ -92,7 +144,8 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
        private class ArgeoWorkspaceAccessManagerImpl implements SecurityConstants,
                        WorkspaceAccessManager {
                private final WorkspaceAccessManager wam;
-               //private String defaultWorkspace;
+
+               // private String defaultWorkspace;
 
                public ArgeoWorkspaceAccessManagerImpl(WorkspaceAccessManager wam) {
                        super();
@@ -101,8 +154,8 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
 
                public void init(Session systemSession) throws RepositoryException {
                        wam.init(systemSession);
-//                     defaultWorkspace = ((RepositoryImpl) getRepository()).getConfig()
-//                                     .getDefaultWorkspaceName();
+                       // defaultWorkspace = ((RepositoryImpl) getRepository()).getConfig()
+                       // .getDefaultWorkspaceName();
                }
 
                public void close() throws RepositoryException {
index ffd8d6f3905369a79b7a139e753db5355881b297..bf2eff60a70adb3367e465b60b50d2d771d38a16 100644 (file)
@@ -4,7 +4,7 @@ import java.security.Principal;
 
 import org.springframework.security.GrantedAuthority;
 
-/** Wraps a {@link GrantedAuthority} as a prin,cipal. */
+/** Wraps a {@link GrantedAuthority} as a principal. */
 class GrantedAuthorityPrincipal implements Principal {
        private final GrantedAuthority grantedAuthority;
 
index 6b729a19b5db255bb7367becb139ef601c17df7e..3a39e690627712d3379d90b1c65638e05c2ec6e8 100644 (file)
@@ -9,6 +9,7 @@ import java.util.Random;
 import java.util.concurrent.Executor;
 
 import javax.jcr.Node;
+import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
@@ -63,8 +64,6 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
 
        public UserDetails mapUserFromContext(final DirContextOperations ctx,
                        final String username, GrantedAuthority[] authorities) {
-               // if (repository == null)
-               // throw new ArgeoException("No JCR repository registered");
                final StringBuffer userHomePathT = new StringBuffer("");
                Runnable action = new Runnable() {
                        public void run() {
@@ -98,11 +97,7 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
 
        /** @return path to the user home node */
        protected String mapLdapToJcr(String username, DirContextOperations ctx) {
-               // Session session = null;
                try {
-                       // Repository nodeRepo = JcrUtils.getRepositoryByAlias(
-                       // repositoryFactory, ArgeoJcrConstants.ALIAS_NODE);
-                       // session = nodeRepo.login();
                        Node userHome = JcrUtils.getUserHome(session, username);
                        if (userHome == null)
                                userHome = JcrUtils.createUserHome(session, homeBasePath,
@@ -117,17 +112,26 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
                                userProfile.addMixin(NodeType.MIX_CREATED);
                                userProfile.addMixin(NodeType.MIX_LAST_MODIFIED);
                        }
+
                        for (String jcrProperty : propertyToAttributes.keySet())
                                ldapToJcr(userProfile, jcrProperty, ctx);
+
+                       // assign default values
+                       if (!userProfile.hasProperty(Property.JCR_DESCRIPTION))
+                               userProfile.setProperty(Property.JCR_DESCRIPTION, "");
+                       if (!userProfile.hasProperty(Property.JCR_TITLE))
+                               userProfile.setProperty(Property.JCR_TITLE, userProfile
+                                               .getProperty(ARGEO_FIRST_NAME).getString()
+                                               + " "
+                                               + userProfile.getProperty(ARGEO_LAST_NAME).getString());
+
                        session.save();
-                       if (log.isDebugEnabled())
-                               log.debug("Mapped " + ctx.getDn() + " to " + userProfile);
+                       if (log.isTraceEnabled())
+                               log.trace("Mapped " + ctx.getDn() + " to " + userProfile);
                        return userHomePath;
                } catch (Exception e) {
                        JcrUtils.discardQuietly(session);
                        throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
-               } finally {
-                       // JcrUtils.logoutQuietly(session);
                }
        }
 
@@ -142,26 +146,17 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
                                encodePassword(user.getPassword()));
 
                final JcrUserDetails jcrUserDetails = (JcrUserDetails) user;
-               // systemExecutor.execute(new Runnable() {
-               // public void run() {
-               // Session session = null;
                try {
-                       // Repository nodeRepo = JcrUtils.getRepositoryByAlias(
-                       // repositoryFactory, ArgeoJcrConstants.ALIAS_NODE);
-                       // session = nodeRepo.login();
                        Node userProfile = session.getNode(jcrUserDetails.getHomePath()
                                        + '/' + ARGEO_PROFILE);
                        for (String jcrProperty : propertyToAttributes.keySet())
                                jcrToLdap(userProfile, jcrProperty, ctx);
-                       if (log.isDebugEnabled())
-                               log.debug("Mapped " + userProfile + " to " + ctx.getDn());
+
+                       if (log.isTraceEnabled())
+                               log.trace("Mapped " + userProfile + " to " + ctx.getDn());
                } catch (RepositoryException e) {
                        throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
-               } finally {
-                       // session.logout();
                }
-               // }
-               // });
        }
 
        protected String encodePassword(String password) {
@@ -198,10 +193,6 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
        protected void jcrToLdap(Node userProfile, String jcrProperty,
                        DirContextOperations ctx) {
                try {
-                       if (!userProfile.hasProperty(jcrProperty))
-                               return;
-                       String value = userProfile.getProperty(jcrProperty).getString();
-
                        String ldapAttribute;
                        if (propertyToAttributes.containsKey(jcrProperty))
                                ldapAttribute = propertyToAttributes.get(jcrProperty);
@@ -209,6 +200,18 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
                                throw new ArgeoException(
                                                "No LDAP attribute mapped for JCR proprty "
                                                                + jcrProperty);
+
+                       // fix issue with empty 'sn' in LDAP
+                       if (ldapAttribute.equals("sn")
+                                       && (!userProfile.hasProperty(jcrProperty) || userProfile
+                                                       .getProperty(jcrProperty).getString().trim()
+                                                       .equals("")))
+                               userProfile.setProperty(jcrProperty, "empty");
+
+                       if (!userProfile.hasProperty(jcrProperty))
+                               return;
+                       String value = userProfile.getProperty(jcrProperty).getString();
+
                        ctx.setAttributeValue(ldapAttribute, value);
                } catch (Exception e) {
                        throw new ArgeoException("Cannot map JCR property " + jcrProperty
@@ -228,16 +231,6 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
                this.homeBasePath = homeBasePath;
        }
 
-       // public void register(RepositoryFactory repositoryFactory,
-       // Map<String, String> parameters) {
-       // this.repositoryFactory = repositoryFactory;
-       // }
-       //
-       // public void unregister(RepositoryFactory repositoryFactory,
-       // Map<String, String> parameters) {
-       // this.repositoryFactory = null;
-       // }
-
        public void setUsernameAttribute(String usernameAttribute) {
                this.usernameAttribute = usernameAttribute;
        }
index 8ddc5bf62a761157ded685e27bf07bd0ec7d9cc1..6e88ffb3fc4397262c5c5a9c952bae7d6c8f38a0 100644 (file)
@@ -7,6 +7,5 @@
 
        <bean id="genericJcrQueryEditor"
                class="org.argeo.eclipse.ui.jcr.editors.GenericJcrQueryEditor" scope="prototype">
-               <property name="session" ref="jcrSession" />
        </bean>
 </beans>
index 487cebfdfe8102b9ad54785c2e5fe88e38c246e3..0e87da8c0f35ceff64f5156dc6dcce2a50fe4748 100644 (file)
@@ -8,9 +8,6 @@
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
        osgi:default-timeout="30000">\r
 \r
-       <reference id="nodeJcrSession" interface="javax.jcr.Session"\r
-               filter="(argeo.jcr.repository.alias=node)" />\r
-\r
        <set id="repositories" interface="javax.jcr.Repository">\r
                <listener ref="repositoryRegister" bind-method="register"\r
                        unbind-method="unregister" />\r
diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java
new file mode 100644 (file)
index 0000000..ee03121
--- /dev/null
@@ -0,0 +1,121 @@
+package org.argeo.jackrabbit;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+
+public class JackrabbitAuthorizations {
+       private final static Log log = LogFactory
+                       .getLog(JackrabbitAuthorizations.class);
+
+       private Repository repository;
+       private Executor systemExecutor;
+
+       /**
+        * key := privilege1,privilege2/path/to/node<br/>
+        * value := group1,group2
+        */
+       private Map<String, String> groupPrivileges = new HashMap<String, String>();
+
+       public void init() {
+               systemExecutor.execute(new Runnable() {
+                       public void run() {
+                               JackrabbitSession session = null;
+                               try {
+                                       session = (JackrabbitSession) repository.login();
+                                       initAuthorizations(session);
+                               } catch (Exception e) {
+                                       JcrUtils.discardQuietly(session);
+                               } finally {
+                                       JcrUtils.logoutQuietly(session);
+                               }
+                       }
+               });
+       }
+
+       protected void initAuthorizations(JackrabbitSession session)
+                       throws RepositoryException {
+               JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session
+                               .getAccessControlManager();
+               UserManager um = session.getUserManager();
+
+               for (String privileges : groupPrivileges.keySet()) {
+                       String path = null;
+                       int slashIndex = privileges.indexOf('/');
+                       if (slashIndex == 0) {
+                               throw new ArgeoException("Privilege " + privileges
+                                               + " badly formatted it starts with /");
+                       } else if (slashIndex > 0) {
+                               path = privileges.substring(slashIndex);
+                               privileges = privileges.substring(0, slashIndex);
+                       }
+
+                       if (path == null)
+                               path = "/";
+
+                       List<Privilege> privs = new ArrayList<Privilege>();
+                       for (String priv : privileges.split(",")) {
+                               privs.add(acm.privilegeFromName(priv));
+                       }
+
+                       String groupNames = groupPrivileges.get(privileges);
+                       for (String groupName : groupNames.split(",")) {
+                               Group group = (Group) um.getAuthorizable(groupName);
+                               if (group == null)
+                                       group = um.createGroup(groupName);
+
+                               AccessControlPolicy policy = null;
+                               AccessControlPolicyIterator policyIterator = acm
+                                               .getApplicablePolicies(path);
+                               if (policyIterator.hasNext()) {
+                                       policy = policyIterator.nextAccessControlPolicy();
+                               } else {
+                                       AccessControlPolicy[] existingPolicies = acm
+                                                       .getPolicies(path);
+                                       policy = existingPolicies[0];
+                               }
+                               if (policy instanceof AccessControlList) {
+                                       ((AccessControlList) policy).addAccessControlEntry(
+                                                       group.getPrincipal(),
+                                                       privs.toArray(new Privilege[privs.size()]));
+                                       acm.setPolicy(path, policy);
+                               }
+                               if (log.isDebugEnabled())
+                                       log.debug("Added privileges " + privileges + " to "
+                                                       + groupName + " on " + path);
+                       }
+               }
+               session.save();
+       }
+
+       public void setGroupPrivileges(Map<String, String> groupPrivileges) {
+               this.groupPrivileges = groupPrivileges;
+       }
+
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setSystemExecutor(Executor systemExecutor) {
+               this.systemExecutor = systemExecutor;
+       }
+
+}
index 48845a0d805308d605dceee175792f1570b3ff62..942313f8a5b68d3b0dba896629ddf3c248469dab 100644 (file)
@@ -192,7 +192,7 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                else
                        action.run();
        }
-
+       
        public void destroy() throws Exception {
                if (repository != null) {
                        if (repository instanceof JackrabbitRepository)
index d05d8450a4608f94c5f6e54f228aec1e3d0e2b63..1c33a43dec9a6788831fa92a2e8b83326645438c 100644 (file)
@@ -238,6 +238,7 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean,
                                threadSession = login();
                        }
 
+                       preCall(threadSession);
                        Object ret = method.invoke(threadSession, args);
                        if ("logout".equals(method.getName())) {
                                session.remove();