--- /dev/null
+package org.argeo.osgi.useradmin;
+
+interface BasicTestConstants {
+ final static String ROOT_USER_DN = "uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org";
+ final static String ADMIN_GROUP_DN = "cn=admin,ou=Roles,dc=demo,dc=example,dc=org";
+}
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
-public class LdifParserTest extends TestCase {
- public void testSimpleLdif() throws Exception {
+public class LdifParserTest extends TestCase implements BasicTestConstants {
+ public void testBasicLdif() throws Exception {
LdifParser ldifParser = new LdifParser();
SortedMap<LdapName, Attributes> res = ldifParser.read(getClass()
- .getResourceAsStream("test.ldif"));
- LdapName rootDn = new LdapName(
- "uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org");
+ .getResourceAsStream("basic.ldif"));
+ LdapName rootDn = new LdapName(ROOT_USER_DN);
Attributes rootAttributes = res.get(rootDn);
assertNotNull(rootAttributes);
assertEquals("Superuser", rootAttributes.get("description").get());
new String(rawPwEntry));
LdapName adminDn = new LdapName(
- "cn=admin,ou=Roles,dc=demo,dc=example,dc=org");
+ ADMIN_GROUP_DN);
Attributes adminAttributes = res.get(adminDn);
assertNotNull(adminAttributes);
Attribute memberAttribute = adminAttributes.get("member");
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+import junit.framework.TestCase;
+
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+
+public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
+
+ public void testBasicUserAdmin() {
+ LdifUserAdmin userAdmin = new LdifUserAdmin(getClass()
+ .getResourceAsStream("basic.ldif"));
+ User rootUser = (User) userAdmin.getRole(ROOT_USER_DN);
+ assertNotNull(rootUser);
+ Group adminGroup = (Group) userAdmin.getRole(ADMIN_GROUP_DN);
+ assertNotNull(adminGroup);
+ Role[] members = adminGroup.getMembers();
+ assertEquals(1, members.length);
+ assertEquals(rootUser.getName(), members[0].getName());
+ }
+}
--- /dev/null
+dn: dc=demo,dc=example,dc=org
+objectClass: domain
+objectClass: extensibleObject
+objectClass: top
+dc: demo
+
+dn: ou=Roles,dc=demo,dc=example,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Roles
+
+dn: ou=People,dc=demo,dc=example,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: People
+
+dn: uid=demo,ou=People,dc=demo,dc=example,dc=org
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: demo User
+description: Demo user
+givenname: Demo
+mail: demo@localhost
+sn: User
+uid: demo
+userpassword:: e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9
+
+dn: uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: top
+cn: demo User
+description: Superuser
+givenname: Root
+mail: root@localhost
+sn: Root
+uid: root
+userpassword:: e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9
+
+dn: cn=admin,ou=Roles,dc=demo,dc=example,dc=org
+objectClass: groupOfNames
+objectClass: top
+cn: admin
+member: uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org
\ No newline at end of file
+++ /dev/null
-dn: dc=demo,dc=example,dc=org
-objectClass: domain
-objectClass: extensibleObject
-objectClass: top
-dc: demo
-
-dn: ou=Roles,dc=demo,dc=example,dc=org
-objectClass: organizationalUnit
-objectClass: top
-ou: Roles
-
-dn: ou=People,dc=demo,dc=example,dc=org
-objectClass: organizationalUnit
-objectClass: top
-ou: People
-
-dn: uid=demo,ou=People,dc=demo,dc=example,dc=org
-objectClass: organizationalPerson
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: top
-cn: demo User
-description: Demo user
-givenname: Demo
-mail: demo@localhost
-sn: User
-uid: demo
-userpassword:: e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9
-
-dn: uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org
-objectClass: person
-objectClass: inetOrgPerson
-objectClass: organizationalPerson
-objectClass: top
-cn: demo User
-description: Superuser
-givenname: Root
-mail: root@localhost
-sn: Root
-uid: root
-userpassword:: e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9
-
-dn: cn=admin,ou=Roles,dc=demo,dc=example,dc=org
-objectClass: groupOfNames
-objectClass: top
-cn: admin
-member: uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org
\ No newline at end of file
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+import org.osgi.service.useradmin.UserAdmin;
+
+/**
+ * Exceptions related to Argeo's implementation of OSGi {@link UserAdmin}
+ * service.
+ */
+public class ArgeoUserAdminException extends RuntimeException {
+ private static final long serialVersionUID = 1419352360062048603L;
+
+ public ArgeoUserAdminException(String message) {
+ super(message);
+ }
+
+ public ArgeoUserAdminException(String message, Throwable e) {
+ super(message, e);
+ }
+}
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+
+class AttributeDictionary extends Dictionary {
+ private final Attributes attributes;
+
+ public AttributeDictionary(Attributes attributes) {
+ this.attributes = attributes;
+ }
+
+ @Override
+ public int size() {
+ return attributes.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return attributes.size() == 0;
+ }
+
+ @Override
+ public Enumeration<String> keys() {
+ return attributes.getIDs();
+ }
+
+ @Override
+ public Enumeration<Object> elements() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object get(Object key) {
+ try {
+ return attributes.get(key.toString()).get();
+ } catch (NamingException e) {
+ throw new ArgeoUserAdminException("Cannot get value for attribute "
+ + key, e);
+ }
+ }
+
+ @Override
+ public Object put(Object key, Object value) {
+ if (!(value instanceof String || value instanceof byte[]))
+ throw new IllegalArgumentException(
+ "Value muste be String or byte[]");
+ try {
+ Attribute attribute = attributes.get(key.toString());
+ attribute = new BasicAttribute(key.toString());
+ attribute.add(value);
+ Attribute previousAttribute = attributes.put(attribute);
+ if (previousAttribute != null)
+ return previousAttribute.get();
+ else
+ return null;
+ } catch (NamingException e) {
+ throw new ArgeoUserAdminException("Cannot get value for attribute "
+ + key, e);
+ }
+ }
+
+ @Override
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+}
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+
+public class LdifGroup extends LdifUser implements Group {
+
+ public LdifGroup(LdapName dn, Attributes attributes) {
+ super(dn, attributes);
+ }
+
+ @Override
+ public boolean addMember(Role role) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addRequiredMember(Role role) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeMember(Role role) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Role[] getMembers() {
+ Attribute memberAttribute = getAttributes().get("member");
+ if (memberAttribute == null)
+ return new Role[0];
+ try {
+ List<Role> roles = new ArrayList<Role>();
+ NamingEnumeration values = memberAttribute.getAll();
+ while (values.hasMore()) {
+ LdapName dn = new LdapName(values.next().toString());
+ roles.add(new LdifUser(dn, null));
+ }
+ return roles.toArray(new Role[roles.size()]);
+ } catch (Exception e) {
+ throw new ArgeoUserAdminException("Cannot get members", e);
+ }
+ }
+
+ @Override
+ public Role[] getRequiredMembers() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getType() {
+ return GROUP;
+ }
+
+}
if (currentDn != null) {
Attributes previous = res.put(currentDn,
currentAttributes);
- if (log.isDebugEnabled())
- log.debug("Added " + currentDn);
+ if (log.isTraceEnabled())
+ log.trace("Added " + currentDn);
if (previous != null) {
log.warn("There was already an entry with DN "
+ currentDn
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+class LdifUser implements User {
+ private final LdapName dn;
+ private final Attributes attributes;
+
+ LdifUser(LdapName dn, Attributes attributes) {
+ this.dn = dn;
+ this.attributes = attributes;
+ }
+
+ @Override
+ public String getName() {
+ return dn.toString();
+ }
+
+ @Override
+ public int getType() {
+ return USER;
+ }
+
+ @Override
+ public Dictionary<String, Object> getProperties() {
+ if (attributes == null)
+ throw new ArgeoUserAdminException(
+ "Must be loaded from user admin service");
+ return new AttributeDictionary(attributes);
+ }
+
+ @Override
+ public Dictionary<String, Object> getCredentials() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean hasCredential(String key, Object value) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ protected LdapName getDn() {
+ return dn;
+ }
+
+ protected Attributes getAttributes() {
+ return attributes;
+ }
+
+}
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+import java.io.InputStream;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+public class LdifUserAdmin implements UserAdmin {
+ private SortedMap<LdapName, Role> roles = new TreeMap<LdapName, Role>();
+
+ public LdifUserAdmin(InputStream in) {
+ try {
+ LdifParser ldifParser = new LdifParser();
+ SortedMap<LdapName, Attributes> allEntries = ldifParser.read(in);
+ for (LdapName key : allEntries.keySet()) {
+ Attributes attributes = allEntries.get(key);
+ NamingEnumeration objectClasses = attributes.get("objectClass")
+ .getAll();
+ objectClasses: while (objectClasses.hasMore()) {
+ String objectClass = objectClasses.next().toString();
+ if (objectClass.equals("inetOrgPerson")) {
+ roles.put(key, new LdifUser(key, attributes));
+ break objectClasses;
+ } else if (objectClass.equals("groupOfNames")) {
+ roles.put(key, new LdifGroup(key, attributes));
+ break objectClasses;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new ArgeoUserAdminException(
+ "Cannot initialise user admin service from LDIF", e);
+ }
+ }
+
+ @Override
+ public Role getRole(String name) {
+ LdapName key;
+ try {
+ key = new LdapName(name);
+ } catch (InvalidNameException e) {
+ // TODO implements default base DN
+ throw new IllegalArgumentException("Badly formatted role name: "
+ + name, e);
+ }
+
+ if (!roles.containsKey(key))
+ return null;
+ return roles.get(key);
+ }
+
+ @Override
+ public Authorization getAuthorization(User user) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Role createRole(String name, int type) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeRole(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Role[] getRoles(String filter) throws InvalidSyntaxException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public User getUser(String key, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+}