Fix LDIF user directory scoping
[lgpl/argeo-commons.git] / org.argeo.enterprise / src / org / argeo / osgi / useradmin / LdifUserAdmin.java
index 4ebca4fcff3a0c3b95ee27d5a16f107173ed8b14..8668152d6d7aac69a77c20d879cc92b75e10b539 100644 (file)
@@ -1,14 +1,16 @@
 package org.argeo.osgi.useradmin;
 
-import static org.argeo.naming.LdapObjs.inetOrgPerson;
 import static org.argeo.naming.LdapAttrs.objectClass;
+import static org.argeo.naming.LdapObjs.inetOrgPerson;
 
 import java.io.File;
 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;
@@ -26,6 +29,7 @@ import org.argeo.naming.LdifParser;
 import org.argeo.naming.LdifWriter;
 import org.osgi.framework.Filter;
 import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
 
 /**
  * A user admin based on a LDIF files. Requires a {@link TransactionManager} and
@@ -40,12 +44,36 @@ public class LdifUserAdmin extends AbstractUserDirectory {
        }
 
        public LdifUserAdmin(Dictionary<String, ?> properties) {
-               super(properties);
+               super(null, properties);
        }
 
-       public LdifUserAdmin(InputStream in) {
-               super(new Hashtable<String, Object>());
-               load(in);
+       public LdifUserAdmin(URI uri, Dictionary<String, ?> properties) {
+               super(uri, properties);
+       }
+
+       @SuppressWarnings("unchecked")
+       @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");
+               LdifUserAdmin scopedUserAdmin = new LdifUserAdmin(properties);
+               scopedUserAdmin.groups = Collections.unmodifiableSortedMap(groups);
+               scopedUserAdmin.users = Collections.unmodifiableSortedMap(users);
+               return scopedUserAdmin;
        }
 
        private static Dictionary<String, Object> fromUri(String uri, String baseDn) {
@@ -134,20 +162,20 @@ 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);
        }
@@ -160,13 +188,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);
                        }