argeo.osgi.start.4.workbench=\
org.eclipse.equinox.http.registry,\
+#argeo.node.useradmin.uri=ldap://localhost:10389/
+
# HTTP
org.osgi.service.http.port=7070
org.eclipse.equinox.http.jetty.log.stderr.threshold=info
log4j.rootLogger=WARN, development
log4j.logger.org.argeo=DEBUG
-log4j.logger.org.apache.jackrabbit.core.RepositoryImpl=DEBUG
+#log4j.logger.org.apache.jackrabbit.core.RepositoryImpl=DEBUG
#log4j.logger.argeo.stats=DEBUG
## Appenders
package org.argeo.cms.internal.kernel;
-import java.net.URL;
-
import javax.jcr.RepositoryException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
-import org.argeo.cms.internal.useradmin.JcrUserAdmin;
import org.argeo.cms.internal.useradmin.SimpleJcrSecurityModel;
import org.argeo.cms.internal.useradmin.jackrabbit.JackrabbitUserAdminService;
+import org.argeo.osgi.useradmin.AbstractLdapUserAdmin;
+import org.argeo.osgi.useradmin.LdapUserAdmin;
import org.argeo.osgi.useradmin.LdifUserAdmin;
import org.argeo.security.OsAuthenticationToken;
import org.argeo.security.UserAdminService;
private final InternalAuthenticationProvider internalAuth;
private final AnonymousAuthenticationProvider anonymousAuth;
private final JackrabbitUserAdminService userAdminService;
- private final LdifUserAdmin userAdmin;
+ private final AbstractLdapUserAdmin userAdmin;
private ServiceRegistration<AuthenticationManager> authenticationManagerReg;
private ServiceRegistration<UserAdminService> userAdminServiceReg;
.getFrameworkProp(KernelConstants.USERADMIN_URI);
if (userAdminUri == null)
userAdminUri = getClass().getResource("demo.ldif").toString();
- userAdmin = new LdifUserAdmin(userAdminUri);
+
+ if (userAdminUri.startsWith("ldap"))
+ userAdmin = new LdapUserAdmin(userAdminUri);
+ else
+ userAdmin = new LdifUserAdmin(userAdminUri);
}
public void publish() {
ou: users
dn: uid=demo,ou=users,dc=example,dc=com
+objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
-objectClass: inetOrgPerson
objectClass: top
cn: Demo User
description: Demo user
userpassword:: e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9
dn: uid=root,ou=users,dc=example,dc=com
-objectClass: person
objectClass: inetOrgPerson
+objectClass: person
objectClass: organizationalPerson
objectClass: top
cn: Super User
public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
- public void testBasicUserAdmin() {
+ public void testBasicUserAdmin() throws Exception {
LdifUserAdmin userAdmin = new LdifUserAdmin(getClass()
.getResourceAsStream("basic.ldif"));
.getBytes();
assertTrue(rootUser.hasCredential("userpassword", hashedPassword));
assertTrue(demoUser.hasCredential("userpassword", hashedPassword));
+
+ // search
+ Role[] search = userAdmin.getRoles(null);
+ assertEquals(4, search.length);
+ search = userAdmin.getRoles("(objectClass=groupOfNames)");
+ assertEquals(2, search.length);
+ search = userAdmin.getRoles("(objectclass=inetOrgPerson)");
+ assertEquals(2, search.length);
+ search = userAdmin.getRoles("(&(objectclass=inetOrgPerson)(uid=demo))");
+ assertEquals(1, search.length);
}
}
ou: People
dn: uid=demo,ou=People,dc=demo,dc=example,dc=org
+objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
-objectClass: inetOrgPerson
objectClass: top
cn: demo User
description: Demo user
userpassword:: e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9
dn: uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org
-objectClass: person
objectClass: inetOrgPerson
+objectClass: person
objectClass: organizationalPerson
objectClass: top
-cn: demo User
+cn: Super Admin
description: Superuser
givenname: Root
mail: root@localhost
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import org.osgi.service.useradmin.UserAdmin;
+
+public abstract class AbstractLdapUserAdmin implements UserAdmin {
+ private boolean isReadOnly;
+ private URI uri;
+
+ public AbstractLdapUserAdmin() {
+ }
+
+ public AbstractLdapUserAdmin(URI uri, boolean isReadOnly) {
+ this.uri = uri;
+ this.isReadOnly = isReadOnly;
+ }
+
+ private List<String> indexedUserProperties = Arrays.asList(new String[] {
+ "uid", "mail", "cn" });
+
+ protected URI getUri() {
+ return uri;
+ }
+
+ protected void setUri(URI uri) {
+ this.uri = uri;
+ }
+
+ protected List<String> getIndexedUserProperties() {
+ return indexedUserProperties;
+ }
+
+ protected void setIndexedUserProperties(List<String> indexedUserProperties) {
+ this.indexedUserProperties = indexedUserProperties;
+ }
+
+ protected void setReadOnly(boolean isReadOnly) {
+ this.isReadOnly = isReadOnly;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public void destroy() {
+
+ }
+
+}
package org.argeo.osgi.useradmin;
+import java.net.URI;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
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 LdapUserAdmin implements UserAdmin {
+public class LdapUserAdmin extends AbstractLdapUserAdmin {
private final static Log log = LogFactory.getLog(LdapUserAdmin.class);
- private List<String> indexedUserProperties = Arrays.asList(new String[] {
- "uid", "mail", "cn" });
-
private String baseDn = "dc=example,dc=com";
private InitialLdapContext initialLdapContext = null;
public LdapUserAdmin(String uri) {
try {
+ setUri(new URI(uri));
Hashtable<String, Object> connEnv = new Hashtable<String, Object>();
connEnv.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
- connEnv.put(Context.PROVIDER_URL, "ldap://localhost:10389/");
+ connEnv.put(Context.PROVIDER_URL, getUri().toString());
connEnv.put("java.naming.ldap.attributes.binary", "userPassword");
// connEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
// connEnv.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
@Override
public Role[] getRoles(String filter) throws InvalidSyntaxException {
- // TODO Auto-generated method stub
- return null;
+ try {
+ String searchFilter = filter;
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+ String searchBase = baseDn;
+ NamingEnumeration<SearchResult> results = initialLdapContext
+ .search(searchBase, searchFilter, searchControls);
+
+ ArrayList<Role> res = new ArrayList<Role>();
+ while (results.hasMoreElements()) {
+ SearchResult searchResult = results.next();
+ Attributes attrs = searchResult.getAttributes();
+ String name = searchResult.getName();
+ LdifUser role;
+ if (attrs.get("objectClass").contains("groupOfNames"))
+ role = new LdifGroup(new LdapName(name), attrs);
+ else if (attrs.get("objectClass").contains("inetOrgPerson"))
+ role = new LdifUser(new LdapName(name), attrs);
+ else
+ throw new ArgeoUserAdminException(
+ "Unsupported LDAP type for " + name);
+ res.add(role);
+ }
+ return res.toArray(new Role[res.size()]);
+ } catch (Exception e) {
+ throw new ArgeoUserAdminException("Cannot get roles for filter "
+ + filter, e);
+ }
}
@Override
public User getUser(String key, String value) {
if (key == null) {
List<User> users = new ArrayList<User>();
- for (String prop : indexedUserProperties) {
+ for (String prop : getIndexedUserProperties()) {
User user = getUser(prop, value);
if (user != null)
users.add(user);
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Dictionary;
import java.util.LinkedHashMap;
import java.util.List;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
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;
/** User admin implementation using LDIF file(s) as backend. */
-public class LdifUserAdmin implements UserAdmin {
+public class LdifUserAdmin extends AbstractLdapUserAdmin {
SortedMap<LdapName, LdifUser> users = new TreeMap<LdapName, LdifUser>();
SortedMap<LdapName, LdifGroup> groups = new TreeMap<LdapName, LdifGroup>();
- private final boolean isReadOnly;
- private final URI uri;
-
- private List<String> indexedUserProperties = Arrays.asList(new String[] {
- "uid", "mail", "cn" });
private Map<String, Map<String, LdifUser>> userIndexes = new LinkedHashMap<String, Map<String, LdifUser>>();
public LdifUserAdmin(String uri) {
}
public LdifUserAdmin(String uri, boolean isReadOnly) {
- this.isReadOnly = isReadOnly;
+ setReadOnly(isReadOnly);
try {
- this.uri = new URI(uri);
+ setUri(new URI(uri));
} catch (URISyntaxException e) {
throw new ArgeoUserAdminException("Invalid URI " + uri, e);
}
- if (!isReadOnly && !this.uri.getScheme().equals("file:"))
- throw new UnsupportedOperationException(this.uri.getScheme()
+ if (!isReadOnly && !getUri().getScheme().equals("file:"))
+ throw new UnsupportedOperationException(getUri().getScheme()
+ "not supported read-write.");
try {
- load(this.uri.toURL().openStream());
+ load(getUri().toURL().openStream());
} catch (Exception e) {
- throw new ArgeoUserAdminException("Cannot open URL " + this.uri, e);
+ throw new ArgeoUserAdminException("Cannot open URL " + getUri(), e);
}
}
public LdifUserAdmin(InputStream in) {
load(in);
- isReadOnly = true;
- this.uri = null;
+ setReadOnly(true);
+ setUri(null);
}
protected void load(InputStream in) {
group.loadMembers(this);
// indexes
- for (String attr : indexedUserProperties)
+ for (String attr : getIndexedUserProperties())
userIndexes.put(attr, new TreeMap<String, LdifUser>());
for (LdifUser user : users.values()) {
Dictionary<String, Object> properties = user.getProperties();
- for (String attr : indexedUserProperties) {
+ for (String attr : getIndexedUserProperties()) {
Object value = properties.get(attr);
if (value != null) {
LdifUser otherUser = userIndexes.get(attr).put(
if (otherUser != null)
throw new ArgeoUserAdminException("User " + user
+ " and user " + otherUser
- + " both habe property " + attr
+ + " both have property " + attr
+ " set to " + value);
}
}
@Override
public Role[] getRoles(String filter) throws InvalidSyntaxException {
+ ArrayList<Role> res = new ArrayList<Role>();
if (filter == null) {
- ArrayList<Role> res = new ArrayList<Role>();
res.addAll(users.values());
res.addAll(groups.values());
- return res.toArray(new Role[res.size()]);
+ } else {
+ Filter f = FrameworkUtil.createFilter(filter);
+ for (LdifUser user : users.values())
+ if (f.match(user.getProperties()))
+ res.add(user);
+ for (LdifUser group : groups.values())
+ if (f.match(group.getProperties()))
+ res.add(group);
}
- throw new UnsupportedOperationException();
+ return res.toArray(new Role[res.size()]);
}
@Override
// Try all indexes
List<LdifUser> collectedUsers = new ArrayList<LdifUser>(
- indexedUserProperties.size());
+ getIndexedUserProperties().size());
// try dn
LdifUser user = null;
try {
// throw new UnsupportedOperationException();
}
- public boolean getIsReadOnly() {
- return isReadOnly;
- }
-
}