LDIF user admin read-only features working (adding properties and credentials)
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 25 Aug 2015 08:54:49 +0000 (08:54 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 25 Aug 2015 08:54:49 +0000 (08:54 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8338 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/AttributeDictionary.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifGroup.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUser.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java

index c2d5b31f0d7b260f13e14c43e030392a0183fa98..d2a6c94c144d7663b735a5b9ed44df81652fa735 100644 (file)
@@ -5,6 +5,8 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
 import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
@@ -15,11 +17,14 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
        public void testBasicUserAdmin() {
                LdifUserAdmin userAdmin = new LdifUserAdmin(getClass()
                                .getResourceAsStream("basic.ldif"));
+
+               // users
                User rootUser = (User) userAdmin.getRole(ROOT_USER_DN);
                assertNotNull(rootUser);
                User demoUser = (User) userAdmin.getRole(DEMO_USER_DN);
                assertNotNull(demoUser);
 
+               // groups
                Group adminGroup = (Group) userAdmin.getRole(ADMIN_GROUP_DN);
                assertNotNull(adminGroup);
                Role[] members = adminGroup.getMembers();
@@ -39,5 +44,15 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
                assertTrue(rootRoles.contains(ROOT_USER_DN));
                assertTrue(rootRoles.contains(ADMIN_GROUP_DN));
                assertTrue(rootRoles.contains(EDITOR_GROUP_DN));
+
+               // properties
+               assertEquals("root@localhost", rootUser.getProperties().get("mail"));
+
+               // credentials
+               byte[] hashedPassword = ("{SHA}" + Base64
+                               .encodeBase64String(DigestUtils.sha1("demo".getBytes())))
+                               .getBytes();
+               assertTrue(rootUser.hasCredential("userpassword", hashedPassword));
+               assertTrue(demoUser.hasCredential("userpassword", hashedPassword));
        }
 }
index 7691d8a94d7dfe4c09e1a89437d7b4a637f53298..99e5edb6292dc821b0f6d5fd167179f6681f4b19 100644 (file)
@@ -1,44 +1,90 @@
 package org.argeo.osgi.useradmin;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
 
+import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttribute;
 
-class AttributeDictionary extends Dictionary {
+class AttributeDictionary extends Dictionary<String,Object> {
        private final Attributes attributes;
+       private final List<String> effectiveKeys = new ArrayList<String>();
+       private final List<String> attrFilter;
+       private final Boolean includeFilter;
 
-       public AttributeDictionary(Attributes attributes) {
+       public AttributeDictionary(Attributes attributes, List<String> attrFilter,
+                       Boolean includeFilter) {
                this.attributes = attributes;
+               this.attrFilter = attrFilter;
+               this.includeFilter = includeFilter;
+               try {
+                       NamingEnumeration<String> ids = attributes.getIDs();
+                       while (ids.hasMore()) {
+                               String id = ids.next();
+                               if (includeFilter && attrFilter.contains(id))
+                                       effectiveKeys.add(id);
+                               else if (!includeFilter && !attrFilter.contains(id))
+                                       effectiveKeys.add(id);
+                       }
+               } catch (NamingException e) {
+                       throw new ArgeoUserAdminException(
+                                       "Cannot initialise attribute dictionary", e);
+               }
        }
 
        @Override
        public int size() {
-               return attributes.size();
+               return effectiveKeys.size();
        }
 
        @Override
        public boolean isEmpty() {
-               return attributes.size() == 0;
+               return effectiveKeys.size() == 0;
        }
 
        @Override
        public Enumeration<String> keys() {
-               return attributes.getIDs();
+               return Collections.enumeration(effectiveKeys);
        }
 
        @Override
        public Enumeration<Object> elements() {
-               throw new UnsupportedOperationException();
+               final Iterator<String> it = effectiveKeys.iterator();
+               return new Enumeration<Object>() {
+
+                       @Override
+                       public boolean hasMoreElements() {
+                               return it.hasNext();
+                       }
+
+                       @Override
+                       public Object nextElement() {
+                               String key = it.next();
+                               try {
+                                       return attributes.get(key).get();
+                               } catch (NamingException e) {
+                                       throw new ArgeoUserAdminException(
+                                                       "Cannot get value for key " + key, e);
+                               }
+                       }
+
+               };
        }
 
        @Override
        public Object get(Object key) {
                try {
-                       return attributes.get(key.toString()).get();
+                       Attribute attr = attributes.get(key.toString());
+                       if (attr == null)
+                               return null;
+                       return attr.get();
                } catch (NamingException e) {
                        throw new ArgeoUserAdminException("Cannot get value for attribute "
                                        + key, e);
@@ -46,10 +92,15 @@ class AttributeDictionary extends Dictionary {
        }
 
        @Override
-       public Object put(Object key, Object value) {
+       public Object put(String key, Object value) {
                if (!(value instanceof String || value instanceof byte[]))
-                       throw new IllegalArgumentException(
-                                       "Value muste be String or byte[]");
+                       throw new IllegalArgumentException("Value must be String or byte[]");
+
+               if (includeFilter && !attrFilter.contains(key))
+                       throw new IllegalArgumentException("Key " + key + " not included");
+               else if (!includeFilter && attrFilter.contains(key))
+                       throw new IllegalArgumentException("Key " + key + " excluded");
+
                try {
                        Attribute attribute = attributes.get(key.toString());
                        attribute = new BasicAttribute(key.toString());
@@ -67,7 +118,20 @@ class AttributeDictionary extends Dictionary {
 
        @Override
        public Object remove(Object key) {
-               throw new UnsupportedOperationException();
-       }
+               if (includeFilter && !attrFilter.contains(key))
+                       throw new IllegalArgumentException("Key " + key + " not included");
+               else if (!includeFilter && attrFilter.contains(key))
+                       throw new IllegalArgumentException("Key " + key + " excluded");
 
+               try {
+                       Attribute attr = attributes.remove(key.toString());
+                       if (attr != null)
+                               return attr.get();
+                       else
+                               return null;
+               } catch (NamingException e) {
+                       throw new ArgeoUserAdminException("Cannot remove attribute " + key,
+                                       e);
+               }
+       }
 }
index 845094820c84e897df2844ce31e83ed8e20d7eac..4154d55a74ffec26983324055449d80ff55eebae 100644 (file)
@@ -79,7 +79,7 @@ public class LdifGroup extends LdifUser implements Group {
                        return new ArrayList<LdapName>();
                try {
                        List<LdapName> roles = new ArrayList<LdapName>();
-                       NamingEnumeration values = memberAttribute.getAll();
+                       NamingEnumeration<?> values = memberAttribute.getAll();
                        while (values.hasMore()) {
                                LdapName dn = new LdapName(values.next().toString());
                                roles.add(dn);
index 379ac23ab2ca6349203655b318b4166efc8e620d..9f378f1510163396fb8ccb2cbcc965e929bb360a 100644 (file)
@@ -1,6 +1,7 @@
 package org.argeo.osgi.useradmin;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Dictionary;
 import java.util.List;
 
@@ -16,9 +17,19 @@ class LdifUser implements User {
        private final LdapName dn;
        private Attributes attributes;
 
+       private final AttributeDictionary properties;
+       private final AttributeDictionary credentials;
+
+       private List<String> credentialAttributes = Arrays
+                       .asList(new String[] { "userpassword" });
+
        LdifUser(LdapName dn, Attributes attributes) {
                this.dn = dn;
                this.attributes = attributes;
+               properties = new AttributeDictionary(attributes, credentialAttributes,
+                               false);
+               credentials = new AttributeDictionary(attributes, credentialAttributes,
+                               true);
        }
 
        @Override
@@ -33,21 +44,25 @@ class LdifUser implements User {
 
        @Override
        public Dictionary<String, Object> getProperties() {
-               if (attributes == null)
-                       throw new ArgeoUserAdminException(
-                                       "Must be loaded from user admin service");
-               return new AttributeDictionary(attributes);
+               return properties;
        }
 
        @Override
        public Dictionary<String, Object> getCredentials() {
-               // TODO Auto-generated method stub
-               return null;
+               return credentials;
        }
 
        @Override
        public boolean hasCredential(String key, Object value) {
-               // TODO Auto-generated method stub
+               Object storedValue = getCredentials().get(key);
+               if (storedValue == null || value == null)
+                       return false;
+               if (!(value instanceof String || value instanceof byte[]))
+                       return false;
+               if (storedValue instanceof String && value instanceof String)
+                       return storedValue.equals(value);
+               if (storedValue instanceof byte[] && value instanceof byte[])
+                       return Arrays.equals((byte[]) storedValue, (byte[]) value);
                return false;
        }
 
@@ -79,5 +94,4 @@ class LdifUser implements User {
        public String toString() {
                return dn.toString();
        }
-
 }
index 440e93d9d1f3fc9fcb3b28049ec69609a795376a..8cc7cb39581f5a8f4d50c47919e828969369fb31 100644 (file)
@@ -25,8 +25,8 @@ public class LdifUserAdmin implements UserAdmin {
                        SortedMap<LdapName, Attributes> allEntries = ldifParser.read(in);
                        for (LdapName key : allEntries.keySet()) {
                                Attributes attributes = allEntries.get(key);
-                               NamingEnumeration objectClasses = attributes.get("objectClass")
-                                               .getAll();
+                               NamingEnumeration<?> objectClasses = attributes.get(
+                                               "objectClass").getAll();
                                objectClasses: while (objectClasses.hasMore()) {
                                        String objectClass = objectClasses.next().toString();
                                        if (objectClass.equals("inetOrgPerson")) {