void expireAuthTokens(Subject subject);
- UserDirectory getUserDirectory(User user);
+ UserDirectory getDirectory(Role role);
// User createUserFromPerson(Node person);
@Override
public Iterator<Content> iterator() {
List<Content> res = new ArrayList<>();
- for (Iterator<HierarchyUnit> it = directory.getRootHierarchyUnits().iterator(); it.hasNext();) {
+ for (Iterator<HierarchyUnit> it = directory.getRootHierarchyUnits(false).iterator(); it.hasNext();) {
res.add(new HierarchyUnitContent(getSession(), provider, it.next()));
}
return res.iterator();
}
@Override
- public UserDirectory getUserDirectory(User user) {
+ public UserDirectory getDirectory(Role user) {
String name = user.getName();
NavigableMap<String, UserDirectory> possible = new TreeMap<>();
for (UserDirectory userDirectory : userDirectories.keySet()) {
import org.argeo.osgi.transaction.WorkControl;
import org.argeo.util.naming.LdapAttrs;
+import org.argeo.util.naming.LdapObjs;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
static final String SHARED_STATE_PASSWORD = "javax.security.auth.login.password";
private final Hashtable<String, Object> properties;
- private final LdapName baseDn, userBaseDn, groupBaseDn;
+ private final LdapName baseDn;
+ // private final LdapName userBaseDn, groupBaseDn;
+ private final Rdn userBaseRdn, groupBaseRdn;
private final String userObjectClass, userBase, groupObjectClass, groupBase;
private final boolean readOnly;
groupBase = UserAdminConf.groupBase.getValue(properties);
try {
baseDn = new LdapName(UserAdminConf.baseDn.getValue(properties));
- userBaseDn = new LdapName(userBase + "," + baseDn);
- groupBaseDn = new LdapName(groupBase + "," + baseDn);
+ userBaseRdn = new Rdn(userBase);
+// userBaseDn = new LdapName(userBase + "," + baseDn);
+ groupBaseRdn = new Rdn(groupBase);
+// groupBaseDn = new LdapName(groupBase + "," + baseDn);
} catch (InvalidNameException e) {
throw new IllegalArgumentException("Badly formated base DN " + UserAdminConf.baseDn.getValue(properties),
e);
}
protected DirectoryUser newRole(LdapName dn, int type, Attributes attrs) {
- LdifUser newRole;
+ DirectoryUser newRole;
BasicAttribute objClass = new BasicAttribute(objectClass.name());
if (type == Role.USER) {
String userObjClass = newUserObjectClass(dn);
objClass.add(top.name());
objClass.add(extensibleObject.name());
attrs.put(objClass);
- newRole = new LdifUser(this, dn, attrs);
+ newRole = newUser(dn, attrs);
} else if (type == Role.GROUP) {
String groupObjClass = getGroupObjectClass();
objClass.add(groupObjClass);
// objClass.add(LdifName.extensibleObject.name());
objClass.add(top.name());
attrs.put(objClass);
- newRole = new LdifGroup(this, dn, attrs);
+ newRole = newGroup(dn, attrs);
} else
throw new IllegalArgumentException("Unsupported type " + type);
return newRole;
throw new UnsupportedOperationException();
}
+ void isFunctionalHierarchyUnit(HierarchyUnit hu) {
+
+ }
+
// @Override
// public List<? extends Role> getHierarchyUnitRoles(String filter, boolean deep) {
// try {
// }
@Override
- public Iterable<HierarchyUnit> getRootHierarchyUnits() {
+ public Iterable<HierarchyUnit> getRootHierarchyUnits(boolean functionalOnly) {
throw new UnsupportedOperationException();
}
+ /*
+ * ROLES CREATION
+ */
+ protected DirectoryUser newUser(LdapName name, Attributes attrs) {
+ // TODO support devices, applications, etc.
+ return new LdifUser.LdifPerson(this, name, attrs);
+ }
+
+ protected DirectoryGroup newGroup(LdapName name, Attributes attrs) {
+ if (hasObjectClass(attrs, LdapObjs.organization))
+ return new LdifGroup.LdifOrganization(this, name, attrs);
+ else
+ return new LdifGroup.LdifFunctionalGroup(this, name, attrs);
+
+ }
+
+ private boolean hasObjectClass(Attributes attrs, LdapObjs objectClass) {
+ try {
+ Attribute attr = attrs.get(LdapAttrs.objectClass.name());
+ NamingEnumeration<?> en = attr.getAll();
+ while (en.hasMore()) {
+ String v = en.next().toString();
+ if (v.equalsIgnoreCase(objectClass.name()))
+ return true;
+
+ }
+ return false;
+ } catch (NamingException e) {
+ throw new IllegalStateException("Cannot search for objectClass " + objectClass.name(), e);
+ }
+ }
+
// GETTERS
protected String getMemberAttributeId() {
return memberAttributeId;
}
protected int roleType(LdapName dn) {
- if (dn.startsWith(groupBaseDn))
+ Rdn technicalRdn = LdapNameUtils.getParentRdn(dn);
+ if (groupBaseRdn.equals(technicalRdn))
return Role.GROUP;
- else if (dn.startsWith(userBaseDn))
+ else if (userBaseRdn.equals(technicalRdn))
return Role.USER;
else
- return Role.GROUP;
+ throw new IllegalArgumentException(
+ "Cannot dind role type, " + technicalRdn + " is not a technical RDN for " + dn);
}
/** dn can be null, in that case a default should be returned. */
return userObjectClass;
}
- public String getUserBase() {
+ @Deprecated
+ String getUserBase() {
return userBase;
}
+ Rdn getUserBaseRdn() {
+ return userBaseRdn;
+ }
+
protected String newUserObjectClass(LdapName dn) {
return getUserObjectClass();
}
return groupObjectClass;
}
- public String getGroupBase() {
+ @Deprecated
+ String getGroupBase() {
return groupBase;
}
+ Rdn getGroupBaseRdn() {
+ return groupBaseRdn;
+ }
+
LdapName getBaseDn() {
return (LdapName) baseDn.clone();
}
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+public interface FunctionalGroup {
+
+}
/** A unit within the high-level organisational structure of a directory. */
public interface HierarchyUnit {
- final static int UNKOWN = 0;
- final static int ORGANIZATION = 1;
- final static int OU = 2;
-
String getHierarchyUnitName();
HierarchyUnit getParent();
Iterable<HierarchyUnit> getDirectHierachyUnits();
- int getHierarchyUnitType();
+ Iterable<HierarchyUnit> getFunctionalHierachyUnits();
+
+ boolean isFunctional();
String getBasePath();
}
}
+ static Rdn getParentRdn(LdapName dn) {
+ if (dn.size() < 2)
+ throw new IllegalArgumentException(dn + " has no parent");
+ Rdn parentRdn = dn.getRdn(dn.size() - 2);
+ return parentRdn;
+ }
+
static LdapName toLdapName(String distinguishedName) {
try {
return new LdapName(distinguishedName);
if (attrs.size() == 0)
return null;
int roleType = roleType(name);
- LdifUser res;
+ DirectoryUser res;
if (roleType == Role.GROUP)
- res = new LdifGroup(this, name, attrs);
+ res = newGroup( name, attrs);
else if (roleType == Role.USER)
- res = new LdifUser(this, name, attrs);
+ res = newUser( name, attrs);
else
throw new UserDirectoryException("Unsupported LDAP type for " + name);
return res;
Attributes attrs = searchResult.getAttributes();
Attribute objectClassAttr = attrs.get(objectClass.name());
LdapName dn = toDn(searchBase, searchResult);
- LdifUser role;
+ DirectoryUser role;
if (objectClassAttr.contains(getGroupObjectClass())
|| objectClassAttr.contains(getGroupObjectClass().toLowerCase()))
- role = new LdifGroup(this, dn, attrs);
+ role = newGroup( dn, attrs);
else if (objectClassAttr.contains(getUserObjectClass())
|| objectClassAttr.contains(getUserObjectClass().toLowerCase()))
- role = new LdifUser(this, dn, attrs);
+ role = newUser( dn, attrs);
else {
// log.warn("Unsupported LDAP type for " + searchResult.getName());
continue results;
import org.osgi.service.useradmin.Role;
/** Directory group implementation */
-class LdifGroup extends LdifUser implements DirectoryGroup {
+abstract class LdifGroup extends LdifUser implements DirectoryGroup {
private final String memberAttributeId;
LdifGroup(AbstractUserDirectory userAdmin, LdapName dn, Attributes attributes) {
public int getType() {
return GROUP;
}
+
+ /*
+ * KIND
+ */
+ static class LdifFunctionalGroup extends LdifGroup implements FunctionalGroup {
+
+ public LdifFunctionalGroup(AbstractUserDirectory userAdmin, LdapName dn, Attributes attributes) {
+ super(userAdmin, dn, attributes);
+ }
+
+ }
+
+ static class LdifOrganization extends LdifGroup implements Organization {
+
+ public LdifOrganization(AbstractUserDirectory userAdmin, LdapName dn, Attributes attributes) {
+ super(userAdmin, dn, attributes);
+ }
+
+ }
+
+ static class LdifSystemPermissions extends LdifGroup implements SystemPermissions {
+
+ public LdifSystemPermissions(AbstractUserDirectory userAdmin, LdapName dn, Attributes attributes) {
+ super(userAdmin, dn, attributes);
+ }
+
+ }
}
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.useradmin.Role;
private final AbstractUserDirectory directory;
private final LdapName dn;
- private final int type;
+ private final boolean functional;
private final Attributes attributes;
HierarchyUnit parent;
List<HierarchyUnit> children = new ArrayList<>();
- LdifHierarchyUnit(AbstractUserDirectory directory, LdapName dn, int type, Attributes attributes) {
+ LdifHierarchyUnit(AbstractUserDirectory directory, LdapName dn, Attributes attributes) {
Objects.requireNonNull(directory);
Objects.requireNonNull(dn);
this.directory = directory;
this.dn = dn;
- this.type = type;
this.attributes = attributes;
+
+ Rdn rdn = LdapNameUtils.getLastRdn(dn);
+ functional = !(directory.getUserBaseRdn().equals(rdn) || directory.getGroupBaseRdn().equals(rdn));
}
@Override
}
@Override
- public int getHierarchyUnitType() {
- return type;
+ public Iterable<HierarchyUnit> getFunctionalHierachyUnits() {
+ List<HierarchyUnit> res = new ArrayList<>();
+ for (HierarchyUnit hu : children) {
+ if (hu.isFunctional())
+ res.add(hu);
+ }
+ return res;
+ }
+
+ @Override
+ public boolean isFunctional() {
+ return functional;
}
@Override
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import java.util.StringJoiner;
import javax.naming.NamingEnumeration;
import org.argeo.util.naming.SharedSecret;
/** Directory user implementation */
-class LdifUser implements DirectoryUser {
+abstract class LdifUser implements DirectoryUser {
private final AbstractUserDirectory userAdmin;
private final LdapName dn;
publishedAttributes = modifiedAttributes;
}
- public DirectoryUser getPublished() {
- return new LdifUser(userAdmin, dn, publishedAttributes, true);
- }
+// public DirectoryUser getPublished() {
+// return new LdifUser(userAdmin, dn, publishedAttributes, true);
+// }
@Override
public int hashCode() {
return ch >= 32 && ch < 127;
}
+ static class LdifPerson extends LdifUser implements Person {
+
+ public LdifPerson(AbstractUserDirectory userAdmin, LdapName dn, Attributes attributes) {
+ super(userAdmin, dn, attributes);
+ }
+
+ }
}
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
String objectClass = objectClasses.next().toString();
// System.out.println(" " + objectClass);
if (objectClass.toLowerCase().equals(inetOrgPerson.name().toLowerCase())) {
- users.put(key, new LdifUser(this, key, attributes));
+ users.put(key, newUser(key, attributes));
break objectClasses;
} else if (objectClass.toLowerCase().equals(getGroupObjectClass().toLowerCase())) {
- groups.put(key, new LdifGroup(this, key, attributes));
+ groups.put(key, newGroup(key, attributes));
break objectClasses;
// } else if (objectClass.equalsIgnoreCase(LdapObjs.organization.name())) {
// // we only consider organizations which are not groups
// if (getUserBase().equalsIgnoreCase(name) || getGroupBase().equalsIgnoreCase(name))
// break objectClasses; // skip
// TODO skip if it does not contain groups or users
- hierarchy.put(key, new LdifHierarchyUnit(this, key, HierarchyUnit.OU, attributes));
+ hierarchy.put(key, new LdifHierarchyUnit(this, key, attributes));
break objectClasses;
}
}
}
@Override
- public Iterable<HierarchyUnit> getRootHierarchyUnits() {
- return rootHierarchyUnits;
+ public Iterable<HierarchyUnit> getRootHierarchyUnits(boolean functionalOnly) {
+ if (functionalOnly) {
+ List<HierarchyUnit> res = new ArrayList<>();
+ for (HierarchyUnit hu : rootHierarchyUnits) {
+ if (hu.isFunctional())
+ res.add(hu);
+ }
+ return res;
+
+ } else {
+ return rootHierarchyUnits;
+ }
}
@Override
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+public interface Organization {
+
+}
public class OsUserDirectory extends AbstractUserDirectory {
private final String osUsername = System.getProperty("user.name");
private final LdapName osUserDn;
- private final LdifUser osUser;
+ private final DirectoryUser osUser;
public OsUserDirectory(URI uriArg, Dictionary<String, ?> props) {
super(uriArg, props, false);
osUserDn = new LdapName(LdapAttrs.uid.name() + "=" + osUsername + "," + getUserBase() + "," + getBaseDn());
Attributes attributes = new BasicAttributes();
attributes.put(LdapAttrs.uid.name(), osUsername);
- osUser = new LdifUser(this, osUserDn, attributes);
+ osUser = newUser(osUserDn, attributes);
} catch (NamingException e) {
throw new UserDirectoryException("Cannot create system user", e);
}
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+public interface Person {
+
+}
--- /dev/null
+package org.argeo.osgi.useradmin;
+
+public interface SystemPermissions {
+
+}
String getUserObjectClass();
- String getUserBase();
+// String getUserBase();
String getGroupObjectClass();
- String getGroupBase();
+// String getGroupBase();
Optional<String> getRealm();
- Iterable<HierarchyUnit> getRootHierarchyUnits();
+ Iterable<HierarchyUnit> getRootHierarchyUnits(boolean functionalOnly);
HierarchyUnit getHierarchyUnit(String path);