X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=security%2Fruntime%2Forg.argeo.security.jackrabbit%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fjackrabbit%2FArgeoSecurityManager.java;h=e5c0ed70bb7f093d3fb32000a5565f7a6da3010f;hb=014ba4ec8967e0af6c0315c2b0b9d9807df21b0d;hp=1838dd05ef14741cc768eeea81a9d8062b52cf8b;hpb=a8233e9378854fc9ed1f4186095d06866cbea9f8;p=lgpl%2Fargeo-commons.git 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 1838dd05e..e5c0ed70b 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 @@ -2,28 +2,31 @@ package org.argeo.security.jackrabbit; import java.security.Principal; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import javax.jcr.Node; +import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Session; -import javax.jcr.security.AccessControlList; -import javax.jcr.security.AccessControlManager; -import javax.jcr.security.AccessControlPolicy; -import javax.jcr.security.AccessControlPolicyIterator; +import javax.jcr.Value; +import javax.jcr.ValueFactory; import javax.jcr.security.Privilege; import javax.security.auth.Subject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy; import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.jackrabbit.core.DefaultSecurityManager; 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; @@ -34,13 +37,20 @@ import org.springframework.security.GrantedAuthority; public class ArgeoSecurityManager extends DefaultSecurityManager { private Log log = LogFactory.getLog(ArgeoSecurityManager.class); + /** + * Since this is called once when the session is created, we take the + * opportunity to make sure that Jackrabbit users and groups reflect Spring + * Security name and authorities. + */ @Override - /** Since this is called once when the session is created, we take the opportunity to synchronize Spring and Jackrabbit users and groups.*/ public String getUserID(Subject subject, String workspaceName) throws RepositoryException { long begin = System.currentTimeMillis(); - if (!subject.getPrincipals(SystemPrincipal.class).isEmpty()) + if (log.isTraceEnabled()) + log.trace(subject); + // skip Jackrabbit system user + if (!subject.getPrincipals(ArgeoSystemPrincipal.class).isEmpty()) return super.getUserID(subject, workspaceName); Authentication authen; @@ -59,10 +69,11 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { if (user == null) { user = systemUm.createUser(userId, authen.getCredentials() .toString(), authen, null); + JcrUtils.createUserHomeIfNeeded(getSystemSession(), userId); + getSystemSession().save(); + setSecurityHomeAuthorizations(user); log.info(userId + " added as " + user); } - - setHomeNodeAuthorizations(user); // process groups List userGroupIds = new ArrayList(); @@ -75,7 +86,6 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { if (!group.isMember(user)) group.addMember(user); userGroupIds.add(ga.getAuthority()); - } // check if user has not been removed from some groups @@ -85,45 +95,52 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { group.removeMember(user); } - if (log.isTraceEnabled()) - log.trace("Spring and Jackrabbit Security synchronized for user " + if (log.isDebugEnabled()) + log.debug("Spring and Jackrabbit Security synchronized for user " + userId + " in " + (System.currentTimeMillis() - begin) + " ms"); return userId; } - protected void setHomeNodeAuthorizations(User user) { - // give all privileges on user home - // FIXME: fails on an empty repo + protected synchronized void setSecurityHomeAuthorizations(User user) { + // give read privileges on user security home 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); - } + if (userHome == null) + throw new ArgeoException("No security home available for user " + + userId); + + String path = userHome.getPath(); + Principal principal = user.getPrincipal(); + + JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) getSystemSession() + .getAccessControlManager(); + JackrabbitAccessControlPolicy[] ps = acm + .getApplicablePolicies(principal); + if (ps.length == 0) { + // log.warn("No ACL found for " + user); + return; } + + JackrabbitAccessControlList list = (JackrabbitAccessControlList) ps[0]; + + // add entry + Privilege[] privileges = new Privilege[] { acm + .privilegeFromName(Privilege.JCR_READ) }; + Map restrictions = new HashMap(); + ValueFactory vf = getSystemSession().getValueFactory(); + restrictions.put("rep:nodePath", + vf.createValue(path, PropertyType.PATH)); + restrictions.put("rep:glob", vf.createValue("*")); + list.addEntry(principal, privileges, true /* allow or deny */, + restrictions); } catch (Exception e) { - log.warn("Cannot set authorization on user node for " + userId - + ": " + e.getMessage()); + e.printStackTrace(); + throw new ArgeoException( + "Cannot set authorization on security home for " + userId + + ": " + e.getMessage()); } }