Index: /xwiki-platform-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/CustomIdentifierAuthenticationService.java
===================================================================
--- /xwiki-platform-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/CustomIdentifierAuthenticationService.java	(revision 0)
+++ /xwiki-platform-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/CustomIdentifierAuthenticationService.java	(revision 0)
@@ -0,0 +1,550 @@
+package com.xpn.xwiki.user.impl.xwiki;
+
+import java.math.BigInteger;
+import java.rmi.RemoteException;
+import java.security.Principal;
+import java.sql.Array;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.securityfilter.filter.SecurityRequestWrapper;
+import org.securityfilter.realm.SimplePrincipal;
+
+import com.xpn.xwiki.XWiki;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.user.api.XWikiGroupService;
+import com.xpn.xwiki.user.api.XWikiUser;
+import com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl;
+import com.xpn.xwiki.user.impl.xwiki.XWikiAuthenticator;
+
+/**
+ * 
+ * 
+ *   email |  --------------------->     MyAuthService.checkAuth 
+ *  pass  |                                  |
+ *                                           |
+ *                                      MyFormAuthenticator.
+ *                                           |
+ *                                           |
+ *                                        MyAuthService.authenticate
+ *                                          detect 
+ *                                        email only-> check email/password against the web service authenticator
+ *                                        retrieve the XWiki ID 
+ *                                        say ok
+ *                                        concatenate ID+EMAIL in the Principal
+ *                                           |
+ *                                           |
+ *                                        MyFormAuthenticator: saves the Principal in the cookie
+ *                                           | 
+ *                                        MyAuthService returns the XWiki ID encapsulated in a XWikiUser
+ **/
+
+public class CustomIdentifierAuthenticationService extends XWikiAuthServiceImpl
+{
+
+    private static final Log log = LogFactory.getLog(CustomIdentifierAuthenticationService.class);
+
+    protected SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+
+    public static final String USER_SPACE = "XWiki";
+
+    public static final String ADMINISTRATION_SPACE = "Administration";
+
+    public static final String USER_ADMINISTRATION_CLASS_NAME = "XWiki.UserAdministrationData";
+
+    public static final int VOTES_MAX_VALUE = 10;
+
+    public XWikiUser checkAuth(XWikiContext context) throws XWikiException
+    {
+        XWiki xwiki = context.getWiki();
+        HttpServletRequest request = null;
+        HttpServletResponse response = null;
+
+        if (context.getRequest() != null)
+            request = context.getRequest().getHttpServletRequest();
+
+        if (context.getResponse() != null)
+            response = context.getResponse().getHttpServletResponse();
+
+        if (request == null)
+            return null;
+
+        XWikiAuthenticator auth = getAuthenticator(context);
+        SecurityRequestWrapper wrappedRequest =
+            new SecurityRequestWrapper(request, null, null, auth.getAuthMethod());
+
+        try {
+
+            // Process login out (this only works with FORMS
+            if (auth.processLogout(wrappedRequest, response, xwiki.getUrlPatternMatcher())) {
+                if (log.isInfoEnabled())
+                    log.info("User " + context.getUser() + " has been logged-out");
+                wrappedRequest.setUserPrincipal(null);
+                return null;
+            }
+            Principal user = wrappedRequest.getUserPrincipal();
+            if (auth.processLogin(wrappedRequest, response, context)) {
+                user = wrappedRequest.getUserPrincipal();
+
+                // RETURN THE XWIKI ID EXTRACTED FROM THE PRINCIPAL
+
+                if (user == null)
+                    return null;
+                else
+                    return new XWikiUser(convertNameToId(user.getName(), USER_SPACE));
+            }
+
+            // Principal user = wrappedRequest.getUserPrincipal();
+
+            // RETURN THE XWIKI ID EXTRACTED FROM THE PRINCIPAL
+            if (user == null)
+                return null;
+            else {
+                // return new XWikiUser(user.getName());
+
+                return new XWikiUser(convertNameToId(user.getName(), USER_SPACE));
+            }
+        } catch (Exception e) {
+            log.error("checkAut", e);
+            return null;
+        }
+    }
+
+    public String convertNameToId(String name, String userspace)
+    {
+        String xwikiId = "id";
+        if (name != null && name.indexOf(' ') > 0)
+            xwikiId = name.substring(0, name.indexOf(' '));
+        return userspace + "." + xwikiId;
+    }
+
+    public Principal authenticate(String username, String password, XWikiContext context)
+        throws XWikiException
+    {
+        /*
+         * This function was returning null on failure so I preserved that behaviour, while adding
+         * the exact error messages to the context given as argument. However, the right way to do
+         * this would probably be to throw XWikiException-s.
+         */
+
+        if ((username == null) || (username.trim().equals(""))) {
+            context.put("message", "nousername");
+            return null;
+        }
+
+        if ((password == null) || (password.trim().equals(""))) {
+            context.put("message", "nopassword");
+            return null;
+        }
+
+        String superadmin = "superadmin";
+        if (username.equals(superadmin)) {
+            String superadminpassword = context.getWiki().Param("xwiki.superadminpassword");
+            if ((superadminpassword != null) && (superadminpassword.equals(password))) {
+                Principal principal = new SimplePrincipal("XWiki.superadmin");
+                return principal;
+            } else {
+                context.put("message", "wrongpassword");
+                return null;
+            }
+        }
+
+        // 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
+        if (context != null) {
+            // String susername = username;
+            // int i = username.indexOf(".");
+            // if (i != -1)
+            // susername = username.substring(i + 1);
+
+            // username is either email-address (first login) or cust-id + email-address (already
+            // logged in or cookie)
+            // First we check in the local database
+
+            if (username.indexOf(' ') > 0) {
+                // user already logged in
+                String userid = username.substring(0, username.indexOf(' '));
+                String user = findUser(userid, context);
+                if (user != null) {
+                    if (checkPassword(user, password, context)) {
+                        // TODO AUTH MANDRIVA // GET XWIKI USER ID //
+                        // :SL: at this stage we return only the CUST-ID since the email address is
+                        // not used anymore for authentication
+                        // (it will be used again when the Cookie expires: the user will have to
+                        // login again
+                        return new SimplePrincipal(username);
+                    }
+                }
+            }
+
+            // if (context.isVirtual()) {
+            // 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) {
+                    if (username != null && username.indexOf('@') > 0) {
+                        // if (checkPassword(susername, password, context)) {
+                        // concatenate user + mail in the principal
+                        boolean authentified = false;
+                        log.info("Username: " + username + " Password: " + password);
+                        MdkoPacket packet = authenticateAgainstMyMandriva(username, password);
+                        if (packet != null && packet.getData() != null
+                            && packet.getData().getCustid() != null) {
+                            packet = fetchMemberDetails(packet.getData().getCustid());
+                            String[] familiesArray = packet.getData().getFamilies();
+                            List<String> families = new ArrayList<String>();
+                            if (familiesArray != null)
+                                families = Arrays.asList(familiesArray);
+                            MdkoData mdkoData = packet.getData();
+
+                            Date expirationDate = format.parse(expiration);
+                            Calendar cal = GregorianCalendar.getInstance();
+                            Date now = cal.getTime();
+                            long delta = expirationDate.getTime() - now.getTime();
+
+                            authentified = (delta > 0);
+                            
+                            log.info("User " + username + " families: " + families);
+                            log.info("User " + username + " delta: " + delta);
+                            log.info("User " + username + " authentified: " + authentified);
+                            String requestURL = context.getRequest().getRequestURL().toString();
+                            log.info("User " + username + " requestURL: " + requestURL);
+
+                            if (authentified) {
+
+                                log.info("User " + username + " " + packet.getData().getCustid()
+                                    + " is authentified");
+                                synchronizeData(packet.getData(), password, context.getWiki()
+                                    .getDatabase(), context, true);
+                                log.info("User " + username + " " + packet.getData().getCustid()
+                                    + " : data synchronized");
+
+                                return new SimplePrincipal(packet.getData().getCustid() + " "
+                                    + username);
+
+                            }
+                        }
+                        // return new SimplePrincipal(susername);
+                        context.put("message", "wrongpassword");
+                        return null;
+                        // return new SimplePrincipal(context.getDatabase() + ":" + user);
+                        /*
+                         * } else { context.put("message", "wrongpassword"); return null; }
+                         */
+
+                    } else {
+
+                        return null;
+                    }
+                } catch (Exception e) {
+                    context.put("message", "loginfailed");
+                    log.error("authenticate", e);
+
+                    return null;
+                }
+            } finally {
+                context.setDatabase(db);
+            }
+        } else {
+            // error message was already set
+            return null;
+        }
+        /*
+         * } else { context.put("message", "loginfailed"); return null; }
+         */
+    }
+
+    protected MdkoPacket authenticateAgainstMyMandriva(String username, String password)
+    {
+
+        MyFactory myFactory = MyFactory.getInstance();
+        MdkoPacket packet;
+        try {
+            packet = myFactory.authenticateUser(username, password);
+            boolean result = (packet.getData() != null && packet.getData().getCustid() != null);
+            log.debug("(debug) Password check for user '" + username + "': " + result);
+            return packet;
+        } catch (RemoteException e) {
+            log.error("authenticateUser", e);
+            return null;
+        }
+
+    }
+
+    public MdkoPacket fetchMemberDetails(String custId)
+    {
+        MyFactory myFactory = MyFactory.getInstance();
+        MdkoPacket packet;
+        try {
+            packet = myFactory.fetchDetails(custId);
+            return packet;
+        } catch (RemoteException e) {
+            log.error("authenticateUser", e);
+            return null;
+        }
+
+    }
+
+    protected void synchronizeData(MdkoData data, String password, String database,
+        XWikiContext context, boolean flag)
+    {
+        try {
+            XWiki wiki = context.getWiki();
+            BaseClass bclass = wiki.getUserClass(context);
+            BaseClass adminUserClass = wiki.getClass(USER_ADMINISTRATION_CLASS_NAME, context);
+
+            String dbsave = context.getDatabase();
+            // context.setDatabase(database);
+
+            String fullwikiname = USER_SPACE + "." + data.getCustid();
+            String adminuserdocname = getAdministrationUserDocumentName(data.getCustid());
+            XWikiDocument doc = wiki.getDocument(fullwikiname, context);
+            XWikiDocument adminuserdoc = wiki.getDocument(adminuserdocname, context);
+
+            if (wiki.exists(fullwikiname, context) && doc.getObjectNumbers(bclass.getName()) > 0) {
+
+                BaseObject userobj = doc.getObject(bclass.getName());
+                if (userobj == null)
+                    userobj =
+                        createUserObject(doc.getFullName(), data, password, context,
+                            flag);
+
+                convertMdkoDataToUserObject(data, fullwikiname, password, userobj, false);
+                try {
+                    wiki.saveDocument(doc, context);
+                } catch (Exception e) {
+                    log.error("synchronizeData", e);
+                    e.printStackTrace();
+                }
+
+                updateUserGroups(data, userobj, context, flag);
+
+                BaseObject adminUserData = adminuserdoc.getObject(adminUserClass.getName());
+                if (adminUserData == null)
+                    adminUserData =
+                        createUserAdministrationObject(adminuserdocname, data, context);
+
+                convertMdkoDataToUserAdministrationData(data, adminuserdocname, adminUserData,
+                    false);
+                wiki.saveDocument(adminuserdoc, context);
+
+            } else {
+
+                createUserObject(doc.getFullName(), data, password, context, flag);
+                createUserAdministrationObject(adminuserdoc.getFullName(), data, context);
+
+            }
+
+            context.setDatabase(dbsave);
+        } catch (Exception e) {
+            log.error("synchronizeData", e);
+            e.printStackTrace();
+        }
+        return;
+
+    }
+
+    public static String getAdministrationUserDocumentName(String custid)
+    {
+        String docname = ADMINISTRATION_SPACE + "." + custid;
+        return docname;
+    }
+
+    private BaseObject createUserObject(String userDocFullName, MdkoData data, String password,
+        XWikiContext context, boolean flag) throws XWikiException
+    {
+
+        XWiki wiki = context.getWiki();
+        BaseObject bobj = new BaseObject();
+        BaseClass bclass = wiki.getUserClass(context);
+        bobj.setClassName(bclass.getName());
+        convertMdkoDataToUserObject(data, userDocFullName, password, bobj, true);
+        XWikiDocument doc = wiki.getDocument(userDocFullName, context);
+        doc.setParent("");
+        doc.addObject(bclass.getName(), bobj);
+        doc.setContent("#includeForm(\"XWiki.XWikiUserTemplate\")");
+        wiki.protectUserPage(userDocFullName, "edit", doc, context);
+        wiki.saveDocument(doc, context);
+        wiki.setUserDefaultGroup(userDocFullName, context);
+
+        updateUserGroups(data, bobj, context, flag);
+        return bobj;
+
+    }
+
+    private BaseObject createUserAdministrationObject(String adminuserdocname, MdkoData data,
+        XWikiContext context) throws XWikiException
+    {
+        XWiki wiki = context.getWiki();
+        BaseClass adminUserClass = wiki.getClass(USER_ADMINISTRATION_CLASS_NAME, context);
+        BaseObject adminUserData = new BaseObject();
+        adminUserData.setClassName(adminUserClass.getName());
+        convertMdkoDataToUserAdministrationData(data, adminuserdocname, adminUserData, true);
+        XWikiDocument adminuserdoc = wiki.getDocument(adminuserdocname, context);
+
+        adminuserdoc.setParent("");
+        adminuserdoc.addObject(adminUserClass.getName(), adminUserData);
+        adminuserdoc.setContent("#includeForm(\"" + ADMINISTRATION_SPACE
+            + ".UserAdministrationDataTemplate\")");
+        wiki.saveDocument(adminuserdoc, context);
+        return adminUserData;
+
+    }
+
+    private void updateUserGroups(MdkoData data, BaseObject bobj, XWikiContext context,
+        boolean flag)
+
+    {
+
+        try {
+            XWiki xwiki = context.getWiki();
+            
+            String group = getGroupNameFromMembershipLevel();
+
+            String xwikiId = USER_SPACE + "." + data.getCustid();
+            Collection userGroups =
+                xwiki.getGroupService(context).listGroupsForUser(xwikiId, context);
+            
+
+                removeUserFromGroups(data.getCustid(), groups.toArray(new String[0]), context);
+                log.info("Removing user " + data.getCustid() + " from groups");
+                addUserTotGroup(data.getCustid(), group, context);
+
+            String[] familiesArray = data.getFamilies();
+            List<String> families = new ArrayList<String>();
+            if (familiesArray != null)
+                families = Arrays.asList(familiesArray);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    private void convertMdkoDataToUserObject(MdkoData data, String fullwikiname, String password,
+        BaseObject bobj, boolean init)
+    {
+        bobj.setName(fullwikiname);
+        bobj.setStringValue("first_name", data.getAlias());
+        bobj.setStringValue("lastname", data.getLastname());
+        bobj.setStringValue("email", data.getEmail());
+        bobj.setStringValue("password", password);
+        // only create the fields below if we are initiating the object
+        if (init) {
+            bobj.setStringValue("blog", "");
+            bobj.setStringValue("blogfeed", "");
+            bobj.setStringValue("city", "");
+            bobj.setStringValue("company", "");
+            bobj.setStringValue("country", "");
+            bobj.setLargeStringValue("comment", "");
+            bobj.setStringValue("signature", "");
+
+            bobj.setStringValue("default_language", data.getLang_code().substring(0, 2));
+
+            bobj.setStringValue("avatar", "");
+        }
+
+    }
+
+    private void convertMdkoDataToUserAdministrationData(MdkoData data, String fullName,
+        BaseObject userAdministrationData, boolean init)
+    {
+        userAdministrationData.setName(fullName);
+
+        String registration = data.getTimecreate();
+
+    }
+
+    public void addUserTotGroup(String fullUserName, String fullGroupName, XWikiContext context)
+        throws XWikiException
+    {
+        XWiki xwiki = context.getWiki();
+        BaseClass gclass = xwiki.getGroupClass(context);
+
+        XWikiDocument groupdoc = xwiki.getDocument(fullGroupName, context);
+
+        BaseObject memberobj = (BaseObject) gclass.newObject(context);
+        memberobj.setClassName(gclass.getName());
+        memberobj.setName(groupdoc.getFullName());
+        memberobj.setStringValue("member", fullUserName);
+        groupdoc.addObject(gclass.getName(), memberobj);
+        if (groupdoc.isNew()) {
+            String content = "#includeForm(\"XWiki.XWikiGroupTemplate\")";
+            groupdoc.setContent(content);
+            xwiki.saveDocument(groupdoc, context);
+        } else {
+            xwiki.getHibernateStore().saveXWikiObject(memberobj, context, true);
+        }
+
+        try {
+            XWikiGroupService gservice = (XWikiGroupService) xwiki.getGroupService(context);
+            gservice.addUserToGroup(fullUserName, context.getDatabase(), fullGroupName, context);
+        } catch (Exception e) {
+            log.error("addUserTotGroup", e);
+            e.printStackTrace();
+        }
+    }
+
+    public void removeUserFromGroups(String fullUserName, String[] groupNames,
+        XWikiContext context) throws XWikiException
+    {
+        XWiki xwiki = context.getWiki();
+
+        BaseClass gclass = xwiki.getGroupClass(context);
+
+        for (int i = 0; i < groupNames.length; i++) {
+
+            XWikiDocument groupdoc = xwiki.getDocument(groupNames[i], context);
+
+            if (groupdoc.isNew())
+                continue;
+
+            BaseObject memberobj = groupdoc.getObject(gclass.getName(), "member", fullUserName);
+
+            if (memberobj == null)
+                continue;
+
+            boolean inGroup = groupdoc.removeObject(memberobj);
+
+            if (!inGroup)
+                continue;
+
+            xwiki.getHibernateStore().saveXWikiObject(memberobj, context, true);
+
+            try {
+                XWikiGroupService gservice = (XWikiGroupService) xwiki.getGroupService(context);
+                gservice.removeUserFromGroup(fullUserName, context.getDatabase(), groupNames[i],
+                    context);
+            } catch (Exception e) {
+                log.error("removeUserFromGroups", e);
+                e.printStackTrace();
+            }
+
+        }
+    }
+
+}
Index: /xwiki-platform-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java
===================================================================
--- /xwiki-platform-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java	(revision 3992)
+++ /xwiki-platform-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java	(working copy)
@@ -138,7 +138,9 @@
                     // did the user request that their login be persistent? 
                     if (rememberme != null) { 
                         // remember login 
-                        persistentLoginManager.rememberLogin(request, response, username, password); 
+                        //:SL: 
+                        String loginRemember = principal.getName(); 
+                        persistentLoginManager.rememberLogin(request, response, loginRemember, password); 
                     } else { 
                         // forget login 
                         persistentLoginManager.forgetLogin(request, response); 
