Added: 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultJamesUser.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultJamesUser.java?rev=599566&view=auto
==============================================================================
--- 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultJamesUser.java
 (added)
+++ 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultJamesUser.java
 Thu Nov 29 12:08:58 2007
@@ -0,0 +1,141 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+
+
+package org.apache.james.userrepository;
+
+import org.apache.james.services.JamesUser;
+import org.apache.mailet.MailAddress;
+
+/**
+ * Implementation of User Interface.
+ *
+ *
+ * @version $Revision: 521427 $
+ */
+
+public class DefaultJamesUser 
+        extends DefaultUser
+        implements JamesUser {
+
+    private static final long serialVersionUID = 6323959976390389529L;
+
+    /**
+     * Whether forwarding is enabled for this user.
+     */
+    private boolean forwarding;
+
+    /**
+     * The mail address to which this user's email is forwarded.
+     */
+    private MailAddress forwardingDestination;
+
+    /**
+     * Is this user an alias for another username on the system.
+     */
+    private boolean aliasing;
+
+
+    /**
+     * The user name that this user name is aliasing.
+     */
+    private String alias;
+
+    public DefaultJamesUser(String name, String alg) {
+        super(name, alg);
+        initialize();
+    }
+
+    public DefaultJamesUser(String name, String passwordHash, String hashAlg) {
+        super(name, passwordHash, hashAlg);
+        initialize();
+    }
+
+
+    /**
+     * Initializes default values for local fields.
+     */
+    public void initialize() {
+        forwarding = false;
+        forwardingDestination = null;
+        aliasing = false;
+        alias = "";
+    }
+
+    /**
+     * @see org.apache.james.services.JamesUser#setForwarding(boolean)
+     */
+    public void setForwarding(boolean forward) {
+        forwarding = forward;
+    }
+
+    /**
+     * @see org.apache.james.services.JamesUser#getForwarding()
+     */
+    public boolean getForwarding() {
+        return forwarding;
+    }
+
+    /**
+     * @see 
org.apache.james.services.JamesUser#setForwardingDestination(org.apache.mailet.MailAddress)
+     */
+    public boolean setForwardingDestination(MailAddress address) {
+        /* TODO: Some verification would be good */
+        forwardingDestination = address;
+        return true;
+    }
+
+    /**
+     * @see org.apache.james.services.JamesUser#getForwardingDestination()
+     */
+    public MailAddress getForwardingDestination() {
+        return forwardingDestination;
+    }
+
+    /**
+     * @see org.apache.james.services.JamesUser#setAliasing(boolean)
+     */
+    public void setAliasing(boolean alias) {
+        aliasing = alias;
+    }
+
+    /**
+     * @see org.apache.james.services.JamesUser#getAliasing()
+     */
+    public boolean getAliasing() {
+        return aliasing;
+    }
+
+    /**
+     * @see org.apache.james.services.JamesUser#setAlias(java.lang.String)
+     */
+    public boolean setAlias(String address) {
+        /* TODO: Some verification would be good */
+        alias = address;
+        return true;
+    }
+
+    /**
+     * @see org.apache.james.services.JamesUser#getAlias()
+     */
+    public String getAlias() {
+        return alias;
+    }
+}

Added: 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultUser.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultUser.java?rev=599566&view=auto
==============================================================================
--- 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultUser.java
 (added)
+++ 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/DefaultUser.java
 Thu Nov 29 12:08:58 2007
@@ -0,0 +1,120 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+
+
+package org.apache.james.userrepository;
+
+import org.apache.james.security.DigestUtil;
+import org.apache.james.services.User;
+
+import java.io.Serializable;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Implementation of User Interface. Instances of this class do not allow
+ * the the user name to be reset.
+ *
+ *
+ * @version CVS $Revision: 521427 $
+ */
+
+public class DefaultUser implements User, Serializable {
+    
+    private static final long serialVersionUID = 5178048915868531270L;
+    
+    private String userName;
+    private String hashedPassword;
+    private String algorithm ;
+
+    /**
+     * Standard constructor.
+     *
+     * @param name the String name of this user
+     * @param hashAlg the algorithm used to generate the hash of the password
+     */
+    public DefaultUser(String name, String hashAlg) {
+        userName = name;
+        algorithm = hashAlg;
+    }
+
+    /**
+     * Constructor for repositories that are construcing user objects from
+     * separate fields, e.g. databases.
+     *
+     * @param name the String name of this user
+     * @param passwordHash the String hash of this users current password
+     * @param hashAlg the String algorithm used to generate the hash of the
+     * password
+     */
+    public DefaultUser(String name, String passwordHash, String hashAlg) {
+        userName = name;
+        hashedPassword = passwordHash;
+        algorithm = hashAlg;
+    }
+
+    /**
+     * @see org.apache.james.services.User#getUserName()
+     */
+    public String getUserName() {
+        return userName;
+    }
+
+    /**
+     * @see org.apache.james.services.User#verifyPassword(java.lang.String)
+     */
+    public boolean verifyPassword(String pass) {
+        try {
+            String hashGuess = DigestUtil.digestString(pass, algorithm);
+            return hashedPassword.equals(hashGuess);
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new RuntimeException("Security error: " + nsae);
+        }
+    }
+
+    /**
+     * @see org.apache.james.services.User#setPassword(java.lang.String)
+     */
+    public boolean setPassword(String newPass) {
+        try {
+            hashedPassword = DigestUtil.digestString(newPass, algorithm);
+            return true;
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new RuntimeException("Security error: " + nsae);
+        }
+    }
+
+    /**
+     * Method to access hash of password
+     *
+     * @return the String of the hashed Password
+     */
+    protected String getHashedPassword() {
+        return hashedPassword;
+    }
+
+    /**
+     * Method to access the hashing algorithm of the password.
+     *
+     * @return the name of the hashing algorithm used for this user's password
+     */
+    protected String getHashAlgorithm() {
+        return algorithm;
+    }
+}

Added: 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersFileRepository.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersFileRepository.java?rev=599566&view=auto
==============================================================================
--- 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersFileRepository.java
 (added)
+++ 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersFileRepository.java
 Thu Nov 29 12:08:58 2007
@@ -0,0 +1,295 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+
+
+package org.apache.james.userrepository;
+
+import org.apache.avalon.cornerstone.services.store.ObjectRepository;
+import org.apache.avalon.cornerstone.services.store.Store;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.james.services.User;
+import org.apache.james.userrepository.AbstractUsersRepository;
+import org.apache.james.userrepository.DefaultJamesUser;
+
+
+import java.util.Iterator;
+
+/**
+ * Implementation of a Repository to store users on the File System.
+ *
+ * Requires a configuration element in the .conf.xml file of the form:
+ *  <repository destinationURL="file://path-to-root-dir-for-repository"
+ *              type="USERS"
+ *              model="SYNCHRONOUS"/>
+ * Requires a logger called UsersRepository.
+ *
+ *
+ * @version CVS $Revision: 521427 $
+ *
+ */
+public class UsersFileRepository
+    extends AbstractUsersRepository
+    implements Configurable, Serviceable, Initializable {
+ 
+    /**
+     * Whether 'deep debugging' is turned on.
+     */
+    protected static boolean DEEP_DEBUG = false;
+
+    private Store store;
+    private ObjectRepository objectRepository;
+    private static String urlSeparator = "/"; 
+
+    /**
+     * The destination URL used to define the repository.
+     */
+    private String destination;
+
+    /**
+     * Set the Store
+     * 
+     * @param store the Store
+     */
+    public void setStore(Store store) {
+        this.store = store;
+    }
+
+    /**
+     * @see 
org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
+     */
+    public void service( final ServiceManager componentManager )
+        throws ServiceException {
+
+        try {
+            setStore((Store)componentManager.lookup( Store.ROLE ));
+        } catch (Exception e) {
+            final String message = "Failed to retrieve Store component:" + 
e.getMessage();
+            getLogger().error( message, e );
+            throw new ServiceException ("", message, e );
+        }
+    }
+
+    /**
+     * @see 
org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
+     */
+    public void configure( final Configuration configuration )
+        throws ConfigurationException {
+        super.configure(configuration);
+        destination = configuration.getChild( "destination" ).getAttribute( 
"URL" );
+
+        if (!destination.endsWith(urlSeparator)) {
+            destination += urlSeparator;
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize()
+        throws Exception {
+
+        try {
+            //prepare Configurations for object and stream repositories
+            final DefaultConfiguration objectConfiguration
+                = new DefaultConfiguration( "repository",
+                                            
"generated:UsersFileRepository.compose()" );
+
+            objectConfiguration.setAttribute( "destinationURL", destination );
+            objectConfiguration.setAttribute( "type", "OBJECT" );
+            objectConfiguration.setAttribute( "model", "SYNCHRONOUS" );
+
+            objectRepository = (ObjectRepository)store.select( 
objectConfiguration );
+            if (getLogger().isDebugEnabled()) {
+                StringBuffer logBuffer =
+                    new StringBuffer(192)
+                            .append(this.getClass().getName())
+                            .append(" created in ")
+                            .append(destination);
+                getLogger().debug(logBuffer.toString());
+            }
+        } catch (Exception e) {
+            if (getLogger().isErrorEnabled()) {
+                getLogger().error("Failed to initialize repository:" + 
e.getMessage(), e );
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * @see org.apache.james.services.UsersRepository#list()
+     */
+    public Iterator list() {
+        return objectRepository.list();
+    }
+
+    /**
+     * @see 
org.apache.james.userrepository.AbstractUsersRepository#doAddUser(org.apache.james.services.User)
+     */
+    protected void doAddUser(User user) {
+        try {
+            objectRepository.put(user.getUserName(), user);
+        } catch (Exception e) {
+            throw new RuntimeException("Exception caught while storing user: " 
+ e );
+        }
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#addUser(java.lang.String, 
java.lang.String)
+     */
+    public boolean addUser(String username, String password) {
+        User newbie = new DefaultJamesUser(username, "SHA");
+        newbie.setPassword(password);
+        return addUser(newbie);
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#getUserByName(java.lang.String)
+     */
+    public synchronized User getUserByName(String name) {
+        if (ignoreCase) {
+            name = getRealName(name);
+            if (name == null ) {
+                return null;
+            }
+        }
+        if (contains(name)) {
+            try {
+                return (User)objectRepository.get(name);
+            } catch (Exception e) {
+                throw new RuntimeException("Exception while retrieving user: "
+                                           + e.getMessage());
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#getUserByNameCaseInsensitive(java.lang.String)
+     */
+    public User getUserByNameCaseInsensitive(String name) {
+        String realName = getRealName(name, true);
+        if (realName == null ) {
+            return null;
+        }
+        return getUserByName(realName);
+    }
+
+    /**
+     * Return the real name, given the ignoreCase boolean parameter
+     */
+    public String getRealName(String name, boolean ignoreCase) {
+        if (ignoreCase) {
+            Iterator it = list();
+            while (it.hasNext()) {
+                String temp = (String) it.next();
+                if (name.equalsIgnoreCase(temp)) {
+                    return temp;
+                }
+            }
+            return null;
+        } else {
+            return objectRepository.containsKey(name) ? name : null;
+        }
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#getRealName(java.lang.String)
+     */
+    public String getRealName(String name) {
+        return getRealName(name, ignoreCase);
+    }
+    
+    /**
+     * @see 
org.apache.james.userrepository.AbstractUsersRepository#doUpdateUser(org.apache.james.services.User)
+     */
+    public void doUpdateUser(User user) {
+        try {
+            objectRepository.put(user.getUserName(), user);
+        } catch (Exception e) {
+            throw new RuntimeException("Exception caught while storing user: "
+                    + e);
+        }
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#removeUser(java.lang.String)
+     */
+    public synchronized void removeUser(String name) {
+        objectRepository.remove(name);
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#contains(java.lang.String)
+     */
+    public boolean contains(String name) {
+        if (ignoreCase) {
+            return containsCaseInsensitive(name);
+        } else {
+            return objectRepository.containsKey(name);
+        }
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#containsCaseInsensitive(java.lang.String)
+     */
+    public boolean containsCaseInsensitive(String name) {
+        Iterator it = list();
+        while (it.hasNext()) {
+            if (name.equalsIgnoreCase((String)it.next())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @see org.apache.james.services.UsersRepository#test(java.lang.String, 
java.lang.String)
+     */
+    public boolean test(String name, String password) {
+        User user;
+        try {
+            user = getUserByName(name);
+            if (user == null) return false;
+        } catch (Exception e) {
+            throw new RuntimeException("Exception retrieving User" + e);
+        }
+        return user.verifyPassword(password);
+    }
+
+    /**
+     * @see org.apache.james.services.UsersRepository#countUsers()
+     */
+    public int countUsers() {
+        int count = 0;
+        for (Iterator it = list(); it.hasNext(); it.next()) {
+            count++;
+        }
+        return count;
+    }
+
+}

Added: 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersLDAPRepository.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersLDAPRepository.java?rev=599566&view=auto
==============================================================================
--- 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersLDAPRepository.java
 (added)
+++ 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/UsersLDAPRepository.java
 Thu Nov 29 12:08:58 2007
@@ -0,0 +1,786 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+
+
+package org.apache.james.userrepository;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.james.services.User;
+import org.apache.james.userrepository.AbstractUsersRepository;
+import org.apache.james.userrepository.DefaultUser;
+
+import javax.naming.AuthenticationException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Implementation of a Repository to store users.
+ *
+ * This clas is a dummy for the proposal!
+ *
+ * TODO: Check for aliases (mail attribute) 
+ * 
+ * @version This is $Revision: 521427 $
+ */
+public class UsersLDAPRepository
+    extends AbstractUsersRepository
+    implements Configurable, Initializable{
+
+    private DirContext ctx;
+
+    private String LDAPHost;
+    private String rootNodeDN;
+    private String rootURL;
+    private String serverRDN;
+    private String baseNodeDN;
+    private String baseURL;
+    private String mailAddressAttr;
+    private String identAttr;
+    private String authType;
+    private String principal;
+    private String password;
+    private String usersDomain;
+    private String membersAttr;
+    private boolean manageGroupAttr;
+    private String groupAttr;
+    private boolean managePasswordAttr;
+    private String passwordAttr;
+    private SearchControls searchControls = new SearchControls();
+
+    /**
+     * @see 
org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        super.configure(conf);
+
+        //TODO: Take care of baseNodeDN
+        LDAPHost = conf.getChild("LDAPServer").getValue();
+        usersDomain = conf.getChild("domain").getValue("localhost");
+        rootNodeDN = conf.getChild("LDAPRoot").getValue();
+        serverRDN = conf.getChild("ThisServerRDN").getValue();
+        mailAddressAttr
+            = conf.getChild("MailAddressAttribute").getValue();
+        identAttr = conf.getChild("IdentityAttribute").getValue();
+        authType = conf.getChild("AuthenticationType").getValue();
+        principal = conf.getChild("Principal").getValue();
+        password = conf.getChild("Password").getValue();
+
+        membersAttr = conf.getChild("MembersAttribute").getValue();
+        manageGroupAttr = 
conf.getChild("ManageGroupAttribute").getValueAsBoolean( false );
+        
+        // Check if groupAttr is needed
+        if (manageGroupAttr == true) {
+            groupAttr = conf.getChild("GroupAttribute").getValue();
+        }
+        
+        managePasswordAttr = 
conf.getChild("ManagePasswordAttribute").getValueAsBoolean( false );
+        
+        // Check if passwordAttr is needed
+        if (managePasswordAttr) {
+            passwordAttr = conf.getChild("PasswordAttribute").getValue();
+        }
+    }
+
+    public void setServerRoot() {
+        StringBuffer serverRootBuffer =
+            new StringBuffer(128)
+                    .append(serverRDN)
+                    .append(", ")
+                    .append(rootNodeDN);
+        this.setBase(serverRootBuffer.toString());
+    }
+
+    public void setBase(String base) {
+        baseNodeDN = base;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+        //setServerRoot();
+        StringBuffer urlBuffer =
+            new StringBuffer(128)
+                    .append(LDAPHost)
+                    .append("/");
+        rootURL = urlBuffer.toString() + rootNodeDN;
+        baseURL = urlBuffer.toString(); // + baseNodeDN;
+
+        getLogger().info("Creating initial context from " + baseURL);
+
+        Hashtable env = new Hashtable();
+        env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
+                "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(javax.naming.Context.PROVIDER_URL, baseURL);
+        
+        env.put(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
+        env.put(javax.naming.Context.SECURITY_PRINCIPAL, principal);
+        env.put(javax.naming.Context.SECURITY_CREDENTIALS, password);
+        
+        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+
+        ctx = new InitialDirContext(env); // Could throw a NamingExcpetion
+
+
+        getLogger().info("Initial context initialized from " + baseURL);
+    }
+
+
+
+    public String getChildDestination(String childName) {
+
+        String destination = null;
+        String filter = "cn=" + childName;
+        SearchControls ctls = new SearchControls();
+
+        try {
+
+            NamingEnumeration result  = ctx.search("", filter, ctls);
+
+            if (result.hasMore()) {
+                StringBuffer destinationBuffer =
+                    new StringBuffer(128)
+                            .append("cn=")
+                            .append(childName)
+                            .append(", ")
+                            .append(baseNodeDN);
+                destination = destinationBuffer.toString();
+                getLogger().info("Pre-exisisting LDAP node: " + destination);
+            } else {
+                Attributes attrs = new BasicAttributes(true);
+                Attribute objclass = new BasicAttribute("objectclass");
+                objclass.add("top");
+                objclass.add("rfc822MailGroup");
+                attrs.put(objclass);
+                Attribute cname = new BasicAttribute("cn");
+                cname.add(childName);
+                attrs.put(cname);
+                Attribute owner = new BasicAttribute("owner");
+                owner.add("JAMES-unassigned");
+                attrs.put(owner);
+/*
+                
ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
+                ctx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, 
principal);
+                
ctx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
+*/
+                ctx.createSubcontext("cn=" + childName, attrs);
+//                
ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
+
+                StringBuffer destinationBuffer =
+                    new StringBuffer(128)
+                            .append("cn=")
+                            .append(childName)
+                            .append(", ")
+                            .append(baseNodeDN);
+                destination = destinationBuffer.toString();
+                getLogger().info("Created new LDAP node: " + destination);
+            }
+        } catch (NamingException e) {
+            getLogger().error("Problem with child nodes " + e.getMessage(), e);
+        }
+
+        return destination;
+    }
+
+    /**
+     * List users in repository.
+     *
+     * @return Iterator over a collection of Strings, each being one user in 
the repository.
+     */
+    public Iterator list() {
+        return getUsers().iterator();
+    }
+    
+    /**
+     * Update the repository with the specified user object.  Unsupported for
+     * this user repository type.
+     *
+     * @return false
+     */
+    public boolean addUser(User user) {
+        return false;
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#getUserByName(java.lang.String)
+     */
+    public  User getUserByName(String name) {
+        return new DefaultUser("dummy", "dummy");
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#getUserByNameCaseInsensitive(java.lang.String)
+     */
+    public User getUserByNameCaseInsensitive(String name) {
+        return getUserByName(name);
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#containsCaseInsensitive(java.lang.String)
+     */
+    public boolean containsCaseInsensitive(String name) {
+        return getUsers().contains(name);
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#getRealName(java.lang.String)
+     */
+    public String getRealName(String name) {
+        return getRealName(name, ignoreCase);
+    }
+    
+    /**
+     * Return the real name, given the ignoreCase boolean parameter
+     */
+    public String getRealName(String name, boolean ignoreCase) {
+        Iterator it = list();
+        while (it.hasNext()) {
+            String temp = (String) it.next();     
+            if (ignoreCase) {
+                if (name.equalsIgnoreCase(temp)) {
+                    return temp;
+                }
+            } else {
+                if (name.equals(temp)) {
+                    return temp;
+                }     
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#updateUser(org.apache.james.services.User)
+     */
+    public boolean updateUser(User user) {
+        return false;
+    }
+    
+    /**
+     * @see 
org.apache.james.services.UsersRepository#addUser(java.lang.String, 
java.lang.String)
+     */
+    public boolean addUser(String username, String password) {
+        if (!contains(username)) {
+            addUser(username, password);
+            return contains(username);
+        } else {
+            return false;
+        }
+    }
+
+    private void addGroupToUser(String userName) {
+        String[] attrIDs = {membersAttr};
+
+        Hashtable env = new Hashtable();
+        env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, 
"com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(javax.naming.Context.PROVIDER_URL, rootURL);
+
+        DirContext rootCtx = null;
+        try {
+            rootCtx = new InitialDirContext(env);
+
+            String[] returnAttrs = {groupAttr};
+            SearchControls ctls = new SearchControls();
+            ctls.setReturningAttributes(attrIDs);
+            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            StringBuffer filterBuffer =
+                new StringBuffer(128)
+                        .append(mailAddressAttr)
+                        .append("=")
+                        .append(userName)
+                        .append("@")
+                        .append(usersDomain);
+            String filter = filterBuffer.toString();
+
+            NamingEnumeration enumeration  = rootCtx.search("", filter, ctls);
+
+            if (enumeration.hasMore()) { // ie User is in Directory
+                SearchResult newSr = (SearchResult)enumeration.next();
+                String userDN = newSr.getName();
+                Attribute servers = rootCtx.getAttributes(userDN, 
returnAttrs).get(groupAttr);
+
+
+                if (servers != null && servers.contains(baseNodeDN)) {//server 
already registered for user
+                    getLogger().info(baseNodeDN + " already in user's Groups. 
" );
+                    //System.out.println(baseNodeDN + " already in user's 
Groups. ");
+
+                } else {
+/*
+                    
rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, 
authType);
+                    
rootCtx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, principal);
+                    
rootCtx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
+*/
+                    rootCtx.modifyAttributes(userDN, DirContext.ADD_ATTRIBUTE, 
new BasicAttributes(groupAttr, baseNodeDN, true));
+
+                    
//rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, 
"none");
+                    getLogger().info(baseNodeDN + " added to user's groups ");
+                    //System.out.println(baseNodeDN + " added to users' groups 
");
+
+                }
+
+            } else {
+                StringBuffer infoBuffer =
+                    new StringBuffer(64)
+                            .append("User ")
+                            .append(userName)
+                            .append(" not in directory.");
+                getLogger().info(infoBuffer.toString());
+                // System.out.println(infoBuffer.toString());
+
+            }
+        } catch (NamingException e) {
+            getLogger().error("Problem adding group to user " + userName);
+            //System.out.println("Problem adding group to user " + userName);
+            //System.out.println(e.getMessage());
+            //e.printStackTrace();
+        } finally {
+            closeDirContext(rootCtx);
+        }
+    }
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#removeUser(java.lang.String)
+     */
+    public synchronized void removeUser(String userName) {
+        String[] attrIDs = {membersAttr};
+
+        try {
+            Attribute members = ctx.getAttributes("", 
attrIDs).get(membersAttr);
+            if (members == null) {
+                System.out.println("UsersLDAPRepository - Null list 
attribute.");
+
+            } else  if (!members.contains(userName)) {//user not here
+                getLogger().info(userName + " missing from mailGroup. ");
+                //System.out.println(userName + " missing from mailGroup. ");
+
+            } else {
+                // First, remove username from mailGroup at baseNode
+/*
+                
ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
+                ctx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, 
principal);
+                
ctx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
+*/
+                ModificationItem[] mods = new ModificationItem[1];
+                mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, 
new BasicAttribute(membersAttr, userName));
+
+                ctx.modifyAttributes("", mods);
+
+
+//                
ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
+                getLogger().info(userName + " removed from mailGroup. ");
+                //System.out.println(userName + " removed from mailGroup. ");
+            }
+        } catch (NamingException e) {
+            StringBuffer exceptionBuffer =
+                new StringBuffer(256)
+                        .append("Problem removing user ")
+                        .append(userName)
+                        .append(": ")
+                        .append(e);
+            getLogger().error(exceptionBuffer.toString());
+            //System.out.println("Problem removing user " + userName);
+            //System.out.println(e.getMessage());
+            //e.printStackTrace();
+        }
+        if (manageGroupAttr) {
+            removeGroupFromUser(userName);
+        }
+
+        if (managePasswordAttr) {
+            // not yet implemented
+        }
+
+    }
+
+    public void removeGroupFromUser(String userName) {
+
+        Hashtable env = new Hashtable();
+        env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, 
"com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(javax.naming.Context.PROVIDER_URL, rootURL);
+
+
+        DirContext rootCtx = null;
+        try {
+            rootCtx = new InitialDirContext(env);
+
+            // Find directory entry
+            String[] returnAttrs = {groupAttr};
+            SearchControls ctls = new SearchControls();
+            ctls.setReturningAttributes(returnAttrs);
+            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            StringBuffer filterBuffer =
+                new StringBuffer(128)
+                        .append(mailAddressAttr)
+                        .append("=")
+                        .append(userName)
+                        .append("@")
+                        .append(usersDomain);
+            String filter = filterBuffer.toString();
+
+            NamingEnumeration enumeration  = rootCtx.search("", filter, ctls);
+
+            if (enumeration.hasMore()) { // ie User is in Directory
+                SearchResult newSr = (SearchResult)enumeration.next();
+                String userDN = newSr.getName();
+
+                System.out.println("Found user entry: " + userDN);
+
+                Attribute servers = rootCtx.getAttributes(userDN, 
returnAttrs).get(groupAttr);
+                if (servers == null) { //should not happen
+                    getLogger().info("GroupAttribute missing from user: " + 
userName);
+                    // System.out.println("GroupAttribute missing from user: " 
+ userName );
+
+                } else if (!servers.contains(baseNodeDN)) {//server not 
registered for user
+                    getLogger().info(baseNodeDN + " missing from users' 
Groups. " );
+                    //System.out.println(baseNodeDN + " missing from users' 
Groups. ");
+
+                } else {
+/*
+                    
rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, 
authType);
+                    
rootCtx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, principal);
+                    
rootCtx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
+*/
+                    ModificationItem[] mods = new ModificationItem[1];
+                    mods[0] = new 
ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute(groupAttr, 
baseNodeDN));
+
+                    rootCtx.modifyAttributes(userDN, mods);
+
+                    //rootCtx.modifyAttributes(userDN, 
DirContext.REPLACE_ATTRIBUTE, changes);
+
+//                    
rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
+                    getLogger().info(baseNodeDN + " removed from users' groups 
" );
+                    //System.out.println(baseNodeDN + " removed from users' 
groups ");
+
+                }
+
+            } else {
+                StringBuffer infoBuffer =
+                    new StringBuffer(64)
+                            .append("User ")
+                            .append(userName)
+                            .append(" not in directory.");
+                getLogger().info(infoBuffer.toString());
+                //System.out.println(infoBuffer.toString());
+
+            }
+        } catch (NamingException e) {
+            StringBuffer exceptionBuffer =
+                new StringBuffer(256)
+                        .append("Problem removing user ")
+                        .append(userName)
+                        .append(e);
+            getLogger().error(exceptionBuffer.toString());
+            //System.out.println("Problem removing user " + userName);
+            //System.out.println(e.getMessage());
+            //e.printStackTrace();
+        } finally {
+            closeDirContext(rootCtx);
+            rootCtx = null;
+        }
+    }
+
+
+    /**
+     * @see 
org.apache.james.services.UsersRepository#contains(java.lang.String)
+     */
+    public boolean contains(String name) {
+        boolean found = false;
+        if (ignoreCase) {
+            if(containsCaseInsensitive(name)) {
+                found = true;
+            }
+        } else {
+           Iterator it = list();
+           
+           while (it.hasNext()) {
+               if (name.equals(it.next())) {
+                   found = true;
+               }
+           }
+        }
+        
+        if(found) {
+            StringBuffer infoBuffer =
+                new StringBuffer(64)
+                        .append("Found ")
+                        .append(name)
+                        .append(" in mailGroup. ");
+            getLogger().info(infoBuffer.toString());
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * @see org.apache.james.services.UsersRepository#test(java.lang.String, 
java.lang.String)
+     */
+    public boolean test(String name, String testPassword) {
+        boolean result = false;
+        boolean foundFlag = false;
+        String userDN = null;
+
+        try {
+            String[] returnAttrs = {identAttr, passwordAttr};
+            SearchControls ctls = new SearchControls();
+            ctls.setReturningAttributes(returnAttrs);
+            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            StringBuffer filterBuffer = 
+                new StringBuffer(128)
+                        .append(mailAddressAttr)
+                        .append("=")
+                        .append(name)
+                        .append("@")
+                        .append(usersDomain);
+            String filter = filterBuffer.toString();
+
+            Hashtable env = new Hashtable();
+            env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, 
"com.sun.jndi.ldap.LdapCtxFactory");
+            env.put(javax.naming.Context.PROVIDER_URL, rootURL);
+            DirContext rootCtx = null;
+
+            try {
+                rootCtx = new InitialDirContext(env);
+    
+                NamingEnumeration enumeration  = rootCtx.search("", filter, 
ctls);
+                if (enumeration.hasMore()) { // ie User is in Directory
+                    SearchResult sr = (SearchResult)enumeration.next();
+                    String userRDN = sr.getName();
+                    StringBuffer userDNBuffer =
+                        new StringBuffer(128)
+                                .append(userRDN)
+                                .append(", ")
+                                .append(rootNodeDN);
+                    userDN = userDNBuffer.toString();
+                    foundFlag = true;
+                    //System.out.println("UserDN is : " + userDN);
+                }
+            } finally {
+                closeDirContext(rootCtx);
+            }
+        } catch (Exception e) {
+            StringBuffer exceptionBuffer =
+                new StringBuffer(256)
+                        .append("Problem finding user ")
+                        .append(name)
+                        .append(" for password test.")
+                        .append(e); 
+            getLogger().error(exceptionBuffer.toString());
+            //e.getMessage();
+            //e.printStackTrace();
+        }
+
+        if (foundFlag) { // ie User is in Directory
+            Hashtable env2 = new Hashtable();
+            env2.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, 
"com.sun.jndi.ldap.LdapCtxFactory");
+            env2.put(javax.naming.Context.PROVIDER_URL, rootURL);
+            env2.put(javax.naming.Context.SECURITY_AUTHENTICATION, "simple");
+            env2.put(javax.naming.Context.SECURITY_PRINCIPAL, userDN);
+            env2.put(javax.naming.Context.SECURITY_CREDENTIALS, testPassword);
+            //System.out.println("Creating initial context from " + baseURL);
+
+            DirContext testCtx = null;
+            try {
+                testCtx = new InitialDirContext(env2);
+                result = true;
+
+            } catch (AuthenticationException ae) {
+                result = false;
+                StringBuffer exceptionBuffer =
+                    new StringBuffer(256)
+                            .append("Attempt to authenticate with incorrect 
password for ")
+                            .append(name)
+                            .append(" : ")
+                            .append(ae); 
+                getLogger().error(exceptionBuffer.toString());
+                //System.out.println(exceptionBuffer.toString());
+                //System.out.println(ae.getMessage());
+                //ae.printStackTrace();
+            } catch (Exception e) {
+                StringBuffer exceptionBuffer =
+                    new StringBuffer(256)
+                            .append("Problem checking password for ")
+                            .append(name)
+                            .append(" : ")
+                            .append(e); 
+                getLogger().error(exceptionBuffer.toString());
+                //System.out.println(exceptionBuffer.toString());
+                //System.out.println(e.getMessage());
+                //e.printStackTrace();
+            } finally {
+                closeDirContext(testCtx);
+            }
+        }
+        return result;
+
+    }
+
+    /**
+     * @see org.apache.james.services.UsersRepository#countUsers()
+     */
+    public int countUsers() {
+        return getUsers().size();
+    }
+
+    /**
+     * Disposes of all open directory contexts
+     *
+     * @throws Exception if an error is encountered during shutdown
+     */
+    public void dispose() throws Exception {
+        closeDirContext(ctx);
+        ctx = null;
+    }
+
+    private void closeDirContext(DirContext ctx) {
+        try {
+            if (ctx != null) {
+                ctx.close();
+            }
+        } catch (NamingException ne) {
+            getLogger().warn("UsersLDAPRepository: Unexpected exception 
encountered while closing directory context: " + ne);
+        }
+    }
+
+
+    /**
+     * Adds userName to the MemberAttribute (specified in conf.xml) of this
+     * node.
+     * If ManageGroupAttribute (conf.xml) is TRUE then calls addGroupToUser.
+     */
+    protected void doAddUser(User user) {
+        String userName = user.getUserName();
+        
+        String[] attrIDs = {membersAttr};
+
+        // First, add username to mailGroup at baseNode
+
+        try {
+            Attribute members = ctx.getAttributes("", 
attrIDs).get(membersAttr);
+
+
+            if (members != null && members.contains(userName)) {//user already 
here
+                StringBuffer infoBuffer =
+                    new StringBuffer(64)
+                            .append("Found ")
+                            .append(userName)
+                            .append(" already in mailGroup. ");
+                getLogger().info(infoBuffer.toString());
+                //System.out.println(infoBuffer.toString());
+
+            } else {
+             /*
+            ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, 
authType);
+                ctx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, 
principal);
+                
ctx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
+*/
+                ModificationItem[] mods = new ModificationItem[1];
+                mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new 
BasicAttribute(membersAttr, userName));
+
+                ctx.modifyAttributes("", mods);
+
+//                
ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
+                StringBuffer infoBuffer =
+                    new StringBuffer(128)
+                            .append(userName)
+                            .append(" added to mailGroup ")
+                            .append(baseNodeDN);
+                getLogger().info(infoBuffer.toString());
+                //System.out.println(infoBuffer.toString());
+            }
+        } catch (NamingException e) {
+            StringBuffer exceptionBuffer =
+                new StringBuffer(256)
+                        .append("Problem adding user ")
+                        .append(userName)
+                        .append(" to: ")
+                        .append(baseNodeDN)
+                        .append(e);
+            getLogger().error(exceptionBuffer.toString());
+        }
+
+        // Add attributes to user objects, if necessary
+
+        if (manageGroupAttr) {
+            addGroupToUser(userName);
+        }
+
+//        if (managePasswordAttr) {
+//            String userPassword = (String) attributes; // Not yet implemented
+//        }
+    }
+
+    protected void doUpdateUser(User user) {
+        // Do nothing
+    }
+    
+    /**
+     * Return a list of all users
+     * 
+     * @return
+     */
+    private List getUsers() {
+        List result = new ArrayList();
+        String filter = mailAddressAttr + "=*";
+
+        try {
+            NamingEnumeration results = ctx.search(rootNodeDN, filter, 
searchControls);
+            
+            while (results != null && results.hasMore()) {
+                Attributes members = ((SearchResult) 
results.next()).getAttributes();
+       
+                if (members != null) {
+
+                    Attribute attr = members.get(identAttr);
+                    if (attr != null) {
+                        NamingEnumeration e = attr.getAll();
+                        while (e.hasMore()) {
+                            result.add(e.next());
+                        }
+                    }
+                }
+            }
+        } catch (NamingException e) {
+            getLogger().error("Problem listing mailboxes. " + e );
+
+        }
+        return result;
+    }
+}
+
+

Added: 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/package.html
URL: 
http://svn.apache.org/viewvc/james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/package.html?rev=599566&view=auto
==============================================================================
--- 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/package.html
 (added)
+++ 
james/server/trunk/user-library/src/main/java/org/apache/james/userrepository/package.html
 Thu Nov 29 12:08:58 2007
@@ -0,0 +1,21 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.    
+-->
+<body>
+<p>Implementations of user repositories for use in James.</p>
+</body>



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to