From a39a9b0e7ad6a44b4fab9db2d2a2224badd4062d Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 25 Sep 2012 16:14:02 +0000 Subject: [PATCH] Ensure backward compatibility of security model git-svn-id: https://svn.argeo.org/commons/trunk@5574 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../argeo/security/jcr/JcrSecurityModel.java | 10 +++- .../jackrabbit/JackrabbitSecurityModel.java | 35 ++++++++++++-- .../ldap/jcr/JcrLdapSynchronizer.java | 48 ++++--------------- .../org.argeo.node.repo.jackrabbit/pom.xml | 15 +++--- .../main/resources/org/argeo/jcr/argeo.cnd | 2 + 5 files changed, 59 insertions(+), 51 deletions(-) diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrSecurityModel.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrSecurityModel.java index a8ae4ab42..1ec6d280f 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrSecurityModel.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrSecurityModel.java @@ -25,7 +25,9 @@ public class JcrSecurityModel { private String homeBasePath = "/home"; /** - * To be called before user details are loaded + * To be called before user details are loaded. Make sure than any logged in + * user has a home directory with full access and a profile with information + * about him (read access) * * @return the user profile (whose parent is the user home) */ @@ -45,6 +47,12 @@ public class JcrSecurityModel { JcrUtils.clearAccessControList(session, homePath, username); JcrUtils.addPrivilege(session, homePath, username, Privilege.JCR_ALL); + } else { + // for backward compatibility with pre 1.0 security model + if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE)) { + userHome.getNode(ArgeoNames.ARGEO_PROFILE).remove(); + userHome.getSession().save(); + } } Node userProfile = UserJcrUtils.getUserProfile(session, username); diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/JackrabbitSecurityModel.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/JackrabbitSecurityModel.java index d6cd1b1b4..4d7dbc935 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/JackrabbitSecurityModel.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/JackrabbitSecurityModel.java @@ -4,30 +4,55 @@ import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; import org.argeo.ArgeoException; +import org.argeo.jcr.ArgeoNames; import org.argeo.security.jcr.JcrSecurityModel; /** Make sure that user authorizable exists before syncing user directories. */ public class JackrabbitSecurityModel extends JcrSecurityModel { + private final static Log log = LogFactory + .getLog(JackrabbitSecurityModel.class); @Override public Node sync(Session session, String username) { + User user = null; try { if (session instanceof JackrabbitSession) { UserManager userManager = ((JackrabbitSession) session) .getUserManager(); - User user = (User) userManager.getAuthorizable(username); - if (user == null) + user = (User) userManager.getAuthorizable(username); + if (user != null) { + String principalName = user.getPrincipal().getName(); + if (!principalName.equals(username)) { + log.warn("Jackrabbit principal is '" + principalName + + "' but username is '" + username + + "'. Recreating..."); + user.remove(); + user = userManager.createUser(username, ""); + } + } else { + // create new principal userManager.createUser(username, ""); + } } + Node userProfile = super.sync(session, username); + if (user != null && userProfile != null) { + Boolean enabled = userProfile.getProperty( + ArgeoNames.ARGEO_ENABLED).getBoolean(); + if (enabled && user.isDisabled()) + user.disable(null); + else if (!enabled && !user.isDisabled()) + user.disable(userProfile.getPath() + " is disabled"); + } + return userProfile; } catch (RepositoryException e) { throw new ArgeoException( - "Cannot perform Jackrabbit specific operaitons", e); + "Cannot perform Jackrabbit specific operations", e); } - return super.sync(session, username); } - } diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java index fa940f93d..669231bc9 100644 --- a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java +++ b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java @@ -185,7 +185,15 @@ public class JcrLdapSynchronizer implements UserDetailsContextMapper, List userPaths = (List) ldapTemplate.listBindings( userBaseName, new ContextMapper() { public Object mapFromContext(Object ctxObj) { - return mapLdapToJcr((DirContextAdapter) ctxObj); + try { + return mapLdapToJcr((DirContextAdapter) ctxObj); + } catch (Exception e) { + // do not break process because of error + log.error( + "Could not LDAP->JCR synchronize user " + + ctxObj, e); + return null; + } } }); @@ -230,7 +238,7 @@ public class JcrLdapSynchronizer implements UserDetailsContextMapper, // Node userProfile = SecurityJcrUtils.createUserProfileIfNeeded( // securitySession, username); Node userProfile = jcrSecurityModel.sync(nodeSession, username); - JcrUserDetails.checkAccountStatus(userProfile); + // JcrUserDetails.checkAccountStatus(userProfile); // password SortedSet passwordAttributes = ctx @@ -263,48 +271,12 @@ public class JcrLdapSynchronizer implements UserDetailsContextMapper, try { // process String username = ctx.getStringAttribute(usernameAttribute); - // Node userHome = SecurityJcrUtils.createUserHomeIfNeeded(session, - // username); - // Node userProfile; // = userHome.getNode(ARGEO_PROFILE); - // if (userHome.hasNode(ARGEO_PROFILE)) { - // userProfile = userHome.getNode(ARGEO_PROFILE); - // - // // compatibility with legacy, will be removed - // if (!userProfile.hasProperty(ARGEO_ENABLED)) { - // session.getWorkspace().getVersionManager() - // .checkout(userProfile.getPath()); - // userProfile.setProperty(ARGEO_ENABLED, true); - // userProfile.setProperty(ARGEO_ACCOUNT_NON_EXPIRED, true); - // userProfile.setProperty(ARGEO_ACCOUNT_NON_LOCKED, true); - // userProfile - // .setProperty(ARGEO_CREDENTIALS_NON_EXPIRED, true); - // session.save(); - // session.getWorkspace().getVersionManager() - // .checkin(userProfile.getPath()); - // } - // } else { - // userProfile = SecurityJcrUtils.createUserProfile( - // securitySession, username); - // userProfile.getSession().save(); - // userProfile.getSession().getWorkspace().getVersionManager() - // .checkin(userProfile.getPath()); - // } Node userProfile = jcrSecurityModel.sync(session, username); Map modifications = new HashMap(); for (String jcrProperty : propertyToAttributes.keySet()) ldapToJcr(userProfile, jcrProperty, ctx, modifications); - // assign default values - // if (!userProfile.hasProperty(Property.JCR_DESCRIPTION) - // && !modifications.containsKey(Property.JCR_DESCRIPTION)) - // modifications.put(Property.JCR_DESCRIPTION, ""); - // if (!userProfile.hasProperty(Property.JCR_TITLE)) - // modifications.put(Property.JCR_TITLE, - // userProfile.getProperty(ARGEO_FIRST_NAME).getString() - // + " " - // + userProfile.getProperty(ARGEO_LAST_NAME) - // .getString()); int modifCount = modifications.size(); if (modifCount > 0) { session.getWorkspace().getVersionManager() diff --git a/server/modules/org.argeo.node.repo.jackrabbit/pom.xml b/server/modules/org.argeo.node.repo.jackrabbit/pom.xml index 162bda216..168f2e500 100644 --- a/server/modules/org.argeo.node.repo.jackrabbit/pom.xml +++ b/server/modules/org.argeo.node.repo.jackrabbit/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 org.argeo.commons.server @@ -19,12 +20,12 @@ ${project.artifactId};singleton:=true *, - com.mysql.jdbc;version="[5.0.0,6.0.0)";resolution:=optional, - org.h2;version="[1.0.0,2.0.0)";resolution:=optional, - org.postgresql;version="[8.0.0,9.0.0)";resolution:=optional, - javax.jcr;version="[2.0.0,3.0.0)", - org.apache.jackrabbit.core;version="[2.0.0,3.0.0)", - org.apache.jackrabbit.core.config;version="[2.0.0,3.0.0)", + com.mysql.jdbc;resolution:=optional, + org.h2;resolution:=optional, + org.postgresql;resolution:=optional, + javax.jcr, + org.apache.jackrabbit.core, + org.apache.jackrabbit.core.config, org.argeo.jackrabbit, org.argeo.jcr, org.springframework.beans.factory.config, diff --git a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd index 1ae7a1e77..fbfea9dd9 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd +++ b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd @@ -21,6 +21,8 @@ mixin mixin - argeo:userID (STRING) m - argeo:remoteRoles (STRING) * +// deprecated. for backward compatibility: ++ argeo:profile (argeo:userProfile) + argeo:keyring (argeo:pbeSpec) + argeo:preferences (argeo:preferenceNode) -- 2.30.2