From: Mathieu Baudier Date: Wed, 23 Mar 2011 16:25:01 +0000 (+0000) Subject: Add authorizations to JCR X-Git-Tag: argeo-commons-2.1.30~1326 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=8b78007039ccb1f19d498742a64cf62435e8b093;p=lgpl%2Fargeo-commons.git Add authorizations to JCR git-svn-id: https://svn.argeo.org/commons/trunk@4343 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java b/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java index c25be6afb..716cb6d85 100644 --- a/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java +++ b/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java @@ -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(); } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java index 5fc482f90..4babb87a0 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java @@ -42,6 +42,9 @@ public interface UserAdminService { public void deleteUser(String username); + /** Synchronize with the underlying DAO. */ + public void synchronize(); + /* * ROLES */ diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java index e744dd0e7..e823124d7 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java @@ -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); diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/SecureThreadBoundSession.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/SecureThreadBoundSession.java index c83f3b594..aa3b15679 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/SecureThreadBoundSession.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/SecureThreadBoundSession.java @@ -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); diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoAccessManager.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoAccessManager.java index b29606318..bb1fe060e 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoAccessManager.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoAccessManager.java @@ -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); } } diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoLoginModule.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoLoginModule.java index 73ec76a8f..a83b6d56b 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoLoginModule.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoLoginModule.java @@ -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 adminPrincipals = subject - .getPrincipals(AdminPrincipal.class); - Set anonymousPrincipals = subject - .getPrincipals(AnonymousPrincipal.class); + clearPrincipals(AdminPrincipal.class); + clearPrincipals(AnonymousPrincipal.class); + clearPrincipals(GrantedAuthorityPrincipal.class); Set thisCredentials = subject .getPublicCredentials(SimpleCredentials.class); if (thisCredentials != null) thisCredentials.clear(); - if (adminPrincipals != null) - adminPrincipals.clear(); - if (anonymousPrincipals != null) - anonymousPrincipals.clear(); return true; } + private void clearPrincipals(Class clss) { + Set principals = subject.getPrincipals(clss); + if (principals != null) + principals.clear(); + } + @SuppressWarnings("rawtypes") @Override protected void doInit(CallbackHandler callbackHandler, Session session, diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java index 72479128c..6b58c6f69 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java @@ -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 userGroupIds = new ArrayList(); 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 = ""; + 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 { diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/GrantedAuthorityPrincipal.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/GrantedAuthorityPrincipal.java index ffd8d6f39..bf2eff60a 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/GrantedAuthorityPrincipal.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/GrantedAuthorityPrincipal.java @@ -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; diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java index 6b729a19b..3a39e6906 100644 --- a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java +++ b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java @@ -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 parameters) { - // this.repositoryFactory = repositoryFactory; - // } - // - // public void unregister(RepositoryFactory repositoryFactory, - // Map parameters) { - // this.repositoryFactory = null; - // } - public void setUsernameAttribute(String usernameAttribute) { this.usernameAttribute = usernameAttribute; } diff --git a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/editors.xml b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/editors.xml index 8ddc5bf62..6e88ffb3f 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/editors.xml +++ b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/editors.xml @@ -7,6 +7,5 @@ - diff --git a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/osgi.xml b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/osgi.xml index 487cebfdf..0e87da8c0 100644 --- a/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/osgi.xml +++ b/server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/osgi.xml @@ -8,9 +8,6 @@ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" osgi:default-timeout="30000"> - - 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 index 000000000..ee0312164 --- /dev/null +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java @@ -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
+ * value := group1,group2 + */ + private Map groupPrivileges = new HashMap(); + + 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 privs = new ArrayList(); + 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 groupPrivileges) { + this.groupPrivileges = groupPrivileges; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setSystemExecutor(Executor systemExecutor) { + this.systemExecutor = systemExecutor; + } + +} diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java index 48845a0d8..942313f8a 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java @@ -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) diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java index d05d8450a..1c33a43de 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java @@ -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();