Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfigTest.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfigTest.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfigTest.java	(révision 0)
@@ -0,0 +1,19 @@
+package com.xpn.xwiki.plugin.ldap;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for the {@link XWikiLDAPConfig} class.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPConfigTest extends TestCase
+{
+    /**
+     * Empty test just to avoid a warning to be thrown when launching the test
+     */
+    public void testEmpty()
+    {
+        // Do nothing
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfigTest.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnectionTest.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnectionTest.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnectionTest.java	(révision 0)
@@ -0,0 +1,123 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.plugin.ldap;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+
+import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;
+import org.apache.directory.server.unit.AbstractServerTest;
+
+/**
+ * Unit tests for the {@link XWikiLDAPConnection} class.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPConnectionTest extends AbstractServerTest
+{
+    private XWikiLDAPConnection connection = new XWikiLDAPConnection();
+
+    private static Set HMSLYDIA_MEMBERS = new HashSet();
+
+    static {
+        HMSLYDIA_MEMBERS.add("cn=Horatio Hornblower,ou=people,o=sevenSeas");
+        HMSLYDIA_MEMBERS.add("cn=William Bush,ou=people,o=sevenSeas");
+        HMSLYDIA_MEMBERS.add("cn=Thomas Quist,ou=people,o=sevenSeas");
+        HMSLYDIA_MEMBERS.add("cn=Moultrie Crystal,ou=people,o=sevenSeas");
+    }
+
+    /**
+     * Initialize the server.
+     */
+    public void setUp() throws Exception
+    {
+        // Add partition 'sevenSeas'
+        MutablePartitionConfiguration pcfg = new MutablePartitionConfiguration();
+        pcfg.setName("sevenSeas");
+        pcfg.setSuffix("o=sevenseas");
+
+        // Create some indices
+        Set indexedAttrs = new HashSet();
+        indexedAttrs.add("objectClass");
+        indexedAttrs.add("o");
+        pcfg.setIndexedAttributes(indexedAttrs);
+
+        // Create a first entry associated to the partition
+        Attributes attrs = new BasicAttributes(true);
+
+        // First, the objectClass attribute
+        Attribute attr = new BasicAttribute("objectClass");
+        attr.add("top");
+        attr.add("organization");
+        attrs.put(attr);
+
+        // The the 'Organization' attribute
+        attr = new BasicAttribute("o");
+        attr.add("sevenseas");
+        attrs.put(attr);
+
+        // Associate this entry to the partition
+        pcfg.setContextEntry(attrs);
+
+        // As we can create more than one partition, we must store
+        // each created partition in a Set before initialization
+        Set pcfgs = new HashSet();
+        pcfgs.add(pcfg);
+
+        configuration.setContextPartitionConfigurations(pcfgs);
+
+        // Create a working directory
+        File workingDirectory = new File("server-work");
+        configuration.setWorkingDirectory(workingDirectory);
+
+        // Now, let's call the upper class which is responsible for the
+        // partitions creation
+        super.setUp();
+
+        // Load a demo ldif file
+        importLdif(this.getClass().getResourceAsStream("XWikiLDAPConnectionTest.ldif"));
+    }
+
+    public void testOpenClose()
+    {
+        assertTrue("LDAP connection failed", connection.open("localhost", this.port,
+            "cn=Horatio Hornblower,ou=people,o=sevenSeas", "pass", null, false));
+
+        this.connection.close();
+    }
+
+    /**
+     * Shutdown the server.
+     */
+    public void tearDown() throws Exception
+    {
+        this.connection.close();
+
+        super.tearDown();
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnectionTest.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtilsTest.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtilsTest.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtilsTest.java	(révision 0)
@@ -0,0 +1,111 @@
+package com.xpn.xwiki.plugin.ldap;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+
+import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;
+import org.apache.directory.server.unit.AbstractServerTest;
+
+public class XWikiLDAPUtilsTest extends AbstractServerTest
+{
+    private XWikiLDAPConnection connection = new XWikiLDAPConnection();
+
+    private XWikiLDAPUtils ldapUtils = new XWikiLDAPUtils(connection);
+
+    private static Set HMSLYDIA_MEMBERS = new HashSet();
+
+    static {
+        HMSLYDIA_MEMBERS.add("cn=Horatio Hornblower,ou=people,o=sevenSeas");
+        HMSLYDIA_MEMBERS.add("cn=William Bush,ou=people,o=sevenSeas");
+        HMSLYDIA_MEMBERS.add("cn=Thomas Quist,ou=people,o=sevenSeas");
+        HMSLYDIA_MEMBERS.add("cn=Moultrie Crystal,ou=people,o=sevenSeas");
+    }
+
+    /**
+     * Initialize the server.
+     */
+    public void setUp() throws Exception
+    {
+        // Add partition 'sevenSeas'
+        MutablePartitionConfiguration pcfg = new MutablePartitionConfiguration();
+        pcfg.setName("sevenSeas");
+        pcfg.setSuffix("o=sevenseas");
+
+        // Create some indices
+        Set indexedAttrs = new HashSet();
+        indexedAttrs.add("objectClass");
+        indexedAttrs.add("o");
+        pcfg.setIndexedAttributes(indexedAttrs);
+
+        // Create a first entry associated to the partition
+        Attributes attrs = new BasicAttributes(true);
+
+        // First, the objectClass attribute
+        Attribute attr = new BasicAttribute("objectClass");
+        attr.add("top");
+        attr.add("organization");
+        attrs.put(attr);
+
+        // The the 'Organization' attribute
+        attr = new BasicAttribute("o");
+        attr.add("sevenseas");
+        attrs.put(attr);
+
+        // Associate this entry to the partition
+        pcfg.setContextEntry(attrs);
+
+        // As we can create more than one partition, we must store
+        // each created partition in a Set before initialization
+        Set pcfgs = new HashSet();
+        pcfgs.add(pcfg);
+
+        configuration.setContextPartitionConfigurations(pcfgs);
+
+        // Create a working directory
+        File workingDirectory = new File("server-work");
+        configuration.setWorkingDirectory(workingDirectory);
+
+        // Now, let's call the upper class which is responsible for the
+        // partitions creation
+        super.setUp();
+
+        // Load a demo ldif file
+        importLdif(this.getClass().getResourceAsStream("XWikiLDAPConnectionTest.ldif"));
+        
+        this.connection.open("localhost", this.port,
+            "cn=Horatio Hornblower,ou=people,o=sevenSeas", "pass", null, false);
+    }
+
+    public void testGetGroupMembers()
+    {
+        List subGroups = new ArrayList();
+        Map members = new HashMap();
+
+        assertTrue("Fail to get members", this.ldapUtils.getGroupMembers(
+            "cn=HMS Lydia,ou=crews,ou=groups,o=sevenSeas", "cn", members, subGroups));
+
+        assertFalse("No member was found", members.isEmpty());
+
+        assertTrue("Wrong members was found", HMSLYDIA_MEMBERS.equals(members.keySet()));
+    }
+
+    /**
+     * Shutdown the server.
+     */
+    public void tearDown() throws Exception
+    {
+        this.connection.close();
+
+        super.tearDown();
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtilsTest.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthenticaterTest.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthenticaterTest.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthenticaterTest.java	(révision 0)
@@ -0,0 +1,61 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.user.impl.LDAP;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for the {@link XWikiLDAPAuthServiceImpl} class.
+ * 
+ * @version $Id: $
+ */
+public class LDAPAuthenticaterTest extends TestCase
+{
+    /*protected void setUp()
+    {
+        XWikiLDAPAuthServiceImpl t = new XWikiLDAPAuthServiceImpl();
+        LDAPConnection lc = t.open("vpc-jag-cv", 0, "", "");
+
+        boolean login = t.verifyPWD(lc, "cn=AAmes,ou=People,o=MegaNova,c=US", "pass");
+        login = t.verifyPWD(lc, "cn=AAmes,ou=People,o=MegaNova,c=US", "fail");
+        t.closeLDAP(lc);
+        lc = t.open("dsmaster", 0, "", "");
+        login =
+            t.verifyPWD(lc, "cn=EAI,department=USER,department=INFORMATIK,department=1230,o=MP",
+                "eaieai");
+        Map members = new HashMap();
+        List subgroups = new ArrayList();
+        boolean isGroup =
+            t.getGroupMembers(lc,
+                "cn=IT-SWL,department=Adm,department=INFORMATIK,department=1230,o=MP", "cn",
+                members, subgroups);
+        t.closeLDAP(lc);
+    }*/
+
+    /**
+     * Empty test just to avoid a warning to be thrown when launching the test
+     */
+    public void testEmpty()
+    {
+        // Do nothing
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthenticaterTest.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/resources/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnectionTest.ldif
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/resources/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnectionTest.ldif	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/test/resources/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnectionTest.ldif	(révision 0)
@@ -0,0 +1,216 @@
+# Sample LDIF data for the ApacheDS v1.0 Basic User's Guide
+#
+# Some sailors and their ships
+# userpassword for all persons is "pass"
+#
+version: 1
+
+dn: ou=people,o=sevenSeas
+objectclass: organizationalUnit
+objectclass: top
+description: Contains entries which describe persons (seamen)
+ou: people
+
+dn: ou=groups,o=sevenSeas
+objectclass: organizationalUnit
+objectclass: top
+description: Contains entries which describe groups (crews, for instance)
+ou: groups
+
+dn: ou=crews,ou=groups,o=sevenSeas
+objectclass: organizationalUnit
+objectclass: top
+description: Contains entries which describe ship crews
+ou: crews
+
+dn: ou=ranks,ou=groups,o=sevenSeas
+objectclass: organizationalUnit
+objectclass: top
+description: Contains entries which describe naval ranks (e.g. captain)
+ou: ranks
+
+# HMS Lydia Crew
+# --------------
+
+dn: cn=Horatio Hornblower,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: Horatio Hornblower
+description: Capt. Horatio Hornblower, R.N
+givenname: Horatio
+sn: Hornblower
+uid: hhornblo
+mail: hhornblo@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=William Bush,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: William Bush
+description: Lt. William Bush
+givenname: William
+manager: cn=Horatio Hornblower,ou=people,o=sevenSeas
+sn: Bush
+uid: wbush
+mail: wbush@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=Thomas Quist,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: Thomas Quist
+description: Seaman Quist
+givenname: Thomas
+manager: cn=Horatio Hornblower,ou=people,o=sevenSeas
+sn: Quist
+uid: tquist
+mail: tquist@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=Moultrie Crystal,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: Moultrie Crystal
+description: Lt. Crystal
+givenname: Moultrie
+manager: cn=Horatio Hornblower,ou=people,o=sevenSeas
+sn: Crystal
+uid: mchrysta
+mail: mchrysta@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=HMS Lydia,ou=crews,ou=groups,o=sevenSeas
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: HMS Lydia
+uniquemember: cn=Horatio Hornblower,ou=people,o=sevenSeas
+uniquemember: cn=William Bush,ou=people,o=sevenSeas
+uniquemember: cn=Thomas Quist,ou=people,o=sevenSeas
+uniquemember: cn=Moultrie Crystal,ou=people,o=sevenSeas
+
+# HMS Victory Crew
+# ----------------
+
+dn: cn=Horatio Nelson,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: Horatio Nelson
+description: Lord Horatio Nelson
+givenname: Horatio
+sn: Nelson
+uid: hnelson
+mail: hnelson@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=Thomas Masterman Hardy,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: Thomas Masterman Hardy
+description: Sir Thomas Masterman Hardy
+givenname: Thomas
+manager: cn=Horatio Nelson,ou=people,o=sevenSeas
+sn: Hardy
+uid: thardy
+mail: thardy@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=Cornelius Buckley,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: Cornelius Buckley
+description: LM Cornelius Buckley
+givenname: Cornelius
+manager: cn=Horatio Nelson,ou=people,o=sevenSeas
+sn: Buckley
+uid: cbuckley
+mail: cbuckley@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=HMS Victory,ou=crews,ou=groups,o=sevenSeas
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: HMS Victory
+uniquemember: cn=Horatio Nelson,ou=people,o=sevenSeas
+uniquemember: cn=Thomas Masterman Hardy,ou=people,o=sevenSeas
+uniquemember: cn=Cornelius Buckley,ou=people,o=sevenSeas
+
+# HMS Bounty Crew
+# ---------------
+
+dn: cn=William Bligh,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: William Bligh
+description: Captain William Bligh
+givenname: William
+sn: Bligh
+uid: wbligh
+mail: wbligh@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=Fletcher Christian,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: Fletcher Christian
+description: Lieutenant Fletcher Christian
+givenname: Fletcher
+manager: cn=William Bligh,ou=people,o=sevenSeas
+sn: Christian
+uid: fchristi
+mail: fchristi@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=John Fryer,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: John Fryer
+description: Master John Fryer
+givenname: John
+manager: cn=William Bligh,ou=people,o=sevenSeas
+sn: Fryer
+uid: jfryer
+mail: jfryer@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=John Hallett,ou=people,o=sevenSeas
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: top
+cn: John Hallett
+description: Midshipman John Hallett
+givenname: John
+manager: cn=William Bligh,ou=people,o=sevenSeas
+sn: Hallett
+uid: jhallett
+mail: jhallett@royalnavy.mod.uk
+userpassword: {SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+
+dn: cn=HMS Bounty,ou=crews,ou=groups,o=sevenSeas
+objectclass: groupOfUniqueNames
+objectclass: top
+cn: HMS Bounty
+uniquemember: cn=William Bligh,ou=people,o=sevenSeas
+uniquemember: cn=Fletcher Christian,ou=people,o=sevenSeas
+uniquemember: cn=John Fryer,ou=people,o=sevenSeas
+uniquemember: cn=John Hallett,ou=people,o=sevenSeas
Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java	(révision 0)
@@ -0,0 +1,234 @@
+package com.xpn.xwiki.plugin.ldap;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.xpn.xwiki.XWikiContext;
+
+/**
+ * Access to LDAP configurations.
+ * 
+ * @version $Id: $
+ */
+public final class XWikiLDAPConfig
+{
+    /**
+     * LDAP properties names suffix in xwiki.cfg.
+     */
+    public static final String CFG_LDAP_SUFFIX = "ldap_";
+
+    /**
+     * LDAP port property name in xwiki.cfg.
+     */
+    public static final String CFG_LDAP_PORT = CFG_LDAP_SUFFIX + "port";
+
+    /**
+     * LDAP group mapping properties names suffix in xwiki.cfg.
+     */
+    public static final String CFG_LDAP_GROUPMAPPING_SUFFIX = CFG_LDAP_PORT + "group_mapping_";
+
+    /**
+     * LDAP properties names suffix in XWikiPreferences.
+     */
+    public static final String PROP_LDAP_SUFFIX = "xwiki.authentication.ldap.";
+
+    /**
+     * LDAP port property name in XWikiPreferences.
+     */
+    public static final String PROP_LDAP_PORT = "ldap_port";
+
+    /**
+     * Mapping fields separator.
+     */
+    public static final String USERMAPPING_SEP = ",";
+
+    /**
+     * Character user to link XWiki field name and LDAP field name in user mappings property.
+     */
+    public static final String USERMAPPING_XWIKI_LDAP_LINK = "=";
+
+    /**
+     * Logging tool.
+     */
+    private static final Log LOG = LogFactory.getLog(XWikiLDAPConfig.class);
+
+    /**
+     * Unique instance of {@link XWikiLDAPConfig}.
+     */
+    private static XWikiLDAPConfig instance;
+
+    /**
+     * Protected constructor. Use {@link #getInstance()}.
+     */
+    private XWikiLDAPConfig()
+    {
+
+    }
+
+    /**
+     * @return unique instance of {@link XWikiLDAPConfig}.
+     */
+    public static XWikiLDAPConfig getInstance()
+    {
+        if (instance == null) {
+            instance = new XWikiLDAPConfig();
+        }
+
+        return instance;
+    }
+
+    /**
+     * First try to retrieve value from XWiki Preferences and then from xwiki.cfg Syntax ldap_*name*
+     * (for XWiki Preferences) will be changed to ldap.*name* for xwiki.cfg.
+     * 
+     * @param name the name of the property.
+     * @param def default value.
+     * @param context the XWiki context.
+     * @return the value of the property.
+     */
+    public String getLDAPParam(String name, String def, XWikiContext context)
+    {
+        String param = def;
+
+        try {
+            param = context.getWiki().getXWikiPreference(name, context);
+        } catch (Exception e) {
+            // ignore
+        }
+
+        if (param == null || "".equals(param)) {
+            try {
+                param =
+                    context.getWiki().Param(
+                        StringUtils.replace(name, CFG_LDAP_SUFFIX, PROP_LDAP_SUFFIX));
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+
+        if (param == null) {
+            param = def;
+        }
+
+        return param;
+    }
+
+    /**
+     * Get LDAP port from configuration.
+     * 
+     * @param context the XWiki context.
+     * @return the LDAP port.
+     */
+    public int getLDAPPort(XWikiContext context)
+    {
+        int port;
+
+        try {
+            port = context.getWiki().getXWikiPreferenceAsInt(CFG_LDAP_PORT, context);
+        } catch (Exception e) {
+            port = (int) context.getWiki().ParamAsLong(PROP_LDAP_PORT, 0);
+        }
+
+        return port;
+    }
+
+    /**
+     * Get mapping between XWiki groups names and LDAP groups names.
+     * 
+     * @param context the XWiki context.
+     * @return the mapping between XWiki users and LDAP users.
+     */
+    public Map getGroupMappings(XWikiContext context)
+    {
+        Map groupMappings = new HashMap();
+
+        int pos = 1;
+        String grouplistmapping = getLDAPParam(CFG_LDAP_GROUPMAPPING_SUFFIX + pos, "", context);
+        while (grouplistmapping != null && grouplistmapping.length() > 0) {
+            int splitt = grouplistmapping.indexOf('=');
+
+            if (splitt < 1) {
+                LOG.error("Error parsing ldap_group_mapping attribute in xwiki.cfg: "
+                    + grouplistmapping);
+            } else {
+                String xwikigroup = grouplistmapping.substring(0, splitt);
+                String ldapgroup = grouplistmapping.substring(splitt + 1);
+
+                groupMappings.put(ldapgroup, xwikigroup);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Groupmapping found: " + xwikigroup + " " + ldapgroup);
+                }
+            }
+
+            ++pos;
+            grouplistmapping = getLDAPParam(CFG_LDAP_GROUPMAPPING_SUFFIX + pos, null, context);
+        }
+
+        return groupMappings;
+    }
+
+    /**
+     * Get mapping between XWiki users attributes and LDAP users attributes.
+     * 
+     * @param attrListToFill the list to fill with extracted LDAP fields to use in LDAP search.
+     * @param context the XWiki context.
+     * @return the mapping between XWiki groups and LDAP groups.
+     */
+    public Map getUserMappings(List attrListToFill, XWikiContext context)
+    {
+        Map userMappings = new HashMap();
+
+        String ldapFieldMapping = getLDAPParam("ldap_fields_mapping", null, context);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Ready to create user from LDAP with fields " + ldapFieldMapping);
+        }
+
+        if (ldapFieldMapping != null && ldapFieldMapping.length() > 0) {
+            String[] fields = ldapFieldMapping.split(USERMAPPING_SEP);
+
+            for (int j = 0; j < fields.length; j++) {
+                String[] field = fields[j].split(USERMAPPING_XWIKI_LDAP_LINK);
+                if (2 == field.length) {
+                    String xwikiattr = field[0].replace(" ", "");
+                    String ldapattr = field[1].replace(" ", "");
+
+                    userMappings.put(ldapattr, xwikiattr);
+
+                    attrListToFill.add(ldapattr);
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Found field mapping: " + xwikiattr
+                            + USERMAPPING_XWIKI_LDAP_LINK + ldapattr);
+                    }
+                } else {
+                    LOG.error("Error parsing ldap_fields_mapping attribute in xwiki.cfg: "
+                        + fields[j]);
+                }
+            }
+        }
+
+        return userMappings;
+    }
+    
+    /**
+     * @param context the XWiki context.
+     * @return the time in ms until a entry in the cache is to expire.
+     */
+    public int getCacheExpiration(XWikiContext context)
+    {
+        try {
+            return context.getWiki().getXWikiPreferenceAsInt("ldap_groupcache_expiration",
+                context);
+        } catch (Exception e) {
+            return (int) context.getWiki().ParamAsLong(
+                "xwiki.authentication.ldap.groupcache_expiration", 21800);
+        }
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConfig.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java	(révision 0)
@@ -0,0 +1,31 @@
+package com.xpn.xwiki.plugin.ldap;
+
+/**
+ * Represent an LDAP attribute.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPSearchAttribute
+{
+    /**
+     * Attribute name.
+     */
+    public String name;
+
+    /**
+     * Attribute value.
+     */
+    public String value;
+
+    /**
+     * Create attribute instance.
+     * 
+     * @param name attribute name.
+     * @param value attribute value.
+     */
+    public XWikiLDAPSearchAttribute(String name, String value)
+    {
+        this.name = name;
+        this.value = value;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPSearchAttribute.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java	(révision 0)
@@ -0,0 +1,273 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.plugin.ldap;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.novell.ldap.LDAPAttribute;
+import com.novell.ldap.LDAPAttributeSet;
+import com.novell.ldap.LDAPConnection;
+import com.novell.ldap.LDAPEntry;
+import com.novell.ldap.LDAPException;
+import com.novell.ldap.LDAPJSSESecureSocketFactory;
+import com.novell.ldap.LDAPSearchConstraints;
+import com.novell.ldap.LDAPSearchResults;
+import com.novell.ldap.LDAPSocketFactory;
+import com.xpn.xwiki.XWikiContext;
+
+import java.security.Security;
+
+/**
+ * LDAP communication tool.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPConnection
+{
+    /**
+     * Logging tool.
+     */
+    private static final Log LOG = LogFactory.getLog(XWikiLDAPConnection.class);
+
+    /**
+     * The LDAP connection.
+     */
+    private LDAPConnection connection;
+
+    /**
+     * Open a LDAP connection.
+     * 
+     * @param ldapUserName the user name to connect to LDAP server.
+     * @param password the password to connect to LDAP server.
+     * @param context the XWiki context.
+     * @return true if connection succeed, false otherwise.
+     */
+    public boolean open(String ldapUserName, String password, XWikiContext context)
+    {
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+
+        // open LDAP
+        int ldapPort = config.getLDAPPort(context);
+        String ldapHost = config.getLDAPParam("ldap_server", "127.0.0.1", context);
+        String bindDNFormat = config.getLDAPParam("ldap_bind_DN", "", context);
+        String bindPasswordFormat = config.getLDAPParam("ldap_bind_pass", "{1}", context);
+
+        Object[] arguments = {ldapUserName, password};
+
+        // allow to use the given user and password also as the LDAP bind user and password
+        String bindDN = String.format(bindDNFormat, arguments);
+        String bindPassword = String.format(bindPasswordFormat, arguments);
+
+        boolean bind;
+        if ("1".equals(config.getLDAPParam("ldap_ssl", "0", context))) {
+            String keyStore = config.getLDAPParam("ldap_ssl.keystore", "", context);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Connecting to LDAP using SSL");
+            }
+
+            bind = open(ldapHost, ldapPort, bindDN, bindPassword, keyStore, true);
+        } else {
+            bind = open(ldapHost, ldapPort, bindDN, bindPassword, null, false);
+        }
+
+        return bind;
+    }
+
+    /**
+     * Open LDAP connection.
+     * 
+     * @param ldapHost the host of the server to connect to.
+     * @param ldapPort the port of the server to connect to.
+     * @param loginDN the user DN to connect to LDAP server.
+     * @param password the password to connect to LDAP server.
+     * @param pathToKeys the patch to SSL keystore to use.
+     * @param ssl if true connect using SSL.
+     * @return true if the connection succeed, false otherwise.
+     */
+    public boolean open(String ldapHost, int ldapPort, String loginDN, String password,
+        String pathToKeys, boolean ssl)
+    {
+        boolean succeed = false;
+
+        int port = ldapPort;
+
+        if (port <= 0) {
+            port = ssl ? LDAPConnection.DEFAULT_SSL_PORT : LDAPConnection.DEFAULT_PORT;
+        }
+
+        int ldapVersion = LDAPConnection.LDAP_V3;
+
+        try {
+            if (ssl) {
+                // Dynamically set JSSE as a security provider
+                Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+
+                if (pathToKeys != null && pathToKeys.length() > 0) {
+                    // Dynamically set the property that JSSE uses to identify
+                    // the keystore that holds trusted root certificates
+
+                    System.setProperty("javax.net.ssl.trustStore", pathToKeys);
+                    // obviously unnecessary: sun default pwd = "changeit"
+                    // System.setProperty("javax.net.ssl.trustStorePassword", sslpwd);
+                }
+
+                LDAPSocketFactory ssf = new LDAPJSSESecureSocketFactory();
+
+                // Set the socket factory as the default for all future connections
+                // LDAPConnection.setSocketFactory(ssf);
+
+                // Note: the socket factory can also be passed in as a parameter
+                // to the constructor to set it for this connection only.
+                this.connection = new LDAPConnection(ssf);
+            } else {
+                this.connection = new LDAPConnection();
+            }
+
+            // connect to the server
+            this.connection.connect(ldapHost, port);
+
+            // authenticate to the server
+            this.connection.bind(ldapVersion, loginDN, password.getBytes("UTF8"));
+
+            if (!this.connection.isConnected() || !this.connection.isConnectionAlive()) {
+                LOG.error("Connection to LDAP failed.");
+
+                /*if (ssl) {
+                    LOG.error("Verify that the SSL certificate is found in the keystore.");
+                }*/
+            }
+
+            succeed = this.connection.isBound();
+        } catch (UnsupportedEncodingException e) {
+            LOG.error("LDAP bind failed with UnsupportedEncodingException.", e);
+        } catch (LDAPException e) {
+            LOG.error("LDAP bind failed with LDAPException.", e);
+        }
+
+        return succeed;
+    }
+
+    /**
+     * Close LDAP connection.
+     */
+    public void close()
+    {
+        try {
+            if (this.connection != null) {
+                this.connection.disconnect();
+            }
+        } catch (LDAPException e) {
+            LOG.debug("LDAP close failed.", e);
+        }
+    }
+
+    /**
+     * Check if provided password is correct provided users's password.
+     * 
+     * @param userDN the user.
+     * @param password the password.
+     * @return true if the password is valid, false otherwise.
+     */
+    public boolean checkPassword(String userDN, String password)
+    {
+        try {
+            LDAPAttribute attribute = new LDAPAttribute("userPassword", password);
+            return this.connection.compare(userDN, attribute);
+        } catch (LDAPException e) {
+            if (e.getResultCode() == LDAPException.NO_SUCH_OBJECT) {
+                LOG.error("Unable to locate user_dn:" + userDN, e);
+            } else if (e.getResultCode() == LDAPException.NO_SUCH_ATTRIBUTE) {
+                LOG.error("Unable to verify password because userPassword attribute not found.",
+                    e);
+            } else {
+                LOG.error("Unable to verify password", e);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Execute a LDAP search query.
+     * 
+     * @param baseDN the root DN where to search.
+     * @param query the LDAP query.
+     * @param attr the attributes names of values to return.
+     * @param ldapScope {@link LDAPConnection#SCOPE_SUB} oder {@link LDAPConnection#SCOPE_BASE}.
+     * @return the found LDAP attributes.
+     */
+    public List searchLDAP(String baseDN, String query, String[] attr, int ldapScope)
+    {
+        List searchAttributeList = new ArrayList();
+
+        try {
+            LDAPSearchConstraints cons = new LDAPSearchConstraints();
+            cons.setTimeLimit(1000);
+
+            // filter return all attributes return attrs and values time out value
+            LDAPSearchResults searchResults =
+                this.connection.search(baseDN, ldapScope, query, attr, false, cons);
+
+            if (!searchResults.hasMore()) {
+                return null;
+            }
+
+            LDAPEntry nextEntry = searchResults.next();
+            String foundDN = nextEntry.getDN();
+            searchAttributeList.add(new XWikiLDAPSearchAttribute("dn", foundDN));
+
+            LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
+
+            for (Iterator attributeIt = attributeSet.iterator(); attributeIt.hasNext();) {
+                LDAPAttribute attribute = (LDAPAttribute) attributeIt.next();
+                String attributeName = attribute.getName();
+
+                Enumeration allValues = attribute.getStringValues();
+
+                if (allValues != null) {
+                    while (allValues.hasMoreElements()) {
+
+                        String value = (String) allValues.nextElement();
+                        searchAttributeList
+                            .add(new XWikiLDAPSearchAttribute(attributeName, value));
+                    }
+                }
+            }
+        } catch (LDAPException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("LDAP Search failed", e);
+            }
+
+            searchAttributeList = null;
+        }
+
+        return searchAttributeList;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPConnection.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtils.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtils.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtils.java	(révision 0)
@@ -0,0 +1,226 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.plugin.ldap;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.novell.ldap.LDAPConnection;
+
+/**
+ * LDAP communication tool.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPUtils
+{
+    /**
+     * Logging tool.
+     */
+    private static final Log LOG = LogFactory.getLog(XWikiLDAPUtils.class);
+
+    /**
+     * Different LDAP implementations groups classes name.
+     */
+    private static final Set LDAP_GROUP_CLASS = new HashSet();
+
+    /**
+     * Different LDAP implementations groups member property name.
+     */
+    private static final Set LDAP_GROUP_MEMBER = new HashSet();
+
+    /**
+     * LDAP objectClass parameter.
+     */
+    private static final String LDAP_OBJECTCLASS = "objectClass";
+
+    /**
+     * The LDAP connection.
+     */
+    private XWikiLDAPConnection connection;
+
+    static {
+        LDAP_GROUP_CLASS.add("group".toLowerCase());
+        LDAP_GROUP_CLASS.add("groupOfNames".toLowerCase());
+        LDAP_GROUP_CLASS.add("groupOfUniqueNames".toLowerCase());
+        LDAP_GROUP_CLASS.add("dynamicGroup".toLowerCase());
+        LDAP_GROUP_CLASS.add("dynamicGroupAux".toLowerCase());
+        LDAP_GROUP_CLASS.add("groupWiseDistributionList".toLowerCase());
+
+        LDAP_GROUP_MEMBER.add("member".toLowerCase());
+        LDAP_GROUP_MEMBER.add("uniqueMember".toLowerCase());
+    }
+    
+    /**
+     * Create an instance of {@link XWikiLDAPUtils}.
+     * 
+     * @param connection the XWiki LDAP connection tool.
+     */
+    public XWikiLDAPUtils(XWikiLDAPConnection connection)
+    {
+        this.connection = connection;
+    }
+
+    /**
+     * Execute LDAP query to get all group's members.
+     * 
+     * @param groupDN the group to retrieve the members of and scan for subgroups.
+     * @param uidAttributeName the attribute containing the identifier for a user.
+     * @return the LDAP search result.
+     */
+    private List searchGroupsMembers(String groupDN, String uidAttributeName)
+    {
+        String[] attrs = new String[2 + LDAP_GROUP_MEMBER.size()];
+
+        int i = 0;
+        attrs[i++] = LDAP_OBJECTCLASS;
+        attrs[i++] = uidAttributeName;
+        for (Iterator it = LDAP_GROUP_MEMBER.iterator(); it.hasNext();) {
+            attrs[i++] = (String) it.next();
+        }
+
+        return connection.searchLDAP(groupDN, null, attrs, LDAPConnection.SCOPE_BASE);
+    }
+
+    /**
+     * Extract group's members from provided LDAP search result.
+     * 
+     * @param searchAttributeList the LDAP search result.
+     * @param uidAttributeName the attribute containing the identifier for a user.
+     * @param memberMap the result: maps DN to member id.
+     * @param subgroups return all the subgroups identified.
+     */
+    private void getGroupMembers(List searchAttributeList, String uidAttributeName,
+        Map memberMap, List subgroups)
+    {
+        for (Iterator searchAttributeIt = searchAttributeList.iterator(); searchAttributeIt
+            .hasNext();) {
+            XWikiLDAPSearchAttribute searchAttribute =
+                (XWikiLDAPSearchAttribute) searchAttributeIt.next();
+
+            String key = searchAttribute.name;
+            if (LDAP_GROUP_MEMBER.contains(key)) {
+
+                // or subgroup
+                String member = searchAttribute.value;
+
+                // we check for subgroups recursive call to scan all subgroups and identify members
+                // and their uid
+                getGroupMembers(member, uidAttributeName, memberMap, subgroups);
+            }
+        }
+    }
+
+    /**
+     * Get all members of a given group based on the groupDN. If the group contains subgroups get
+     * these members as well. Retrieve an identifier for each member.
+     * 
+     * @param searchAttributeList the LDAP seach result containing group's members.
+     * @param isGroup whether the groupDN is actually a group.
+     * @param id the group identifier based on <code>uidAttributeName</code>.
+     * @param groupDN the group to retrieve the members of and scan for subgroups.
+     * @param uidAttributeName the attribute containing the identifier for a user.
+     * @param memberMap the result: maps DN to member id.
+     * @param subgroups return all the subgroups identified.
+     */
+    private void getGroupMembers(List searchAttributeList, boolean isGroup, String id,
+        String groupDN, String uidAttributeName, Map memberMap, List subgroups)
+    {
+        if (!isGroup) {
+            if (id == null) {
+                LOG.error("Could not find attribute " + uidAttributeName + " for LDAP dn "
+                    + groupDN);
+            }
+
+            if (!memberMap.containsKey(groupDN)) {
+                memberMap.put(groupDN, id == null ? "" : id);
+            }
+        } else {
+
+            // remember this group
+            if (subgroups != null) {
+                subgroups.add(groupDN);
+            }
+
+            getGroupMembers(searchAttributeList, uidAttributeName, memberMap, subgroups);
+        }
+    }
+
+    /**
+     * Get all members of a given group based on the groupDN. If the group contains subgroups get
+     * these members as well. Retrieve an identifier for each member.
+     * 
+     * @param groupDN the group to retrieve the members of and scan for subgroups.
+     * @param uidAttributeNameIn the attribute containing the identifier for a user (default=cn).
+     * @param memberMap the result: maps DN to member id.
+     * @param subgroups all the subgroups identified.
+     * @return whether the groupDN is actually a group.
+     */
+    public boolean getGroupMembers(String groupDN, String uidAttributeNameIn, Map memberMap,
+        List subgroups)
+    {
+        boolean isGroup = false;
+
+        // break out if there is a look of groups
+        if (subgroups != null && subgroups.contains(groupDN)) {
+            return true;
+        }
+
+        String uidAttributeName =
+            uidAttributeNameIn == null || uidAttributeNameIn.length() == 0 ? "cn"
+                : uidAttributeNameIn;
+
+        List searchAttributeList = searchGroupsMembers(groupDN, uidAttributeName);
+
+        if (searchAttributeList != null) {
+            String id = null;
+
+            for (Iterator seachAttributeIt = searchAttributeList.iterator(); seachAttributeIt
+                .hasNext();) {
+                XWikiLDAPSearchAttribute searchAttribute =
+                    (XWikiLDAPSearchAttribute) seachAttributeIt.next();
+
+                String key = searchAttribute.name;
+
+                if (key.equalsIgnoreCase(LDAP_OBJECTCLASS)) {
+                    String objectName = searchAttribute.value;
+                    if (LDAP_GROUP_CLASS.contains(objectName.toLowerCase())) {
+                        isGroup = true;
+                    }
+                } else if (key.equalsIgnoreCase(uidAttributeName)) {
+                    id = searchAttribute.value;
+                }
+            }
+
+            getGroupMembers(searchAttributeList, isGroup, id, groupDN, uidAttributeName,
+                memberMap, subgroups);
+        }
+
+        return isGroup;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/ldap/XWikiLDAPUtils.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java	(révision 0)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java	(révision 0)
@@ -0,0 +1,846 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.user.impl.LDAP;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.securityfilter.realm.SimplePrincipal;
+
+import com.novell.ldap.LDAPConnection;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.cache.api.XWikiCache;
+import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.plugin.ldap.XWikiLDAPConfig;
+import com.xpn.xwiki.plugin.ldap.XWikiLDAPConnection;
+import com.xpn.xwiki.plugin.ldap.XWikiLDAPSearchAttribute;
+import com.xpn.xwiki.plugin.ldap.XWikiLDAPUtils;
+import com.xpn.xwiki.user.api.XWikiGroupService;
+import com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl;
+import java.security.Principal;
+import java.util.HashMap;
+
+/**
+ * This class provides an authentication method that validates a user trough LDAP against a
+ * directory. It just gives LDAP users access if they belong to a particular group and creates XWiki
+ * users if they have never logged in before Furthermore, it synchronizes membership to XWiki groups
+ * based on membership to LDAP groups.
+ * 
+ * @version $Id: $
+ */
+public class XWikiLDAPAuthServiceImpl extends XWikiAuthServiceImpl
+{
+    /**
+     * simple cache for LDAP groups and their members - cache entries are to expire after 6h and
+     * there is no size limit.
+     */
+    protected static XWikiCache cache;
+
+    /**
+     * Logging tool.
+     */
+    private static final Log LOG = LogFactory.getLog(XWikiLDAPAuthServiceImpl.class);
+
+    /**
+     * Initialize groups cache.
+     * 
+     * @param context the XWiki context containing {@link XWikiCacheService}.
+     * @throws XWikiException error when creating the cache.
+     */
+    private static void initGroupCache(XWikiContext context) throws XWikiException
+    {
+        if (cache == null) {
+            cache = context.getWiki().getCacheService().newCache("ldap.group");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl#authenticate(java.lang.String,
+     *      java.lang.String, com.xpn.xwiki.XWikiContext)
+     */
+    public Principal authenticate(String userName, String password, XWikiContext context)
+        throws XWikiException
+    {
+        // 1. check Superadmin
+        // 2. check if ldap authentication is off => authenticate against db
+        // 3. bind to LDAP => if failed try db
+        // 4. if group param, verify group membership (& get DN)
+        // 4. if no group locate dn_ldap attribute on user
+        // 5. if no dn search for user
+        // 6. compare pwd
+        // 7. if flag check if !user exists => create user
+        // 8. if flag update user attributes
+        // 9. if flag update Xwiki groupmembership
+        // on Error try local DB login
+
+        Principal principal = null;
+
+        // Check if cache is initialized
+        initGroupCache(context);
+
+        // message to the user: nousername, nopassword, wrongpassword, wronguser, loginfailed
+        // context.put("message", "nopassword");
+
+        if ((userName == null) || (userName.length() == 0)) {
+            return null;
+        }
+        String ldapUserName = userName.replaceAll(" ", "");
+        if ((password == null) || (password.trim().length() == 0)) {
+            return null;
+        }
+
+        // strip possible "XWiki."
+        // ATTENTION: Possible incompatibility to before now user is NEVER located with
+        // "XWiki.username" in LDAP
+        int i = ldapUserName.indexOf(".");
+        if (i != -1) {
+            ldapUserName = ldapUserName.substring(i + 1);
+        }
+
+        // If we have the context then we are using direct mode
+        // then we should specify the database
+        // This is needed for virtual mode to work
+
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+
+        XWikiLDAPConnection connector = new XWikiLDAPConnection();
+        XWikiLDAPUtils ldapUtils = new XWikiLDAPUtils(connector);
+
+        try {
+            // Check for superadmin
+            if (isSuperAdmin(ldapUserName)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Superadmin logged in.");
+                }
+
+                return authenticateSuperAdmin(password, context);
+            }
+
+            // check if LDAP is activated in xwiki.cfg
+            String ldapActiv = config.getLDAPParam("ldap", "0", context);
+            if (!ldapActiv.equalsIgnoreCase("1")) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("LDAP authentication failed: LDAP not activ");
+                }
+
+                return null;
+            }
+
+            // Open LDAP connection
+            if (!connector.open(ldapUserName, password, context)) {
+                LOG.error("Bind to LDAP server failed.");
+                return null;
+            }
+
+            String uidattr = config.getLDAPParam("ldap_UID_attr", "cn", context);
+
+            // verify group
+            String userDN = null;
+            String userGroup = config.getLDAPParam("ldap_user_group", "", context);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Checking if the user belongs to the user group: " + userGroup);
+            }
+
+            if (userGroup.length() > 0) {
+                Map groupMembers = getGroupMembers(ldapUtils, userGroup, context);
+
+                // check if user is in the list
+                userDN = findInGroup(ldapUserName, groupMembers, "cn");
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found user dn in user group:" + userDN);
+                }
+
+                // if a usergroup is specified THEN the user MUST be in the group to validate in
+                // LDAP
+                if (userDN == null) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("LDAP authentication failed: user not in LDAP user group");
+                    }
+
+                    // no valid LDAP user from the group
+                    return null;
+                }
+            }
+
+            if (userDN == null) {
+                // get DN from existing XWiki user
+                userDN = getLDAPDN(ldapUserName, context);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found user dn with the user object: " + userDN);
+                }
+            }
+
+            // parse field mappings
+            List attributeNameList = new ArrayList();
+            Map userMappings = config.getUserMappings(attributeNameList, context);
+
+            List searchAttributes = null;
+
+            // if we still don't have a dn, search for it. Also get the attributes, we might need
+            // them
+            if (userDN == null) {
+                // search for the user in LDAP
+                String query = "(" + uidattr + "=" + ldapUserName + ")";
+                String baseDN = config.getLDAPParam("ldap_base_DN", "", context);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Searching for the user in LDAP: user:" + ldapUserName + " base:"
+                        + baseDN + " query:" + query + " uid:" + uidattr);
+                }
+
+                String[] attributeNameTable = null;
+                int lsize = attributeNameList.size();
+                if (lsize > 0) {
+                    attributeNameTable = (String[]) attributeNameList.toArray(new String[lsize]);
+                }
+
+                searchAttributes =
+                    connector.searchLDAP(baseDN, query, attributeNameTable,
+                        LDAPConnection.SCOPE_SUB);
+
+                for (Iterator it = searchAttributes.iterator(); it.hasNext();) {
+                    XWikiLDAPSearchAttribute searchAttribute =
+                        (XWikiLDAPSearchAttribute) it.next();
+
+                    if ("dn".equals(searchAttribute.name)) {
+                        userDN = searchAttribute.value;
+
+                        break;
+                    }
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found Attributes in LDAP " + searchAttributes.size());
+                    LOG.debug("Found user dn=" + userDN);
+                }
+            }
+
+            // NOW verify password
+            if ("1".equals(config.getLDAPParam("ldap_validate_password", "0", context))) {
+                if (!connector.checkPassword(userDN, password)) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG
+                            .debug("LDAP authentication failed: could not validate the password: wrong password for "
+                                + userDN);
+                    }
+
+                    return null;
+                }
+            } else {
+                LOG.debug("Password is already supposed to be verified when bound to LDAP");
+            }
+
+            // check if we have to create the user
+            String xwikiuser = findUser(ldapUserName, context);
+
+            boolean createuser = false;
+            if (xwikiuser == null
+                || config.getLDAPParam("ldap_update_user", "0", context).equals("1")) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("LDAP attributes will be used to update XWiki attributes.");
+                }
+
+                // get attributes from LDAP if we don't already have them
+                if (searchAttributes == null) {
+                    String[] attributeNameTable = null;
+                    int lsize = attributeNameList.size();
+                    if (lsize > 0) {
+                        attributeNameTable =
+                            (String[]) attributeNameList.toArray(new String[lsize]);
+                    }
+
+                    // didn't get attributes before, so do it now
+                    searchAttributes =
+                        connector.searchLDAP(userDN, null, attributeNameTable,
+                            LDAPConnection.SCOPE_BASE);
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Found Attributes in LDAP " + searchAttributes.size());
+                    }
+                }
+
+                // create user
+                if (xwikiuser == null) {
+                    LOG.debug("Creating new XWiki user based on LDAP attribues located at "
+                        + userDN);
+                    createUserFromLDAP(ldapUserName, userMappings, searchAttributes, context);
+                    LOG.debug("New XWiki user created: " + ldapUserName);
+                    createuser = true;
+                } else {
+                    LOG.debug("Updating existing user with LDAP attribues located at " + userDN);
+                    updateUserFromLDAP(ldapUserName, userMappings, searchAttributes, context);
+                }
+            }
+
+            // from now on we can enter the application
+            principal = getUserPrincipal(ldapUserName, context);
+            if (principal == null) {
+                LOG.debug("Could not create authenticated principal.");
+                return null;
+            }
+
+            // update group membership, join and remove from given groups sync group membership for
+            // this user
+            syncGroupsMembership(ldapUserName, userDN, createuser, ldapUtils, context);
+        } catch (Exception e) {
+            LOG.error("LDAP authentication failed.", e);
+        } finally {
+            connector.close();
+
+            // one last option
+            if (principal == null) {
+                principal = localDBLogin(userName, password, context);
+            }
+        }
+
+        return principal;
+    }
+
+    /**
+     * Try local DB login and return {@link Principal}.
+     * 
+     * @param userName the name of the user to log in.
+     * @param password the password of the user to log in.
+     * @param context the XWiki context.
+     * @return the {@link Principal}.
+     * @throws XWikiException error when checking user name and password.
+     */
+    protected Principal localDBLogin(String userName, String password, XWikiContext context)
+        throws XWikiException
+    {
+        Principal principal = null;
+
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+
+        String trylocal = config.getLDAPParam("ldap_trylocal", "0", context);
+
+        if ("1".equals(trylocal)) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Trying authentication against XWiki DB");
+            }
+
+            // try local user
+            // Use XWiki password
+            if (checkPassword(findUser(userName, context), password, context)) {
+                principal = getUserPrincipal(userName, context);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("XWiki DB login succeeded");
+                }
+            } else {
+                context.put("message", "loginfailed");
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("XWiki DB login failed");
+                }
+            }
+        }
+
+        return principal;
+    }
+
+    /**
+     * Synchronize user XWiki membership with it's LDAP membership.
+     * 
+     * @param userName the name of the user.
+     * @param userDN the LDAP DN of the user.
+     * @param createuser indicate if the user is created or updated.
+     * @param ldapUtils the LDAP communication tool.
+     * @param context the XWiki context.
+     * @throws XWikiCacheNeedsRefreshException error when getting group members from cache.
+     * @throws XWikiException error when synchronizing user membership.
+     */
+    protected void syncGroupsMembership(String userName, String userDN, boolean createuser,
+        XWikiLDAPUtils ldapUtils, XWikiContext context) throws XWikiCacheNeedsRefreshException,
+        XWikiException
+    {
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+
+        // got valid group mappings
+        Map groupMappings = config.getGroupMappings(context);
+
+        // update group membership, join and remove from given groups
+        // sync group membership for this user
+        if (groupMappings.size() > 0) {
+            // flag if always sync or just on create of the user
+            String syncmode = config.getLDAPParam("ldap_mode_group_sync", "", context);
+
+            if ((syncmode.equalsIgnoreCase("create") && createuser)
+                || syncmode.equalsIgnoreCase("always")) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Updating group membership for the user: " + userName);
+                }
+
+                // ASSUMING the implementation still returns the actual list. In this case
+                // manipulations to the list are for real.
+                // get the list of groups the user already belongs to
+                Collection userGroups =
+                    context.getWiki().getGroupService(context).getAllGroupsNamesForMember(
+                        userName, 0, 0, context);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("The user belongs to following XWiki groups: ");
+                    for (Iterator it = userGroups.iterator(); it.hasNext();) {
+                        LOG.debug(it.next().toString());
+                    }
+                }
+
+                // retrieve list of all groups
+                List allxwikigroups =
+                    context.getWiki().getGroupService(context).getAllMatchedGroups(null, false,
+                        0, 0, null, context);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("All defined XWiki groups: ");
+                    for (Iterator it = allxwikigroups.iterator(); it.hasNext();) {
+                        LOG.debug(it.next().toString());
+                    }
+                }
+
+                // go through mapped groups to locate the user
+                for (Iterator itGroupMap = groupMappings.entrySet().iterator(); itGroupMap
+                    .hasNext();) {
+                    Map.Entry entry = (Map.Entry) itGroupMap.next();
+
+                    String groupDN = (String) entry.getKey();
+                    String xwikiGroupName = (String) entry.getValue();
+
+                    // check if group is in list of all groups
+                    if (!allxwikigroups.contains(xwikiGroupName)) {
+                        LOG.error("XWiki group not found:" + xwikiGroupName);
+                        continue;
+                    }
+
+                    Map groupMembers = getGroupMembers(ldapUtils, groupDN, context);
+
+                    if (groupMembers.containsKey(userDN)) {
+                        // add to group if not there
+                        if (!userGroups.contains(xwikiGroupName)) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("Adding user " + userName + " to xwiki group "
+                                    + xwikiGroupName);
+                            }
+
+                            addUserToXWikiGroup(userName, xwikiGroupName, context);
+                            // c.add(xwikigroupname);
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("Finished adding user " + userName + " to xwiki group "
+                                    + xwikiGroupName);
+                            }
+                            // is supposed to equivalent to
+                            // context.getWiki().getGroupService(context).addUserToGroup(user,
+                            // context.getDatabase(), xwikigroupname, context);
+                        }
+                    } else {
+                        // remove from group if there
+                        if (userGroups.contains(xwikiGroupName)) {
+                            removeUserFromGroup(userName, xwikiGroupName, context);
+                            // c.remove(xwikigroupname);
+
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("Finished removing xwiki group " + xwikiGroupName
+                                    + " from user " + userName);
+                            }
+                        }
+                    }
+                }
+
+                /*
+                 * This may not be necessary, but the group service does have a cache, and I've
+                 * found that adding or removing entries sometimes don't take effect if I don't do
+                 * this.
+                 */
+                context.getWiki().getGroupService(context).flushCache();
+            }
+
+        }
+    }
+
+    /**
+     * Get group members from cache or update it from LDAP if it is not already in cached.
+     * 
+     * @param ldapUtils the LDAP communication tool.
+     * @param groupDN the name of the group.
+     * @param uidattr
+     * @param context the XWiki context.
+     * @return the members of the group.
+     * @throws XWikiCacheNeedsRefreshException error when getting group members from cache.
+     */
+    protected Map getGroupMembers(XWikiLDAPUtils ldapUtils, String groupDN, XWikiContext context)
+        throws XWikiCacheNeedsRefreshException
+    {
+        Map groupMembers = null;
+
+        XWikiLDAPConfig config = XWikiLDAPConfig.getInstance();
+
+        String uidattr = config.getLDAPParam("ldap_UID_attr", "cn", context);
+
+        synchronized (cache) {
+            groupMembers = (Map) cache.getFromCache(groupDN, config.getCacheExpiration(context));
+        }
+
+        if (groupMembers == null) {
+            groupMembers = new HashMap();
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Retrieving Members of the group: " + groupDN);
+            }
+
+            if (ldapUtils.getGroupMembers(groupDN, uidattr, groupMembers, new ArrayList())) {
+                synchronized (cache) {
+                    cache.putInCache(groupDN, groupMembers);
+                }
+            }
+        }
+
+        return groupMembers;
+    }
+
+    /**
+     * Add user name to provided XWiki group.
+     * 
+     * @param userName the name of the user.
+     * @param groupName the name of the group.
+     * @param context the XWiki context.
+     */
+    // TODO move this methods in a toolkit for all platform.
+    protected void addUserToXWikiGroup(String userName, String groupName, XWikiContext context)
+    {
+        try {
+            String fullWikiUserName = "XWiki." + userName;
+
+            String groupClassName = context.getWiki().getGroupClass(context).getName();
+
+            // Get document representing group
+            XWikiDocument groupDoc = context.getWiki().getDocument(groupName, context);
+
+            // Add a member object to document
+            BaseObject memberobj = groupDoc.newObject(groupClassName, context);
+            memberobj.setStringValue("member", fullWikiUserName);
+
+            // Save modifications
+            context.getWiki().saveDocument(groupDoc, context);
+
+            // Update group cache
+            XWikiGroupService gservice = context.getWiki().getGroupService(context);
+            gservice.addUserToGroup(fullWikiUserName, context.getDatabase(), groupName, context);
+
+        } catch (Exception e) {
+            LOG.error(String.format("Failed to add a user [{0}] to a group [{1}]", new String[] {
+            userName, groupName}), e);
+        }
+    }
+
+    /**
+     * Remove user name from provided XWiki group.
+     * 
+     * @param userName the name of the user.
+     * @param groupName the name of the group.
+     * @param context the XWiki context.
+     */
+    // TODO move this methods in a toolkit for all platform.
+    protected void removeUserFromGroup(String userName, String groupName, XWikiContext context)
+    {
+        try {
+            String fullWikiUserName = "XWiki." + userName;
+
+            String groupClassName = context.getWiki().getGroupClass(context).getName();
+
+            // Get the XWiki document holding the objects comprising the group membership list
+            XWikiDocument groupDoc = context.getWiki().getDocument(groupName, context);
+
+            // Get and remove the specific group membership object for the user
+            BaseObject groupObj = groupDoc.getObject(groupClassName, "member", fullWikiUserName);
+            groupDoc.removeObject(groupObj);
+
+            // Save modifications
+            context.getWiki().saveDocument(groupDoc, context);
+
+            // XWikiGroupService gservice = context.getWiki().getGroupService(context);
+            // gservice.addUserToGroup(fullwikiname, context.getDatabase(), groupname, context);
+
+        } catch (Exception e) {
+            LOG.error(
+                "Failed to remove a user from a group " + userName + " group: " + groupName, e);
+        }
+    }
+
+    protected Principal getUserPrincipal(String userName, XWikiContext context)
+    {
+        Principal principal = null;
+
+        // First we check in the local database
+        String user = null;
+        try {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Finding user " + userName);
+            }
+
+            user = findUser(userName, context);
+            if (user != null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found user " + userName);
+                }
+
+                principal = new SimplePrincipal(user);
+            }
+        } catch (Exception e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Failed creating a Principal for user " + user, e);
+            }
+        }
+
+        if (context.isVirtual()) {
+            if (principal == null) {
+                // Then we check in the main database
+                String database = context.getDatabase();
+
+                try {
+                    context.setDatabase(context.getMainXWiki());
+
+                    try {
+                        user = findUser(userName, context);
+                        if (user != null) {
+                            principal = new SimplePrincipal(context.getDatabase() + ":" + user);
+                        }
+                    } catch (Exception e) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Failed creating a Principal for user " + user, e);
+                        }
+                    }
+                } finally {
+                    context.setDatabase(database);
+                }
+            }
+        }
+
+        return principal;
+    }
+
+    /**
+     * Sets attributes on the user object based on attribute values provided by the LDAP.
+     * 
+     * @param userName
+     * @param mappings
+     * @param attributes
+     * @param context
+     * @throws XWikiException
+     */
+    protected void updateUserFromLDAP(String userName, Map mappings, List attributes,
+        XWikiContext context) throws XWikiException
+    {
+        BaseClass userClass = context.getWiki().getUserClass(context);
+
+        String fullWikiUserName = "XWiki." + userName;
+        XWikiDocument doc = context.getWiki().getDocument(fullWikiUserName, context);
+        BaseObject bobj = doc.getObject(userClass.getName());
+
+        for (Iterator it = attributes.iterator(); it.hasNext();) {
+            XWikiLDAPSearchAttribute lattr = (XWikiLDAPSearchAttribute) it.next();
+
+            String lval = lattr.value;
+            String xattr = (String) mappings.get(lattr.name);
+
+            if (xattr != null) {
+                if (xattr.equals("name")) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Ignoring a mapping for name since the name is already set to "
+                            + userName);
+                    }
+                } else {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Setting XWiki field " + xattr + " (from LDAP attribute: "
+                            + lattr.name + ") Value:" + lval);
+                    }
+
+                    bobj.setStringValue(xattr, lval);
+                }
+            }
+        }
+
+        context.getWiki().saveDocument(doc, context);
+    }
+
+    /**
+     * Create an XWiki user and set all mapped attributes from LDAP to XWiki attributes.
+     * 
+     * @param mappings
+     * @param attributes
+     * @param context
+     * @throws XWikiException
+     */
+    protected void createUserFromLDAP(String userName, Map mappings, List attributes,
+        XWikiContext context) throws XWikiException
+    {
+        BaseClass userClass = context.getWiki().getUserClass(context);
+
+        Map map = new HashMap();
+        for (Iterator it = attributes.iterator(); it.hasNext();) {
+            XWikiLDAPSearchAttribute lattr = (XWikiLDAPSearchAttribute) it.next();
+
+            String lval = lattr.value;
+            String xattr = (String) mappings.get(lattr.name);
+            if (xattr == null) {
+                continue;
+            }
+            map.put(xattr, lval);
+            LOG.debug("Mapping " + xattr + " to " + lval);
+        }
+        // Mark user active
+        map.put("active", "1");
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Creating User: " + userName);
+        }
+
+        context.getWiki().createUser(userName, map, userClass.getName(),
+            "#includeForm(\"XWiki.XWikiUserTemplate\")", "edit", context);
+    }
+
+    /**
+     * Locates the user in the Map: either the user is a value or the key starts with the LDAP
+     * syntax.
+     * 
+     * @param user
+     * @param groupMembers
+     * @param uid
+     * @return
+     */
+    protected String findInGroup(String user, Map groupMembers, String uid)
+    {
+        String result = null;
+
+        String ldapuser = null;
+        if (uid == null || uid.length() == 0) {
+            uid = "cn";
+        }
+        ldapuser = uid + "=" + user.toLowerCase();
+
+        for (Iterator it = groupMembers.keySet().iterator(); it.hasNext();) {
+            String u = (String) it.next();
+            // implementing it case-insensitive for now
+            if (user.equalsIgnoreCase((String) groupMembers.get(u))
+                || u.toLowerCase().startsWith(ldapuser)) {
+                return u;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Tries to retrieve the DN from the users object.
+     * 
+     * @param susername
+     * @param context
+     * @return
+     */
+    protected String getLDAPDN(String susername, XWikiContext context)
+    {
+        String dn = null;
+
+        if (context != null) {
+            // First we check in the local database
+            try {
+                String user = findUser(susername, context);
+                if (user != null && user.length() != 0) {
+                    dn = getDNFromXWikiUser(user, context);
+                }
+            } catch (Exception e) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Faild finding LDAP DN stored in the user object.", e);
+                }
+                // ignore
+            }
+
+            if (context.isVirtual()) {
+                if (dn == null || dn.length() == 0) {
+                    // Then we check in the main database
+                    String db = context.getDatabase();
+                    try {
+                        context.setDatabase(context.getWiki().getDatabase());
+                        try {
+                            String user = findUser(susername, context);
+                            if (user != null && user.length() != 0) {
+                                dn = getDNFromXWikiUser(user, context);
+                            }
+                        } catch (Exception e) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug(
+                                    "Faild finding LDAP DN stored in the user object (virtual).",
+                                    e);
+                            }
+                            // ignore
+                        }
+                    } finally {
+                        context.setDatabase(db);
+                    }
+                }
+            }
+        }
+        return dn;
+    }
+
+    /**
+     * Get the DN user document XWiki.XWikiUsers object contains.
+     * 
+     * @param userName the XWiki user name.
+     * @param context the XWiki context.
+     * @return the DN.
+     */
+    protected String getDNFromXWikiUser(String userName, XWikiContext context)
+    {
+        String dn = null;
+
+        try {
+            XWikiDocument doc = context.getWiki().getDocument(userName, context);
+
+            BaseClass userClass = context.getWiki().getUserClass(context);
+
+            // We only allow empty password from users having a XWikiUsers object.
+            if (doc.getObject(userClass.getName()) != null) {
+                dn = doc.getStringValue(userClass.getName(), "ldap_dn");
+            }
+
+        } catch (Throwable e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Retrieving the ldap_dn attribute from the XWikiUsers object failed.",
+                    e);
+            }
+        }
+
+        return dn;
+    }
+}

Modification de propriétés sur /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/src/main/java/com/xpn/xwiki/user/impl/LDAP/XWikiLDAPAuthServiceImpl.java
___________________________________________________________________
Nom : svn:eol-style
   + native

Index: /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/pom.xml
===================================================================
--- /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/pom.xml	(révision 7502)
+++ /media/data/projets/xwiki/src/xwikibranch12/xwiki-core/xwiki-core/pom.xml	(copie de travail)
@@ -165,6 +165,32 @@
       <artifactId>ldap</artifactId>
       <version>UNKNOWN</version>
     </dependency>
+    
+    <!-- Dependencies for LDAP unit tests -->
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-server-unit</artifactId>
+      <version>1.0.2</version>
+      <scope>test</scope>
+    </dependency>
+    <!-- <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>nlog4j</artifactId>
+      <version>1.2.25</version>
+      <scope>test</scope>
+    </dependency> -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>1.4.3</version>
+      <scope>test</scope>
+    </dependency>
+    <!-- <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-bootstrap-partition</artifactId>
+      <version>1.5.1</version>
+      <scope>test</scope>
+    </dependency> -->
 
     <!-- Version 1.0.0-rc1 has some bad dependencies in the POM. This is fixed in 1.0.0 but unfortunately we're
          using an API (setDataAreaRatio()) that has disappeared in 1.0.0 so we need to fix this before we can
@@ -274,7 +300,7 @@
     <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate</artifactId>
-      <version>3.1.3</version>
+      <version>3.2.5.ga</version>
     </dependency>
     <dependency>
       <groupId>commons-httpclient</groupId>
