X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=security%2Fruntime%2Forg.argeo.security.ldap%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fldap%2Fjcr%2FJcrUserDetailsContextMapper.java;h=b6657f0c597998dc015290ac713d7e1e6651161e;hb=8b8ee149b20e2578a55e17413fa5f7399ff7ba14;hp=8cac6a7097a7f699ae3d585c7cbba87c2b9d586d;hpb=b3bb7ea3fb478885118726e75d08026cfa3c6e73;p=lgpl%2Fargeo-commons.git 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 8cac6a709..b6657f0c5 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 @@ -3,6 +3,7 @@ package org.argeo.security.ldap.jcr; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; +import java.util.Calendar; import java.util.HashMap; import java.util.Map; import java.util.Random; @@ -51,6 +52,9 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper, private PasswordEncoder passwordEncoder; private final Random random; + /** 0 is always sync */ + private Long syncLatency = 10 * 60 * 1000l; + public JcrUserDetailsContextMapper() { random = createRandom(); } @@ -108,13 +112,14 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper, } /** @return path to the user home node */ - protected synchronized String mapLdapToJcr(String username, DirContextOperations ctx) { + protected synchronized String mapLdapToJcr(String username, + DirContextOperations ctx) { String usernameLdap = ctx.getStringAttribute(usernameAttribute); // log.debug("username=" + username + ", usernameLdap=" + usernameLdap); if (!username.equals(usernameLdap)) { String msg = "Provided username '" + username + "' is different from username stored in LDAP '" - + usernameLdap+"'"; + + usernameLdap + "'"; // we log it because the exception may not be displayed log.error(msg); throw new BadCredentialsException(msg); @@ -123,13 +128,24 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper, try { Node userHome = JcrUtils.getUserHome(session, username); - if (userHome == null) + boolean justCreatedHome = false; + if (userHome == null) { userHome = JcrUtils.createUserHome(session, homeBasePath, username); + justCreatedHome = true; + } String userHomePath = userHome.getPath(); Node userProfile; // = userHome.getNode(ARGEO_PROFILE); if (userHome.hasNode(ARGEO_PROFILE)) { userProfile = userHome.getNode(ARGEO_PROFILE); + if (syncLatency != 0 && !justCreatedHome) { + Calendar lastModified = userProfile.getProperty( + Property.JCR_LAST_MODIFIED).getDate(); + long timeSinceLastUpdate = System.currentTimeMillis() + - lastModified.getTimeInMillis(); + if (timeSinceLastUpdate < syncLatency)// skip sync + return userHomePath; + } } else { throw new ArgeoException("We should never reach this point"); // userProfile = userHome.addNode(ARGEO_PROFILE); @@ -138,6 +154,8 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper, // userProfile.addMixin(NodeType.MIX_LAST_MODIFIED); } + session.getWorkspace().getVersionManager() + .checkout(userProfile.getPath()); for (String jcrProperty : propertyToAttributes.keySet()) ldapToJcr(userProfile, jcrProperty, ctx); @@ -149,8 +167,10 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper, .getProperty(ARGEO_FIRST_NAME).getString() + " " + userProfile.getProperty(ARGEO_LAST_NAME).getString()); - + JcrUtils.updateLastModified(userProfile); session.save(); + session.getWorkspace().getVersionManager() + .checkin(userProfile.getPath()); if (log.isTraceEnabled()) log.trace("Mapped " + ctx.getDn() + " to " + userProfile); return userHomePath; @@ -206,9 +226,16 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper, + jcrProperty); String value = ctx.getStringAttribute(ldapAttribute); - if (value == null) - return; - userProfile.setProperty(jcrProperty, value); + String jcrValue = userProfile.hasProperty(jcrProperty) ? userProfile + .getProperty(jcrProperty).getString() : null; + if (value != null && jcrValue != null) { + if (!value.equals(jcrValue)) + userProfile.setProperty(jcrProperty, value); + } else if (value != null && jcrValue == null) { + userProfile.setProperty(jcrProperty, value); + } else if (value == null && jcrValue != null) { + userProfile.setProperty(jcrProperty, value); + } } catch (Exception e) { throw new ArgeoException("Cannot map JCR property " + jcrProperty + " from LDAP", e); @@ -282,4 +309,11 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper, this.session = session; } + /** + * Time in ms during which the LDAP server is not checked. 0 is always sync. + */ + public void setSyncLatency(Long syncLatency) { + this.syncLatency = syncLatency; + } + }