IPA authentication working.
[lgpl/argeo-commons.git] / org.argeo.enterprise / src / org / argeo / osgi / useradmin / LdifUserAdmin.java
index 8ec967b7007a73c8875e557b6e8ecee6c0305105..b19e9bf4f311da72fc962bb5b411913d05ae57b0 100644 (file)
@@ -8,7 +8,9 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -17,6 +19,7 @@ import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import javax.naming.NameNotFoundException;
 import javax.naming.NamingEnumeration;
 import javax.naming.directory.Attributes;
 import javax.naming.ldap.LdapName;
@@ -37,23 +40,43 @@ public class LdifUserAdmin extends AbstractUserDirectory {
        private SortedMap<LdapName, DirectoryGroup> groups = new TreeMap<LdapName, DirectoryGroup>();
 
        public LdifUserAdmin(String uri, String baseDn) {
-               this(fromUri(uri, baseDn));
+               this(fromUri(uri, baseDn), false);
        }
 
        public LdifUserAdmin(Dictionary<String, ?> properties) {
-               super(properties);
+               this(properties, false);
        }
 
-       public LdifUserAdmin(InputStream in) {
-               super(new Hashtable<String, Object>());
-               load(in);
+       protected LdifUserAdmin(Dictionary<String, ?> properties, boolean scoped) {
+               super(null, properties, scoped);
+       }
+
+       public LdifUserAdmin(URI uri, Dictionary<String, ?> properties) {
+               super(uri, properties, false);
        }
 
        @Override
        protected AbstractUserDirectory scope(User user) {
+               Dictionary<String, Object> credentials = user.getCredentials();
+               String username = (String) credentials.get(SHARED_STATE_USERNAME);
+               if (username == null)
+                       username = user.getName();
+               Object pwdCred = credentials.get(SHARED_STATE_PASSWORD);
+               byte[] pwd = (byte[]) pwdCred;
+               if (pwd != null) {
+                       char[] password = DigestUtils.bytesToChars(pwd);
+                       User directoryUser = (User) getRole(username);
+                       if (!directoryUser.hasCredential(null, password))
+                               throw new UserDirectoryException("Invalid credentials");
+               } else {
+                       throw new UserDirectoryException("Password is required");
+               }
                Dictionary<String, Object> properties = cloneProperties();
                properties.put(UserAdminConf.readOnly.name(), "true");
-               return new LdifUserAdmin(properties);
+               LdifUserAdmin scopedUserAdmin = new LdifUserAdmin(properties, true);
+               scopedUserAdmin.groups = Collections.unmodifiableSortedMap(groups);
+               scopedUserAdmin.users = Collections.unmodifiableSortedMap(users);
+               return scopedUserAdmin;
        }
 
        private static Dictionary<String, Object> fromUri(String uri, String baseDn) {
@@ -64,13 +87,15 @@ public class LdifUserAdmin extends AbstractUserDirectory {
        }
 
        public void init() {
+
                try {
-                       if (getUri().getScheme().equals("file")) {
-                               File file = new File(getUri());
+                       URI u = new URI(getUri());
+                       if (u.getScheme().equals("file")) {
+                               File file = new File(u);
                                if (!file.exists())
                                        return;
                        }
-                       load(getUri().toURL().openStream());
+                       load(u.toURL().openStream());
                } catch (Exception e) {
                        throw new UserDirectoryException("Cannot open URL " + getUri(), e);
                }
@@ -125,10 +150,10 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                                objectClasses: while (objectClasses.hasMore()) {
                                        String objectClass = objectClasses.next().toString();
                                        // System.out.println(" " + objectClass);
-                                       if (objectClass.equals(inetOrgPerson.name())) {
+                                       if (objectClass.toLowerCase().equals(inetOrgPerson.name().toLowerCase())) {
                                                users.put(key, new LdifUser(this, key, attributes));
                                                break objectClasses;
-                                       } else if (objectClass.equals(getGroupObjectClass())) {
+                                       } else if (objectClass.toLowerCase().equals(getGroupObjectClass().toLowerCase())) {
                                                groups.put(key, new LdifGroup(this, key, attributes));
                                                break objectClasses;
                                        }
@@ -142,25 +167,24 @@ public class LdifUserAdmin extends AbstractUserDirectory {
        public void destroy() {
                if (users == null || groups == null)
                        throw new UserDirectoryException("User directory " + getBaseDn() + " is already destroyed");
-               users.clear();
                users = null;
-               groups.clear();
                groups = null;
        }
 
-       protected DirectoryUser daoGetRole(LdapName key) {
+       @Override
+       protected DirectoryUser daoGetRole(LdapName key) throws NameNotFoundException {
                if (groups.containsKey(key))
                        return groups.get(key);
                if (users.containsKey(key))
                        return users.get(key);
-               return null;
+               throw new NameNotFoundException(key + " not persisted");
        }
 
+       @Override
        protected Boolean daoHasRole(LdapName dn) {
                return users.containsKey(dn) || groups.containsKey(dn);
        }
 
-       @SuppressWarnings("unchecked")
        protected List<DirectoryUser> doGetRoles(Filter f) {
                ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
                if (f == null) {
@@ -168,13 +192,6 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                        res.addAll(groups.values());
                } else {
                        for (DirectoryUser user : users.values()) {
-                               // System.out.println("\n" + user.getName());
-                               // Dictionary<String, Object> props = user.getProperties();
-                               // for (Enumeration<String> keys = props.keys(); keys
-                               // .hasMoreElements();) {
-                               // String key = keys.nextElement();
-                               // System.out.println(" " + key + "=" + props.get(key));
-                               // }
                                if (f.match(user.getProperties()))
                                        res.add(user);
                        }