From 270c84f092b77b6f101a742cff565d29ee756011 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 25 Aug 2015 08:54:49 +0000 Subject: [PATCH] LDIF user admin read-only features working (adding properties and credentials) git-svn-id: https://svn.argeo.org/commons/trunk@8338 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../osgi/useradmin/LdifUserAdminTest.java | 15 ++++ .../osgi/useradmin/AttributeDictionary.java | 88 ++++++++++++++++--- .../org/argeo/osgi/useradmin/LdifGroup.java | 2 +- .../org/argeo/osgi/useradmin/LdifUser.java | 30 +++++-- .../argeo/osgi/useradmin/LdifUserAdmin.java | 4 +- 5 files changed, 116 insertions(+), 23 deletions(-) diff --git a/org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java b/org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java index c2d5b31f0..d2a6c94c1 100644 --- a/org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java +++ b/org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java @@ -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)); } } diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/AttributeDictionary.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/AttributeDictionary.java index 7691d8a94..99e5edb62 100644 --- a/org.argeo.security.core/src/org/argeo/osgi/useradmin/AttributeDictionary.java +++ b/org.argeo.security.core/src/org/argeo/osgi/useradmin/AttributeDictionary.java @@ -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 { private final Attributes attributes; + private final List effectiveKeys = new ArrayList(); + private final List attrFilter; + private final Boolean includeFilter; - public AttributeDictionary(Attributes attributes) { + public AttributeDictionary(Attributes attributes, List attrFilter, + Boolean includeFilter) { this.attributes = attributes; + this.attrFilter = attrFilter; + this.includeFilter = includeFilter; + try { + NamingEnumeration 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 keys() { - return attributes.getIDs(); + return Collections.enumeration(effectiveKeys); } @Override public Enumeration elements() { - throw new UnsupportedOperationException(); + final Iterator it = effectiveKeys.iterator(); + return new Enumeration() { + + @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); + } + } } diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifGroup.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifGroup.java index 845094820..4154d55a7 100644 --- a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifGroup.java +++ b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifGroup.java @@ -79,7 +79,7 @@ public class LdifGroup extends LdifUser implements Group { return new ArrayList(); try { List roles = new ArrayList(); - NamingEnumeration values = memberAttribute.getAll(); + NamingEnumeration values = memberAttribute.getAll(); while (values.hasMore()) { LdapName dn = new LdapName(values.next().toString()); roles.add(dn); diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUser.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUser.java index 379ac23ab..9f378f151 100644 --- a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUser.java +++ b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUser.java @@ -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 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 getProperties() { - if (attributes == null) - throw new ArgeoUserAdminException( - "Must be loaded from user admin service"); - return new AttributeDictionary(attributes); + return properties; } @Override public Dictionary 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(); } - } diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java index 440e93d9d..8cc7cb395 100644 --- a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java +++ b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java @@ -25,8 +25,8 @@ public class LdifUserAdmin implements UserAdmin { SortedMap 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")) { -- 2.30.2