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.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
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;
-import javax.transaction.TransactionManager;
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
- * an open transaction for write access.
- */
+/** A user admin based on a LDIF files. */
public class LdifUserAdmin extends AbstractUserDirectory {
private SortedMap<LdapName, DirectoryUser> users = new TreeMap<LdapName, DirectoryUser>();
private SortedMap<LdapName, DirectoryGroup> groups = new TreeMap<LdapName, DirectoryGroup>();
public LdifUserAdmin(String uri, String baseDn) {
- this(fromUri(uri, baseDn));
+ this(fromUri(uri, baseDn), false);
}
public LdifUserAdmin(Dictionary<String, ?> properties) {
- super(properties);
+ this(properties, false);
+ }
+
+ protected LdifUserAdmin(Dictionary<String, ?> properties, boolean scoped) {
+ super(null, properties, scoped);
+ }
+
+ public LdifUserAdmin(URI uri, Dictionary<String, ?> properties) {
+ super(uri, properties, false);
}
- public LdifUserAdmin(InputStream in) {
- super(new Hashtable<String, Object>());
- load(in);
+ @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, true);
+ scopedUserAdmin.groups = Collections.unmodifiableSortedMap(groups);
+ scopedUserAdmin.users = Collections.unmodifiableSortedMap(users);
+ return scopedUserAdmin;
}
private static Dictionary<String, Object> fromUri(String uri, String baseDn) {
}
public void init() {
+
try {
- if (getUri().getScheme().equals("file")) {
- File file = new File(getUri());
+ URI u = new URI(getUri());
+ if (u.getScheme().equals("file")) {
+ File file = new File(u);
if (!file.exists())
return;
}
- load(getUri().toURL().openStream());
+ load(u.toURL().openStream());
} catch (Exception e) {
throw new UserDirectoryException("Cannot open URL " + getUri(), e);
}
throw new UserDirectoryException("Cannot save LDIF user admin: no URI is set");
if (isReadOnly())
throw new UserDirectoryException("Cannot save LDIF user admin: " + getUri() + " is read-only");
- try (FileOutputStream out = new FileOutputStream(new File(getUri()))) {
+ try (FileOutputStream out = new FileOutputStream(new File(new URI(getUri())))) {
save(out);
- } catch (IOException e) {
+ } catch (IOException | URISyntaxException e) {
throw new UserDirectoryException("Cannot save user admin to " + getUri(), e);
}
}
objectClasses: while (objectClasses.hasMore()) {
String objectClass = objectClasses.next().toString();
// System.out.println(" " + objectClass);
- if (objectClass.equals(inetOrgPerson.name())) {
+ if (objectClass.toLowerCase().equals(inetOrgPerson.name().toLowerCase())) {
users.put(key, new LdifUser(this, key, attributes));
break objectClasses;
- } else if (objectClass.equals(getGroupObjectClass())) {
+ } else if (objectClass.toLowerCase().equals(getGroupObjectClass().toLowerCase())) {
groups.put(key, new LdifGroup(this, key, attributes));
break objectClasses;
}
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);
}
- @SuppressWarnings("unchecked")
protected List<DirectoryUser> doGetRoles(Filter f) {
ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
if (f == null) {
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);
}