You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by jm...@apache.org on 2022/10/03 15:59:27 UTC

svn commit: r1904380 - in /manifoldcf/trunk/connectors/ldapmapper: ./ connector/src/main/java/org/apache/manifoldcf/authorities/mappers/ldap/ connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/ connector/src/main/resources/o...

Author: jmssiera
Date: Mon Oct  3 15:59:27 2022
New Revision: 1904380

URL: http://svn.apache.org/viewvc?rev=1904380&view=rev
Log:
Fix CONNECTORS-1736

Added:
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/configuration.css   (with props)
Modified:
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/java/org/apache/manifoldcf/authorities/mappers/ldap/LDAPMapper.java
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_en_US.properties
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_es_ES.properties
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_fr_FR.properties
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_ja_JP.properties
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_zh_CN.properties
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/editConfiguration_LDAP.html
    manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/viewConfiguration.html
    manifoldcf/trunk/connectors/ldapmapper/pom.xml

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/java/org/apache/manifoldcf/authorities/mappers/ldap/LDAPMapper.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/java/org/apache/manifoldcf/authorities/mappers/ldap/LDAPMapper.java?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/java/org/apache/manifoldcf/authorities/mappers/ldap/LDAPMapper.java (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/java/org/apache/manifoldcf/authorities/mappers/ldap/LDAPMapper.java Mon Oct  3 15:59:27 2022
@@ -18,35 +18,57 @@
 */
 package org.apache.manifoldcf.authorities.mappers.ldap;
 
-import org.apache.manifoldcf.core.interfaces.*;
-import org.apache.manifoldcf.agents.interfaces.*;
-import org.apache.manifoldcf.authorities.interfaces.*;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.naming.AuthenticationException;
+import javax.naming.CommunicationException;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.StartTlsRequest;
+import javax.naming.ldap.StartTlsResponse;
+
 import org.apache.manifoldcf.authorities.system.Logging;
-import org.apache.manifoldcf.authorities.system.ManifoldCF;
-import org.apache.manifoldcf.connectorcommon.interfaces.*;
-import javax.naming.*;
-import javax.naming.directory.*;
-import javax.naming.ldap.*;
-import org.apache.manifoldcf.ui.util.Encoder;
+import org.apache.manifoldcf.connectorcommon.interfaces.IKeystoreManager;
+import org.apache.manifoldcf.connectorcommon.interfaces.KeystoreManagerFactory;
 import org.apache.manifoldcf.core.common.LDAPSSLSocketFactory;
+import org.apache.manifoldcf.core.interfaces.ConfigNode;
+import org.apache.manifoldcf.core.interfaces.ConfigParams;
+import org.apache.manifoldcf.core.interfaces.IDFactory;
+import org.apache.manifoldcf.core.interfaces.IHTTPOutput;
+import org.apache.manifoldcf.core.interfaces.IPostParameters;
+import org.apache.manifoldcf.core.interfaces.IThreadContext;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
 
-
-import java.io.*;
-import java.util.*;
-
-/** This is the ldap mapper implementation, which uses a ldap association to manipulate a user name.
-*/
-public class LDAPMapper extends org.apache.manifoldcf.authorities.mappers.BaseMappingConnector
-{
+/**
+ * This is the ldap mapper implementation, which uses a ldap association to manipulate a user name.
+ */
+public class LDAPMapper extends org.apache.manifoldcf.authorities.mappers.BaseMappingConnector {
   public static final String _rcsid = "@(#)$Id$";
 
   // Match map for username
   private LdapContext session = null;
   private StartTlsResponse tls = null;
-  
+
   private long sessionExpirationTime = -1L;
 
-  //private ConfigParams parameters;
+  // private ConfigParams parameters;
 
   private String bindUser;
   private String bindPass;
@@ -56,24 +78,57 @@ public class LDAPMapper extends org.apac
   private String serverBase;
   private String userBase;
   private String userSearch;
-  private String userNameReplace;
+  private String ldapUserNameReplace;
+  private String ldapAttributeCondition;
+  private String ldapAttributeRegexpCondition;
+  private Pattern ldapAttributeRegexpConditionPattern;
+  private String ldapUserNameReplaceTrue;
   private List<String> forcedTokens;
   private String userNameAttr;
   private String sslKeystoreData;
-  
+
   private IKeystoreManager sslKeystore;
-  
-  private long responseLifetime = 60000L; //60sec
 
-  private int LRUsize = 1000;
+  private final long responseLifetime = 60000L; // 60sec
 
+  private final int LRUsize = 1000;
 
-  /** Constructor.
-  */
-  public LDAPMapper()
-  {
+  /**
+   * Constructor.
+   */
+  public LDAPMapper() {
   }
-/**
+
+  @Override
+  public String check() throws ManifoldCFException {
+    disconnectSession();
+    getSession();
+    // MHL for a real check of all the search etc.
+    return super.check();
+  }
+
+  /**
+   * This method is called to assess whether to count this connector instance should actually be counted as being connected.
+   *
+   * @return true if the connector instance is actually connected.
+   */
+  @Override
+  public boolean isConnected() {
+    return session != null;
+  }
+
+  /**
+   * Poll. The connection should be closed if it has been idle for too long.
+   */
+  @Override
+  public void poll() throws ManifoldCFException {
+    if (session != null && System.currentTimeMillis() > sessionExpirationTime) {
+      disconnectSession();
+    }
+    super.poll();
+  }
+
+  /**
    * Disconnect a session.
    */
   protected void disconnectSession() {
@@ -82,9 +137,9 @@ public class LDAPMapper extends org.apac
         if (tls != null)
           tls.close();
         session.close();
-      } catch (NamingException e) {
+      } catch (final NamingException e) {
         // Eat this error
-      } catch (IOException e) {
+      } catch (final IOException e) {
         // Eat this error
       }
       tls = null;
@@ -92,11 +147,12 @@ public class LDAPMapper extends org.apac
       sessionExpirationTime = -1L;
     }
   }
-  /** Close the connection.  Call this before discarding the mapping connection.
-  */
+
+  /**
+   * Close the connection. Call this before discarding the mapping connection.
+   */
   @Override
-  public void disconnect()
-    throws ManifoldCFException {
+  public void disconnect() throws ManifoldCFException {
     disconnectSession();
     super.disconnect();
     // Zero out all the stuff that we want to be sure we don't use again
@@ -106,47 +162,53 @@ public class LDAPMapper extends org.apac
     userBase = null;
     userSearch = null;
     userNameAttr = null;
-    userNameReplace = null;
+    ldapUserNameReplace = null;
+    ldapAttributeCondition = null;
+    ldapAttributeRegexpCondition = null;
+    ldapAttributeRegexpConditionPattern = null;
+    ldapUserNameReplaceTrue = null;
     forcedTokens = null;
     sslKeystoreData = null;
     sslKeystore = null;
   }
-   /**
+
+  /**
    * Retrieves LDAPProtocol from serverProtocol String
    *
    * @return LDAPProtocolEnum
    */
   private LDAPProtocolEnum retrieveLDAPProtocol() {
     if (serverProtocol == null || serverProtocol.length() == 0) {
-      return  LDAPProtocolEnum.LDAP;
+      return LDAPProtocolEnum.LDAP;
     }
 
     final LDAPProtocolEnum ldapProtocol;
-    switch (serverProtocol.toUpperCase(Locale.ENGLISH)){
-      case "LDAP":
-        ldapProtocol = LDAPProtocolEnum.LDAP;
-        break;
-      case "LDAPS":
-        ldapProtocol = LDAPProtocolEnum.LDAPS;
-        break;
-      case "LDAP+TLS":
-        ldapProtocol = LDAPProtocolEnum.LDAP_TLS;
-        break;
-      case "LDAPS+TLS":
-        ldapProtocol = LDAPProtocolEnum.LDAPS_TLS;
-        break;
-      default:
-        ldapProtocol = LDAPProtocolEnum.LDAP;
+    switch (serverProtocol.toUpperCase(Locale.ENGLISH)) {
+    case "LDAP":
+      ldapProtocol = LDAPProtocolEnum.LDAP;
+      break;
+    case "LDAPS":
+      ldapProtocol = LDAPProtocolEnum.LDAPS;
+      break;
+    case "LDAP+TLS":
+      ldapProtocol = LDAPProtocolEnum.LDAP_TLS;
+      break;
+    case "LDAPS+TLS":
+      ldapProtocol = LDAPProtocolEnum.LDAPS_TLS;
+      break;
+    default:
+      ldapProtocol = LDAPProtocolEnum.LDAP;
     }
     return ldapProtocol;
   }
+
   /**
    * Checks whether TLS is enabled for given LDAP Protocol
    *
    * @param ldapProtocol to check
    * @return whether TLS is enabled or not
    */
-  private boolean isLDAPTLS (LDAPProtocolEnum ldapProtocol){
+  private boolean isLDAPTLS(final LDAPProtocolEnum ldapProtocol) {
     return LDAPProtocolEnum.LDAP_TLS.equals(ldapProtocol) || LDAPProtocolEnum.LDAPS_TLS.equals(ldapProtocol);
   }
 
@@ -156,30 +218,33 @@ public class LDAPMapper extends org.apac
    * @param ldapProtocol to check
    * @return whether LDAPS or LDAPS with TLS is enabled or not
    */
-  private boolean isLDAPS (LDAPProtocolEnum ldapProtocol){
+  private boolean isLDAPS(final LDAPProtocolEnum ldapProtocol) {
     return LDAPProtocolEnum.LDAPS.equals(ldapProtocol) || LDAPProtocolEnum.LDAPS_TLS.equals(ldapProtocol);
   }
-/**
+
+  /**
    * Stringifies LDAP Context environment variable
+   *
    * @param env LDAP Context environment variable
    * @return Stringified LDAP Context environment. Password is masked if set.
    */
-  private String printLdapContextEnvironment(Hashtable env) {
-    Hashtable copyEnv = new Hashtable<>(env);
-    if (copyEnv.containsKey(Context.SECURITY_CREDENTIALS)){
+  private String printLdapContextEnvironment(final Hashtable env) {
+    final Hashtable copyEnv = new Hashtable<>(env);
+    if (copyEnv.containsKey(Context.SECURITY_CREDENTIALS)) {
       copyEnv.put(Context.SECURITY_CREDENTIALS, "********");
     }
     return Arrays.toString(copyEnv.entrySet().toArray());
   }
-/**
+
+  /**
    * Connect. The configuration parameters are included.
    *
    * @param configParams are the configuration parameters for this connection.
    */
   @Override
-  public void connect(ConfigParams configParams) {
+  public void connect(final ConfigParams configParams) {
     super.connect(configParams);
-    //parameters = configParams;
+    // parameters = configParams;
 
     // Credentials
     bindUser = configParams.getParameter("ldapBindUser");
@@ -192,34 +257,40 @@ public class LDAPMapper extends org.apac
     serverBase = configParams.getParameter("ldapServerBase");
 
     sslKeystoreData = configParams.getParameter("sslKeystore");
-    
+
     userBase = configParams.getParameter("ldapUserBase");
     userSearch = configParams.getParameter("ldapUserSearch");
-  
+
     userNameAttr = configParams.getParameter("ldapUserNameAttr");
-    userNameReplace = configParams.getParameter("ldapUserNameReplace");
+    ldapAttributeCondition = configParams.getParameter("ldapAttributeCondition");
+    ldapAttributeRegexpCondition = configParams.getParameter("ldapAttributeRegexpCondition");
+
+    ldapUserNameReplaceTrue = configParams.getParameter("ldapUserNameReplaceTrue");
+    ldapUserNameReplace = configParams.getParameter("ldapUserNameReplace");
+    if (ldapAttributeCondition != null) {
+      ldapAttributeRegexpConditionPattern = Pattern.compile(ldapAttributeRegexpCondition);
+    }
 
     forcedTokens = new ArrayList<String>();
     int i = 0;
     while (i < configParams.getChildCount()) {
-      ConfigNode sn = configParams.getChild(i++);
+      final ConfigNode sn = configParams.getChild(i++);
       if (sn.getType().equals("access")) {
-        String token = "" + sn.getAttributeValue("token");
+        final String token = "" + sn.getAttributeValue("token");
         forcedTokens.add(token);
       }
     }
   }
-   // All methods below this line will ONLY be called if a connect() call succeeded
+
+  // All methods below this line will ONLY be called if a connect() call succeeded
   // on this instance!
   /**
-   * Session setup. Anything that might need to throw an exception should go
-   * here.
+   * Session setup. Anything that might need to throw an exception should go here.
    */
-  protected LdapContext getSession()
-    throws ManifoldCFException {
+  protected LdapContext getSession() throws ManifoldCFException {
 
     try {
-      LDAPProtocolEnum ldapProtocol = retrieveLDAPProtocol();
+      final LDAPProtocolEnum ldapProtocol = retrieveLDAPProtocol();
       if (session == null) {
         if (serverName == null || serverName.length() == 0) {
           Logging.mappingConnectors.error("Server name parameter missing but required");
@@ -241,7 +312,14 @@ public class LDAPMapper extends org.apac
           Logging.mappingConnectors.error("User search expression missing but required");
           throw new ManifoldCFException("User search expression missing but required");
         }
-        if (userNameReplace == null || userNameReplace.length() == 0) {
+        /*
+         * parameters not mandatory if (ldapAttributeCondition == null || ldapAttributeCondition.length() == 0) { Logging.mappingConnectors.error("User attribute condition missing but required");
+         * throw new ManifoldCFException("User attribute condition missing but required"); } if (ldapAttributeRegexpCondition == null || ldapAttributeRegexpCondition.length() == 0) {
+         * Logging.mappingConnectors.error("User attribute regexp condition missing but required"); throw new ManifoldCFException("User attribute regexp condition missing but required"); } if
+         * (ldapUserNameReplaceTrue == null || ldapUserNameReplaceTrue.length() == 0) { Logging.mappingConnectors.error("ldap attribute replace true missing but required"); throw new
+         * ManifoldCFException("ldap attribute replace if True missing but required"); }
+         */
+        if (ldapUserNameReplace == null || ldapUserNameReplace.length() == 0) {
           Logging.mappingConnectors.error("User name replace attribute missing but required");
           throw new ManifoldCFException("User name replace attribute missing but required");
         }
@@ -265,7 +343,7 @@ public class LDAPMapper extends org.apac
           env.put(Context.SECURITY_PROTOCOL, "ssl");
           env.put("java.naming.ldap.factory.socket", "org.apache.manifoldcf.core.common.LDAPSSLSocketFactory");
         }
-        
+
         if (bindUser != null && !bindUser.isEmpty()) {
           env.put(Context.SECURITY_AUTHENTICATION, "simple");
           env.put(Context.SECURITY_PRINCIPAL, bindUser);
@@ -274,13 +352,13 @@ public class LDAPMapper extends org.apac
 
         Logging.mappingConnectors.info("LDAP Context environment properties: " + printLdapContextEnvironment(env));
         session = new InitialLdapContext(env, null);
-        
+
         if (isLDAPTLS(ldapProtocol)) {
           // Start TLS
-          StartTlsResponse tls = (StartTlsResponse) session.extendedOperation(new StartTlsRequest());
+          final StartTlsResponse tls = (StartTlsResponse) session.extendedOperation(new StartTlsRequest());
           tls.negotiate(sslKeystore.getSecureSocketFactory());
         }
-        
+
       } else {
         if (isLDAPS(ldapProtocol)) {
           // Set thread local for keystore stuff
@@ -290,92 +368,96 @@ public class LDAPMapper extends org.apac
       }
       sessionExpirationTime = System.currentTimeMillis() + 300000L;
       return session;
-    } catch (AuthenticationException e) {
+    } catch (final AuthenticationException e) {
       session = null;
       sessionExpirationTime = -1L;
       Logging.mappingConnectors.error("Authentication error: " + e.getMessage() + ", explanation: " + e.getExplanation(), e);
       throw new ManifoldCFException("Authentication error: " + e.getMessage() + ", explanation: " + e.getExplanation(), e);
-    } catch (CommunicationException e) {
+    } catch (final CommunicationException e) {
       session = null;
       sessionExpirationTime = -1L;
       Logging.mappingConnectors.error("Communication error: " + e.getMessage(), e);
       throw new ManifoldCFException("Communication error: " + e.getMessage(), e);
-    } catch (NamingException e) {
+    } catch (final NamingException e) {
       session = null;
       sessionExpirationTime = -1L;
       Logging.mappingConnectors.error("Naming exception: " + e.getMessage(), e);
       throw new ManifoldCFException("Naming exception: " + e.getMessage(), e);
-    } catch (InterruptedIOException e) {
+    } catch (final InterruptedIOException e) {
       session = null;
       sessionExpirationTime = -1L;
       Logging.mappingConnectors.error("Interrupted IO error: " + e.getMessage());
       throw new ManifoldCFException(e.getMessage(), ManifoldCFException.INTERRUPTED);
-    } catch (IOException e) {
+    } catch (final IOException e) {
       session = null;
       sessionExpirationTime = -1L;
       Logging.mappingConnectors.error("IO error: " + e.getMessage(), e);
       throw new ManifoldCFException("IO error: " + e.getMessage(), e);
     }
-  }  
- 
+  }
+
   /**
    * Obtain the user LDAP record for a given user logon name.
    *
-   * @param ctx is the ldap context to use.
-   * @param userName (Domain Logon Name) is the user name or identifier.
-   * DC=qa-ad-76,DC=metacarta,DC=com)
-   * @return SearchResult for given domain user logon name. (Should throws an
-   * exception if user is not found.)
-   */
-  protected SearchResult getUserEntry(LdapContext ctx, String userName)
-    throws ManifoldCFException {
-    String searchFilter = userSearch.replaceAll("\\{0\\}", escapeDN(userName));
-    SearchControls searchCtls = new SearchControls();
+   * @param ctx      is the ldap context to use.
+   * @param userName (Domain Logon Name) is the user name or identifier. DC=qa-ad-76,DC=metacarta,DC=com)
+   * @return SearchResult for given domain user logon name. (Should throws an exception if user is not found.)
+   */
+  protected SearchResult getUserEntry(final LdapContext ctx, final String userName) throws ManifoldCFException {
+    final String searchFilter = userSearch.replaceAll("\\{0\\}", escapeDN(userName));
+    final SearchControls searchCtls = new SearchControls();
     searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
-    String[] attrIds = {userNameAttr, userNameReplace};
+    final String[] attrIds = new String[4];
+    attrIds[0] = userNameAttr;
+    attrIds[1] = ldapUserNameReplace;
+    if (ldapAttributeCondition != null && ldapAttributeCondition.length() > 0) {
+      attrIds[2] = ldapAttributeCondition;
+      attrIds[3] = ldapUserNameReplaceTrue;
+    }
     searchCtls.setReturningAttributes(attrIds);
 
     try {
-      NamingEnumeration answer = ctx.search(userBase, searchFilter, searchCtls);
+      final NamingEnumeration answer = ctx.search(userBase, searchFilter, searchCtls);
       if (answer.hasMoreElements()) {
         return (SearchResult) answer.next();
       }
       return null;
-    } catch (Exception e) {
+    } catch (final Exception e) {
       throw new ManifoldCFException(e.getMessage(), e);
     }
   }
-  public static String escapeDN(String name) {
-    StringBuilder sb = new StringBuilder(); // If using JDK >= 1.5 consider using StringBuilder
+
+  public static String escapeDN(final String name) {
+    final StringBuilder sb = new StringBuilder(); // If using JDK >= 1.5 consider using StringBuilder
     if ((name.length() > 0) && ((name.charAt(0) == ' ') || (name.charAt(0) == '#'))) {
       sb.append('\\'); // add the leading backslash if needed
     }
     for (int i = 0; i < name.length(); i++) {
-      char curChar = name.charAt(i);
+      final char curChar = name.charAt(i);
       switch (curChar) {
-        case '\\':
-          sb.append("\\\\");
-          break;
-        case ',':
-          sb.append("\\,");
-          break;
-        case '+':
-          sb.append("\\+");
-          break;
-        case '"':
-          sb.append("\\\"");
-          break;
-        case '<':
-          sb.append("\\<");
-          break;
-        case '>':
-          sb.append("\\>");
-          break;
-        case ';':
-          sb.append("\\;");
-          break;
-        default:
-          sb.append(curChar);
+      case '\\':
+        sb.append("\\\\");
+        break;
+      case ',':
+        sb.append("\\,");
+        break;
+      case '+':
+        sb.append("\\+");
+        break;
+      case '"':
+        sb.append("\\\"");
+        break;
+      case '<':
+        sb.append("\\<");
+        break;
+      case '>':
+        sb.append("\\>");
+        break;
+      case ';':
+        sb.append("\\;");
+        break;
+      default:
+        sb.append(curChar);
       }
     }
     if ((name.length() > 1) && (name.charAt(name.length() - 1) == ' ')) {
@@ -384,76 +466,100 @@ public class LDAPMapper extends org.apac
     return sb.toString();
   }
 
-  /** Map an input user name to an output name.
-  *@param userName is the name to map
-  *@return the mapped user name
-  */
+  /**
+   * Map an input user name to an output name.
+   *
+   * @param userName is the name to map
+   * @return the mapped user name
+   */
   @Override
-  public String mapUser(String userName)
-    throws ManifoldCFException
-  {
-    LdapContext lcontext = getSession();
+  public String mapUser(final String userName) throws ManifoldCFException {
+    final LdapContext lcontext = getSession();
 
     try {
-      String searchFilter = userSearch.replaceAll("\\{0\\}", escapeDN(userName));
-      Logging.mappingConnectors.info("SearFilter="+searchFilter);
-
-      SearchResult answer = getUserEntry(lcontext, userName);
-      Logging.mappingConnectors.info("Found answer="+answer.toString());
-      if (Logging.mappingConnectors.isDebugEnabled())
-        Logging.mappingConnectors.debug("Found answer="+answer.toString());
-    
-      Attributes attrs = answer.getAttributes();
-      Attribute attr = attrs.get(userNameReplace);
-      
-      String outputUserName = (String)attr.get(0);
-      Logging.mappingConnectors.info("LDAPMapper: Input user name '"+userName+"'; output user name '"+outputUserName+"'");
-      
+      final String searchFilter = userSearch.replaceAll("\\{0\\}", escapeDN(userName));
       if (Logging.mappingConnectors.isDebugEnabled())
-        Logging.mappingConnectors.debug("LDAPMapper: Input user name '"+userName+"'; output user name '"+outputUserName+"'");
-      
-      return outputUserName;
-    }
-    catch(Exception e)
-    { 
-      throw new ManifoldCFException("replace error: " + e.getMessage(), e);
+        Logging.mappingConnectors.debug("SearchFilter=" + searchFilter);
+
+      final SearchResult answer = getUserEntry(lcontext, userName);
+
+      if (answer != null) {
+        if (Logging.mappingConnectors.isDebugEnabled())
+          Logging.mappingConnectors.debug("Found answer=" + answer.toString());
+        final Attributes attrs = answer.getAttributes();
+        String outputUserName = null;
+        Attribute attrReplace = null;
+        /* by default */
+        attrReplace = attrs.get(ldapUserNameReplace);
+
+        if (ldapAttributeCondition != null && ldapAttributeCondition.length() > 0) {
+          final Attribute attrCondition = attrs.get(ldapAttributeCondition);
+          if (attrCondition != null) {
+            final String valueCondition = (String) attrCondition.get(0);
+            final Matcher matcher = ldapAttributeRegexpConditionPattern.matcher(valueCondition);
+            if (matcher.find()) {
+              attrReplace = attrs.get(ldapUserNameReplaceTrue);
+              if (Logging.mappingConnectors.isDebugEnabled())
+                Logging.mappingConnectors.debug("LDAPMapper: condition matches");
+            } else {
+              if (Logging.mappingConnectors.isDebugEnabled())
+                Logging.mappingConnectors.debug("LDAPMapper: condition not matches");
+            }
+          }
+        }
+        outputUserName = (String) attrReplace.get(0);
+
+        if (Logging.mappingConnectors.isDebugEnabled())
+          Logging.mappingConnectors.debug("LDAPMapper: Input user name '" + userName + "'; output user name '" + outputUserName + "'");
+
+        return outputUserName;
+      } else {
+        if (Logging.mappingConnectors.isDebugEnabled())
+          Logging.mappingConnectors.debug("No Found answer for userName =" + userName);
+        return userName;
       }
+    } catch (final Exception e) {
+      Logging.mappingConnectors.error("replace error for user : '" + userName + "' error :" + e.getMessage());
+      throw new ManifoldCFException("replace error: " + e.getMessage(), e);
+    }
   }
 
   // UI support methods.
   //
   // These support methods are involved in setting up authority connection configuration information. The configuration methods cannot assume that the
-  // current authority object is connected.  That is why they receive a thread context argument.
-    
-  /** Output the configuration header section.
-  * This method is called in the head section of the connector's configuration page.  Its purpose is to add the required tabs to the list, and to output any
-  * javascript methods that might be needed by the configuration editing HTML.
-  * @param threadContext is the local thread context.
-  * @param out is the output to which any HTML should be sent.
-  * @param parameters are the configuration parameters, as they currently
-  * exist, for this connection being configured.
-  * @param tabsArray is an array of tab names. Add to this array any tab names
-  * that are specific to the connector.
-  */
-   @Override
-   public void outputConfigurationHeader(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters, List<String> tabsArray)
-     throws ManifoldCFException, IOException {
-     tabsArray.add(Messages.getString(locale, "LDAP.LDAPMapperTab"));
-     Logging.mappingConnectors.info("LDAP.LDAPMapperTab="+Messages.getString(locale, "LDAP.LDAPMapperTab"));
-     tabsArray.add(Messages.getString(locale, "LDAP.ForcedTokens"));
-     final Map<String,Object> paramMap = new HashMap<String,Object>();
-     fillInLDAPTab(paramMap, out, parameters);
-     fillInForcedTokensTab(paramMap, out, parameters);
-     Messages.outputResourceWithVelocity(out, locale, "editConfiguration.js", paramMap);    
-   }
+  // current authority object is connected. That is why they receive a thread context argument.
+
+  /**
+   * Output the configuration header section. This method is called in the head section of the connector's configuration page. Its purpose is to add the required tabs to the list, and to output any
+   * javascript methods that might be needed by the configuration editing HTML.
+   *
+   * @param threadContext is the local thread context.
+   * @param out           is the output to which any HTML should be sent.
+   * @param parameters    are the configuration parameters, as they currently exist, for this connection being configured.
+   * @param tabsArray     is an array of tab names. Add to this array any tab names that are specific to the connector.
+   */
+  @Override
+  public void outputConfigurationHeader(final IThreadContext threadContext, final IHTTPOutput out, final Locale locale, final ConfigParams parameters, final List<String> tabsArray)
+      throws ManifoldCFException, IOException {
+
+    tabsArray.add(Messages.getString(locale, "LDAP.LDAPMapperTab"));
+    Logging.mappingConnectors.info("LDAP.LDAPMapperTab=" + Messages.getString(locale, "LDAP.LDAPMapperTab"));
+    tabsArray.add(Messages.getString(locale, "LDAP.ForcedTokens"));
+    final Map<String, Object> paramMap = new HashMap<String, Object>();
+    fillInLDAPTab(paramMap, out, parameters);
+    fillInForcedTokensTab(paramMap, out, parameters);
+    Messages.outputResourceWithVelocity(out, locale, "editConfiguration.js", paramMap);
+    Messages.outputResourceWithVelocity(out, locale, "configuration.css", paramMap);
+
+  }
+
   private static String getParam(final ConfigParams parameters, final String name, final String def) {
-    String rval = parameters.getParameter(name);
+    final String rval = parameters.getParameter(name);
     return rval != null ? rval : def;
   }
 
   /** Fill in ForcedTokens tab */
-  protected static void fillInForcedTokensTab(Map<String,Object> velocityContext, IHTTPOutput out, ConfigParams parameters)
-  {
+  protected static void fillInForcedTokensTab(final Map<String, Object> velocityContext, final IHTTPOutput out, final ConfigParams parameters) {
     final List<String> forcedTokenList = new ArrayList<String>();
     for (int i = 0; i < parameters.getChildCount(); i++) {
       final ConfigNode sn = parameters.getChild(i);
@@ -463,21 +569,24 @@ public class LDAPMapper extends org.apac
     }
     velocityContext.put("FORCEDTOKENS", forcedTokenList);
   }
+
   /** Fill in LDAP tab */
-  protected static void fillInLDAPTab(Map<String,Object> velocityContext, IHTTPOutput out, ConfigParams parameters)
-  {
+  protected static void fillInLDAPTab(final Map<String, Object> velocityContext, final IHTTPOutput out, final ConfigParams parameters) {
     velocityContext.put("FSERVERPROTOCOL", getParam(parameters, "ldapProtocol", "ldap"));
     velocityContext.put("FSERVERNAME", getParam(parameters, "ldapServerName", ""));
     velocityContext.put("FSERVERPORT", getParam(parameters, "ldapServerPort", "389"));
     velocityContext.put("FSERVERBASE", getParam(parameters, "ldapServerBase", ""));
-    String sslKeystoreData = parameters.getParameter("sslkeystore");
+    final String sslKeystoreData = parameters.getParameter("sslkeystore");
     if (sslKeystoreData != null)
       velocityContext.put("SSLKEYSTOREDATA", sslKeystoreData);
     velocityContext.put("FUSERBASE", getParam(parameters, "ldapUserBase", "ou=People"));
     velocityContext.put("FUSERSEARCH", getParam(parameters, "ldapUserSearch", "(&(objectClass=inetOrgPerson)(mail={0}))"));
     velocityContext.put("FUSERNAMEATTR", getParam(parameters, "ldapUserNameAttr", "mail"));
     velocityContext.put("FUSERNAMEREPLACE", getParam(parameters, "ldapUserNameReplace", "cn"));
-    
+    velocityContext.put("ATTRIBUTECONDITION", getParam(parameters, "ldapAttributeCondition", "displayName"));
+    velocityContext.put("ATTRIBUTEREGEXPCONDITION", getParam(parameters, "ldapAttributeRegexpCondition", "^a.*$"));
+    velocityContext.put("FUSERNAMETRUEREPLACE", getParam(parameters, "ldapUserNameReplaceTrue", "givenName"));
+
     velocityContext.put("FBINDUSER", getParam(parameters, "ldapBindUser", ""));
     String fBindPass = parameters.getObfuscatedParameter("ldapBindPass");
     if (fBindPass == null)
@@ -485,8 +594,8 @@ public class LDAPMapper extends org.apac
     else
       fBindPass = out.mapPasswordToKey(fBindPass);
     velocityContext.put("FBINDPASS", fBindPass);
-    
-    Map<String,String> sslCertificatesMap = null;
+
+    Map<String, String> sslCertificatesMap = null;
     String message = null;
 
     try {
@@ -494,85 +603,71 @@ public class LDAPMapper extends org.apac
       if (sslKeystoreData == null)
         localSslKeystore = KeystoreManagerFactory.make("");
       else
-        localSslKeystore = KeystoreManagerFactory.make("",sslKeystoreData);
+        localSslKeystore = KeystoreManagerFactory.make("", sslKeystoreData);
 
       // List the individual certificates in the store, with a delete button for each
       final String[] contents = localSslKeystore.getContents();
-      if (contents.length > 0)
-      {
+      if (contents.length > 0) {
         sslCertificatesMap = new HashMap<>();
-        for (final String alias : contents)
-        {
+        for (final String alias : contents) {
           String description = localSslKeystore.getDescription(alias);
           if (description.length() > 128)
-            description = description.substring(0,125) + "...";
+            description = description.substring(0, 125) + "...";
           sslCertificatesMap.put(alias, description);
         }
       }
-    } catch (ManifoldCFException e) {
+    } catch (final ManifoldCFException e) {
       message = e.getMessage();
       Logging.mappingConnectors.warn(e);
     }
 
-    if(sslCertificatesMap != null)
+    if (sslCertificatesMap != null)
       velocityContext.put("SSLCERTIFICATESMAP", sslCertificatesMap);
-    if(message != null)
+    if (message != null)
       velocityContext.put("MESSAGE", message);
   }
+
   /**
-   * Output the configuration body section. This method is called in the body
-   * section of the authority connector's configuration page. Its purpose is to
-   * present the required form elements for editing. The coder can presume that
-   * the HTML that is output from this configuration will be within appropriate
-   * &lt;html&gt;, &lt;body&gt;, and &lt;form&gt; tags. The name of the form is "editconnection".
+   * Output the configuration body section. This method is called in the body section of the authority connector's configuration page. Its purpose is to present the required form elements for editing.
+   * The coder can presume that the HTML that is output from this configuration will be within appropriate &lt;html&gt;, &lt;body&gt;, and &lt;form&gt; tags. The name of the form is "editconnection".
    *
    * @param threadContext is the local thread context.
-   * @param out is the output to which any HTML should be sent.
-   * @param parameters are the configuration parameters, as they currently
-   * exist, for this connection being configured.
-   * @param tabName is the current tab name.
+   * @param out           is the output to which any HTML should be sent.
+   * @param parameters    are the configuration parameters, as they currently exist, for this connection being configured.
+   * @param tabName       is the current tab name.
    */
   @Override
-  public void outputConfigurationBody(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters, String tabName)
-    throws ManifoldCFException, IOException {
-    final Map<String,Object> paramMap = new HashMap<String,Object>();
-    paramMap.put("TabName",tabName);
+  public void outputConfigurationBody(final IThreadContext threadContext, final IHTTPOutput out, final Locale locale, final ConfigParams parameters, final String tabName)
+      throws ManifoldCFException, IOException {
+    final Map<String, Object> paramMap = new HashMap<String, Object>();
+    paramMap.put("TabName", tabName);
     fillInLDAPTab(paramMap, out, parameters);
     fillInForcedTokensTab(paramMap, out, parameters);
-    Messages.outputResourceWithVelocity(out, locale, "editConfiguration_LDAP.html", paramMap);    
-    Messages.outputResourceWithVelocity(out, locale, "editConfiguration_ForcedTokens.html", paramMap);    
-  
-    
+    Messages.outputResourceWithVelocity(out, locale, "editConfiguration_LDAP.html", paramMap);
+    Messages.outputResourceWithVelocity(out, locale, "editConfiguration_ForcedTokens.html", paramMap);
 
   }
-  private boolean copyParam(IPostParameters variableContext, ConfigParams parameters, String name) {
-    String val = variableContext.getParameter(name);
+
+  private boolean copyParam(final IPostParameters variableContext, final ConfigParams parameters, final String name) {
+    final String val = variableContext.getParameter(name);
     if (val == null) {
       return false;
     }
     parameters.setParameter(name, val);
     return true;
   }
-  
+
   /**
-   * Process a configuration post. This method is called at the start of the
-   * authority connector's configuration page, whenever there is a possibility
-   * that form data for a connection has been posted. Its purpose is to gather
-   * form information and modify the configuration parameters accordingly. The
-   * name of the posted form is "editconnection".
+   * Process a configuration post. This method is called at the start of the authority connector's configuration page, whenever there is a possibility that form data for a connection has been posted.
+   * Its purpose is to gather form information and modify the configuration parameters accordingly. The name of the posted form is "editconnection".
    *
-   * @param threadContext is the local thread context.
-   * @param variableContext is the set of variables available from the post,
-   * including binary file post information.
-   * @param parameters are the configuration parameters, as they currently
-   * exist, for this connection being configured.
-   * @return null if all is well, or a string error message if there is an error
-   * that should prevent saving of the connection (and cause a redirection to an
-   * error page).
+   * @param threadContext   is the local thread context.
+   * @param variableContext is the set of variables available from the post, including binary file post information.
+   * @param parameters      are the configuration parameters, as they currently exist, for this connection being configured.
+   * @return null if all is well, or a string error message if there is an error that should prevent saving of the connection (and cause a redirection to an error page).
    */
   @Override
-  public String processConfigurationPost(IThreadContext threadContext, IPostParameters variableContext, Locale locale, ConfigParams parameters)
-    throws ManifoldCFException {
+  public String processConfigurationPost(final IThreadContext threadContext, final IPostParameters variableContext, final Locale locale, final ConfigParams parameters) throws ManifoldCFException {
     copyParam(variableContext, parameters, "ldapProtocol");
     copyParam(variableContext, parameters, "ldapServerName");
     copyParam(variableContext, parameters, "ldapServerPort");
@@ -581,6 +676,9 @@ public class LDAPMapper extends org.apac
     copyParam(variableContext, parameters, "ldapUserSearch");
     copyParam(variableContext, parameters, "ldapUserNameAttr");
     copyParam(variableContext, parameters, "ldapUserNameReplace");
+    copyParam(variableContext, parameters, "ldapAttributeCondition");
+    copyParam(variableContext, parameters, "ldapAttributeRegexpCondition");
+    copyParam(variableContext, parameters, "ldapUserNameReplaceTrue");
 
     copyParam(variableContext, parameters, "ldapBindUser");
     final String bindPass = variableContext.getParameter("ldapBindPass");
@@ -593,7 +691,7 @@ public class LDAPMapper extends org.apac
       // Delete all tokens first
       int i = 0;
       while (i < parameters.getChildCount()) {
-        ConfigNode sn = parameters.getChild(i);
+        final ConfigNode sn = parameters.getChild(i);
         if (sn.getType().equals("access")) {
           parameters.removeChild(i);
         } else {
@@ -613,17 +711,17 @@ public class LDAPMapper extends org.apac
           continue;
         }
         // Get the stuff we need
-        String accessSpec = variableContext.getParameter("spectoken" + accessDescription);
-        ConfigNode node = new ConfigNode("access");
+        final String accessSpec = variableContext.getParameter("spectoken" + accessDescription);
+        final ConfigNode node = new ConfigNode("access");
         node.setAttribute("token", accessSpec);
         parameters.addChild(parameters.getChildCount(), node);
         i++;
       }
 
-      String op = variableContext.getParameter("accessop");
+      final String op = variableContext.getParameter("accessop");
       if (op != null && op.equals("Add")) {
-        String accessspec = variableContext.getParameter("spectoken");
-        ConfigNode node = new ConfigNode("access");
+        final String accessspec = variableContext.getParameter("spectoken");
+        final ConfigNode node = new ConfigNode("access");
         node.setAttribute("token", accessspec);
         parameters.addChild(parameters.getChildCount(), node);
       }
@@ -631,86 +729,65 @@ public class LDAPMapper extends org.apac
 
     String sslKeystoreValue = variableContext.getParameter("sslkeystoredata");
     final String sslConfigOp = variableContext.getParameter("sslconfigop");
-    if (sslConfigOp != null)
-    {
-      if (sslConfigOp.equals("Delete"))
-      {
+    if (sslConfigOp != null) {
+      if (sslConfigOp.equals("Delete")) {
         final String alias = variableContext.getParameter("sslkeystorealias");
         final IKeystoreManager mgr;
         if (sslKeystoreValue != null)
-          mgr = KeystoreManagerFactory.make("",sslKeystoreValue);
+          mgr = KeystoreManagerFactory.make("", sslKeystoreValue);
         else
           mgr = KeystoreManagerFactory.make("");
         mgr.remove(alias);
         sslKeystoreValue = mgr.getString();
-      }
-      else if (sslConfigOp.equals("Add"))
-      {
-        String alias = IDFactory.make(threadContext);
-        byte[] certificateValue = variableContext.getBinaryBytes("sslcertificate");
+      } else if (sslConfigOp.equals("Add")) {
+        final String alias = IDFactory.make(threadContext);
+        final byte[] certificateValue = variableContext.getBinaryBytes("sslcertificate");
         final IKeystoreManager mgr;
         if (sslKeystoreValue != null)
-          mgr = KeystoreManagerFactory.make("",sslKeystoreValue);
+          mgr = KeystoreManagerFactory.make("", sslKeystoreValue);
         else
           mgr = KeystoreManagerFactory.make("");
-        java.io.InputStream is = new java.io.ByteArrayInputStream(certificateValue);
+        final java.io.InputStream is = new java.io.ByteArrayInputStream(certificateValue);
         String certError = null;
-        try
-        {
-          mgr.importCertificate(alias,is);
-        }
-        catch (Throwable e)
-        {
+        try {
+          mgr.importCertificate(alias, is);
+        } catch (final Throwable e) {
           certError = e.getMessage();
-        }
-        finally
-        {
-          try
-          {
+        } finally {
+          try {
             is.close();
-          }
-          catch (IOException e)
-          {
+          } catch (final IOException e) {
             // Eat this exception
           }
         }
 
-        if (certError != null)
-        {
-          return "Illegal certificate: "+certError;
+        if (certError != null) {
+          return "Illegal certificate: " + certError;
         }
         sslKeystoreValue = mgr.getString();
       }
     }
     if (sslKeystoreValue != null)
-      parameters.setParameter("sslkeystore",sslKeystoreValue);
-    
+      parameters.setParameter("sslkeystore", sslKeystoreValue);
+
     return null;
   }
-  
+
   /**
-   * View configuration. This method is called in the body section of the
-   * authority connector's view configuration page. Its purpose is to present
-   * the connection information to the user. The coder can presume that the HTML
-   * that is output from this configuration will be within appropriate &lt;html&gt;
-   * and &lt;body&gt; tags.
+   * View configuration. This method is called in the body section of the authority connector's view configuration page. Its purpose is to present the connection information to the user. The coder can
+   * presume that the HTML that is output from this configuration will be within appropriate &lt;html&gt; and &lt;body&gt; tags.
    *
    * @param threadContext is the local thread context.
-   * @param out is the output to which any HTML should be sent.
-   * @param parameters are the configuration parameters, as they currently
-   * exist, for this connection being configured.
+   * @param out           is the output to which any HTML should be sent.
+   * @param parameters    are the configuration parameters, as they currently exist, for this connection being configured.
    */
   @Override
-  public void viewConfiguration(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters)
-    throws ManifoldCFException, IOException {
-    final Map<String,Object> paramMap = new HashMap<String,Object>();
+  public void viewConfiguration(final IThreadContext threadContext, final IHTTPOutput out, final Locale locale, final ConfigParams parameters) throws ManifoldCFException, IOException {
+    final Map<String, Object> paramMap = new HashMap<String, Object>();
     fillInLDAPTab(paramMap, out, parameters);
     fillInForcedTokensTab(paramMap, out, parameters);
-    Messages.outputResourceWithVelocity(out, locale, "viewConfiguration.html", paramMap);    
+    Messages.outputResourceWithVelocity(out, locale, "configuration.css", paramMap);
+    Messages.outputResourceWithVelocity(out, locale, "viewConfiguration.html", paramMap);
   }
 
-  
-
 }
-
-

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_en_US.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_en_US.properties?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_en_US.properties (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_en_US.properties Mon Oct  3 15:59:27 2022
@@ -32,6 +32,13 @@ LDAP.UserNameAttrColon=User name attribu
 LDAP.UserNameReplaceColon=User replace attribute:
 LDAP.GroupMemberDnColon=Member attribute is DN:
 
+LDAP.AttributeConditionColon=Attribute Condition (leave empty if no condition to have default value):
+LDAP.AttributeCondition=Attribute Condition
+LDAP.AttributeRegexpCondition=Attribute Regexp Condition
+LDAP.TRUE=True
+LDAP.FALSE=False
+LDAP.DEFAULT=False or Default *
+
 LDAP.ForcedTokens=Forced tokens
 LDAP.ForcedTokensColon=Forced tokens:
 LDAP.Add=Add

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_es_ES.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_es_ES.properties?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_es_ES.properties (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_es_ES.properties Mon Oct  3 15:59:27 2022
@@ -32,6 +32,13 @@ LDAP.UserNameAttrColon=User name attribu
 LDAP.UserNameReplaceColon=User replace attribute:
 LDAP.GroupMemberDnColon=Member attribute is DN:
 
+LDAP.AttributeConditionColon=Attribute Condition (leave empty if no condition to have default value):
+LDAP.AttributeCondition=Attribute Condition
+LDAP.AttributeRegexpCondition=Attribute Regexp Condition:
+LDAP.TRUE=True
+LDAP.FALSE=False
+LDAP.DEFAULT=False or Default *
+
 LDAP.ForcedTokens=Forced tokens
 LDAP.ForcedTokensColon=Forced tokens:
 LDAP.Add=Add

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_fr_FR.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_fr_FR.properties?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_fr_FR.properties (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_fr_FR.properties Mon Oct  3 15:59:27 2022
@@ -30,6 +30,13 @@ LDAP.UserNameAttrColon=Attribut nom d'ut
 LDAP.UserNameReplaceColon=Attribut de remplacement pour l'utilisateur:
 LDAP.GroupMemberDnColon=L'attribut membre (member attribute) est DN:
 
+LDAP.AttributeConditionColon=Attribut de condition (laisser vide si pas de condition pour utiliser la valeur par defaut):
+LDAP.AttributeCondition=Attribut de condition
+LDAP.AttributeRegexpCondition=Regexp pour l'attribut de condition
+LDAP.TRUE=vrai
+LDAP.FALSE=Faux
+LDAP.DEFAULT=Faux ou par defaut *
+
 LDAP.ForcedTokens=Jetons forcés
 LDAP.ForcedTokensColon=Jetons forcés:
 LDAP.Add=Ajouter

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_ja_JP.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_ja_JP.properties?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_ja_JP.properties (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_ja_JP.properties Mon Oct  3 15:59:27 2022
@@ -32,6 +32,13 @@ LDAP.UserNameAttrColon=User name attribu
 LDAP.UserNameReplaceColon=User replace attribute:
 LDAP.GroupMemberDnColon=Member attribute is DN:
 
+LDAP.AttributeConditionColon=Attribute Condition (leave empty if no condition to have default value):
+LDAP.AttributeCondition=Attribute Condition
+LDAP.AttributeRegexpCondition=Attribute Regexp Condition
+LDAP.TRUE=True
+LDAP.FALSE=False
+LDAP.DEFAULT=False or Default *
+
 LDAP.ForcedTokens=Forced tokens
 LDAP.ForcedTokensColon=Forced tokens:
 LDAP.Add=Add

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_zh_CN.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_zh_CN.properties?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_zh_CN.properties (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/mappers/ldap/common_zh_CN.properties Mon Oct  3 15:59:27 2022
@@ -32,6 +32,13 @@ LDAP.UserNameAttrColon=User name attribu
 LDAP.UserNameReplaceColon=User replace attribute:
 LDAP.GroupMemberDnColon=Member attribute is DN:
 
+LDAP.AttributeConditionColon=Attribute Condition (leave empty if no condition to have default value):
+LDAP.AttributeCondition=Attribute Condition
+LDAP.AttributeRegexpCondition=Attribute Regexp Condition
+LDAP.TRUE=True
+LDAP.FALSE=False
+LDAP.DEFAULT=False or Default *
+
 LDAP.ForcedTokens=Forced tokens
 LDAP.ForcedTokensColon=Forced tokens:
 LDAP.Add=Add

Added: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/configuration.css
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/configuration.css?rev=1904380&view=auto
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/configuration.css (added)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/configuration.css Mon Oct  3 15:59:27 2022
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<!--
+Copyright 2014 The Apache Software Foundation.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<style type=text/css>
+
+.mainTable
+{
+	border-spacing: 0px;
+	padding: 0px;
+	}
+.main11
+{
+	height: 50px;
+}
+.mainwidth
+{
+	width: 80px;
+	/* must be policedermess width*sqare(2)*/
+	
+}
+
+.table_condition_right
+{
+	
+	//background: #DEDEDE;
+	width: 100%;
+	height: 100%;
+	border-spacing: 0px;
+}
+.condition_right_bottom
+{
+	border-bottom: 5px solid black;
+	//background-color: #AA0000;
+	//height: 145px;
+	//width:50px;
+}
+.condition_right_right
+{
+	border-right: 5px solid black;
+	width:130px;
+	text-align:right;
+	//background-color: #FF0000;
+	//height: 100px;
+}
+.condition_right_empty
+{
+	height: 150px;
+	//width: 50px;
+	//background-color: #00AA00;
+}
+
+.treatment div
+{
+display: block;
+position: relative;
+background: #ABABAB;
+border: 2px solid black;
+}
+.policeConditionTrue {
+height: 50px;
+width: 150px;
+//position: inline;
+vertical-align: middle; /* vertical-milieu de la div */
+display: table-cell; /* div et sa cellule */
+color: #000000; /* couleur sur texte - date */
+font: bold 14px Arial;  
+text-align: center;
+
+margin: 0 auto; /* centre le conteneur */
+}
+
+.policeConditionFalseOrDefault {
+height: 50px;
+width: 150px;
+position: inline;
+vertical-align: middle; /* vertical-milieu de la div */
+display: table-cell; /* div et sa cellule */
+color: #000000; /* couleur sur texte - date */
+font: bold 14px Arial;  
+text-align: center;
+
+margin: 0 auto; /* centre le conteneur */
+}
+.div_condition {
+height: 260px;
+width: 260px;	
+display: block;
+position: relative;
+background: #ABABAB;
+border: 2px solid black;
+transform: rotate(45deg);
+-ms-transform: rotate(45deg); /* Internet Explorer */
+-moz-transform: rotate(45deg); /* Firefox */
+-webkit-transform: rotate(45deg); /* Safari et Chrome */
+-o-transform: rotate(45deg); /* Opera */
+}
+/*Contenu du dernier message*/
+.policeCondition {
+height: 250px;
+width: 250px;
+position: inline;
+vertical-align: middle; /* vertical-milieu de la div */
+display: table-cell; /* div et sa cellule */
+color: #FF0000; /* couleur sur texte - date */
+font: bold 14px Arial;  
+text-align: center;
+transform: rotate(-45deg); /* remise du texte horizontal */
+-ms-transform: rotate(-45deg); /* Internet Explorer */
+-o-transform: rotate(-45deg); /* Opera */
+-webkit-transform: rotate(-45deg); /* Safari et Chrome */
+margin: 0 auto; /* centre le conteneur */
+}
+.policeCondition a {
+color: #312516; /* couleur sur url */
+font: bold 13px papyrus;
+text-align: center;
+}
+.policeCondition a:hover {
+color: green;
+}
+
+</style>
\ No newline at end of file

Propchange: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/configuration.css
------------------------------------------------------------------------------
    svn:executable = *

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/editConfiguration_LDAP.html
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/editConfiguration_LDAP.html?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/editConfiguration_LDAP.html (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/editConfiguration_LDAP.html Mon Oct  3 15:59:27 2022
@@ -84,10 +84,74 @@
     <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.UserNameAttrColon'))</nobr></td>
     <td class="value"><input type="text" size="64" name="ldapUserNameAttr" value="$Encoder.attributeEscape($FUSERNAMEATTR)"/></td>
   </tr>
+  <tr><td class="separator" colspan="2"><hr/></td></tr>
+  <!-- condition here-->
   <tr>
-    <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.UserNameReplaceColon'))</nobr></td>
-    <td class="value"><input type="text" size="64" name="ldapUserNameReplace" value="$Encoder.attributeEscape($FUSERNAMEREPLACE)"/></td>
+    <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.AttributeConditionColon'))</nobr></td>
+    <td class="value">
+      <table class="mainTable">
+        <!-- line 1 -->
+        <tr>
+          <td class="main11" colspan="3">&nbsp;</td>
+        </tr>
+        <!-- line 2 -->
+        <tr>
+          <td class="mainwidth">&nbsp;</td>
+          <td>
+            <table class="table_condition_right">
+              <tr>
+                <td colspan="2" rowspan="2">
+                  <div class="div_condition">                   
+                    <div class="policeCondition">
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.AttributeCondition'))</nobr><br>
+                      <input type="text" size="25" name="ldapAttributeCondition" value="$Encoder.attributeEscape($ATTRIBUTECONDITION)"/><br>
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.AttributeRegexpCondition'))</nobr><br>
+                      <input type="text" size="25" name="ldapAttributeRegexpCondition" value="$Encoder.attributeEscape($ATTRIBUTEREGEXPCONDITION)"/>
+                    </div>                        
+                  </div>  
+                </td>
+                <td class="condition_right_bottom">&nbsp;</td>
+                <td class="condition_right_bottom">&nbsp;</td>
+                <td class="condition_right_empty">&nbsp;</td>
+              </tr>
+              <tr>
+                <td class="condition_right_empty">&nbsp;</td>
+                <td class="condition_right_right">&nbsp;</td>
+                <td class="condition_right_empty">&nbsp;</td>
+              </tr>
+                <td class="condition_right_right"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.TRUE'))</nobr></td>
+                <td class="condition_right_empty">&nbsp;</td>
+                <td class="condition_right_empty">&nbsp;</td>
+                <td class="condition_right_right"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.FALSE'))</nobr></td>
+                <td class="condition_right_empty">&nbsp;</td>
+              </tr>
+              <tr>
+                <td colspan="2">
+                  <div class="treatment">                    
+                    <div class="policeConditionTrue">
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.TRUE'))</nobr><br>
+                      <input type="text" name="ldapUserNameReplaceTrue" value="$Encoder.attributeEscape($FUSERNAMETRUEREPLACE)"/>
+                    </div>                       
+                  </div>
+                </td>
+                <td class="mainwidth">&nbsp;</td>
+                <td colspan="2">
+                  <div class="treatment">                    
+                    <div class="policeConditionFalseOrDefault">
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.DEFAULT'))</nobr><br>
+                      <input type="text" name="ldapUserNameReplace" value="$Encoder.attributeEscape($FUSERNAMEREPLACE)"/>
+                    </div>                        
+                  </div>
+                </td>
+              </tr>
+            </table>
+          </td>
+        </tr>
+      </table>
+    </td>
   </tr>
+  
+
   <tr><td class="separator" colspan="2"><hr/></td></tr>
   <tr>
     <td class="description">
@@ -137,5 +201,7 @@
 
 <input type="hidden" name="ldapUserNameAttr" value="$Encoder.attributeEscape($FUSERNAMEATTR)"/>
 <input type="hidden" name="ldapUserNameReplace" value="$Encoder.attributeEscape($FUSERNAMEREPLACE)"/>
-
+<input type="hidden" name="ldapUserNameReplaceTrue" value="$Encoder.attributeEscape($FUSERNAMETRUEREPLACE)"/>
+<input type="hidden" name="ldapAttributeCondition" value="$Encoder.attributeEscape($ATTRIBUTECONDITION)"/>
+<input type="hidden" name="ldapAttributeRegexpCondition" value="$Encoder.attributeEscape($ATTRIBUTEREGEXPCONDITION)"/>
 #end
\ No newline at end of file

Modified: manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/viewConfiguration.html
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/viewConfiguration.html?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/viewConfiguration.html (original)
+++ manifoldcf/trunk/connectors/ldapmapper/connector/src/main/resources/org/apache/manifoldcf/authorities/mappers/ldap/viewConfiguration.html Mon Oct  3 15:59:27 2022
@@ -49,11 +49,75 @@
     <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.UserNameAttrColon'))</nobr></td>
     <td class="value">$Encoder.bodyEscape($FUSERNAMEATTR)</td>
   </tr>
+  <tr><td class="separator" colspan="2"><hr/></td></tr>
+
+
+<!-- condition here-->
   <tr>
-    <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.UserNameReplaceColon'))</nobr></td>
-    <td class="value">$Encoder.bodyEscape($FUSERNAMEREPLACE)</td>
+    <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.AttributeConditionColon'))</nobr></td>
+    <td class="value">
+      <table class="mainTable">
+        <!-- line 1 -->
+        <tr>
+          <td class="main11" colspan="3">&nbsp;</td>
+        </tr>
+        <!-- line 2 -->
+        <tr>
+          <td class="mainwidth">&nbsp;</td>
+          <td>
+            <table class="table_condition_right">
+              <tr>
+                <td colspan="2" rowspan="2">
+                  <div class="div_condition">                    
+                    <div class="policeCondition">
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.AttributeCondition'))</nobr><br>
+                      $Encoder.bodyEscape($ATTRIBUTECONDITION)<br>
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.AttributeRegexpCondition'))</nobr><br>
+                      $Encoder.bodyEscape($ATTRIBUTEREGEXPCONDITION)
+                    </div>                       
+                  </div>  
+                </td>
+                <td class="condition_right_bottom">&nbsp;</td>
+                <td class="condition_right_bottom">&nbsp;</td>
+                <td class="condition_right_empty">&nbsp;</td>
+              </tr>
+              <tr>
+                <td class="condition_right_empty">&nbsp;</td>
+                <td class="condition_right_right">&nbsp;</td>
+                <td class="condition_right_empty">&nbsp;</td>
+              </tr>
+                <td class="condition_right_right"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.TRUE'))</nobr></td>
+                <td class="condition_right_empty">&nbsp;</td>
+                <td class="condition_right_empty">&nbsp;</td>
+                <td class="condition_right_right"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.FALSE'))</nobr></td>
+                <td class="condition_right_empty">&nbsp;</td>
+              </tr>
+              <tr>
+                <td colspan="2">
+                  <div class="treatment">                    
+                    <div class="policeConditionTrue">
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.TRUE'))</nobr><br>
+                      $Encoder.bodyEscape($FUSERNAMETRUEREPLACE)
+                    </div>                        
+                  </div>
+                </td>
+                <td class="mainwidth">&nbsp;</td>
+                <td colspan="2">
+                  <div class="treatment">                   
+                    <div class="policeConditionFalseOrDefault">
+                      <nobr>$Encoder.bodyEscape($ResourceBundle.getString('LDAP.DEFAULT'))</nobr><br>
+                      $Encoder.bodyEscape($FUSERNAMEREPLACE)
+                    </div>                        
+                  </div>
+                </td>
+              </tr>
+            </table>
+          </td>
+        </tr>
+      </table>
+    </td>
   </tr>
-  
+
   <tr><td class="separator" colspan="4"><hr/></td></tr>
 
   <tr>

Modified: manifoldcf/trunk/connectors/ldapmapper/pom.xml
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/ldapmapper/pom.xml?rev=1904380&r1=1904379&r2=1904380&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/ldapmapper/pom.xml (original)
+++ manifoldcf/trunk/connectors/ldapmapper/pom.xml Mon Oct  3 15:59:27 2022
@@ -59,6 +59,7 @@
         <includes>
           <include>**/*.html</include>
           <include>**/*.js</include>
+          <include>**/*.css</include>
         </includes>
       </resource>
     </resources>