X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.util%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FAbstractUserDirectory.java;h=e13f56289ce8b44b2f9629d2e297aadccbf03c03;hb=eb4324be6ac9cdff15828a21ee7d3f6ca2f19fb9;hp=716ddb5edfa72975fecfd3fef81812d4e7554505;hpb=e168383bac50637131fef8c41e119db7eb2284a7;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java b/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java index 716ddb5ed..e13f56289 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java @@ -18,6 +18,7 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Optional; +import java.util.StringJoiner; import javax.naming.InvalidNameException; import javax.naming.NameNotFoundException; @@ -32,6 +33,7 @@ import javax.naming.ldap.Rdn; 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; @@ -46,8 +48,10 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { static final String SHARED_STATE_PASSWORD = "javax.security.auth.login.password"; private final Hashtable properties; - private final LdapName baseDn, userBaseDn, groupBaseDn; - private final String userObjectClass, userBase, groupObjectClass, groupBase; + private final LdapName baseDn; + // private final LdapName userBaseDn, groupBaseDn; + private final Rdn userBaseRdn, groupBaseRdn, systemRoleBaseRdn; + private final String userObjectClass, groupObjectClass; private final boolean readOnly; private final boolean disabled; @@ -93,23 +97,31 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { forcedPassword = UserAdminConf.forcedPassword.getValue(properties); userObjectClass = UserAdminConf.userObjectClass.getValue(properties); - userBase = UserAdminConf.userBase.getValue(properties); + String userBase = UserAdminConf.userBase.getValue(properties); groupObjectClass = UserAdminConf.groupObjectClass.getValue(properties); - groupBase = UserAdminConf.groupBase.getValue(properties); + String groupBase = UserAdminConf.groupBase.getValue(properties); + String systemRoleBase = UserAdminConf.systemRoleBase.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); + systemRoleBaseRdn = new Rdn(systemRoleBase); } catch (InvalidNameException e) { throw new IllegalArgumentException("Badly formated base DN " + UserAdminConf.baseDn.getValue(properties), e); } + + // read only String readOnlyStr = UserAdminConf.readOnly.getValue(properties); if (readOnlyStr == null) { readOnly = readOnlyDefault(uri); properties.put(UserAdminConf.readOnly.name(), Boolean.toString(readOnly)); } else readOnly = Boolean.parseBoolean(readOnlyStr); + + // disabled String disabledStr = UserAdminConf.disabled.getValue(properties); if (disabledStr != null) disabled = Boolean.parseBoolean(disabledStr); @@ -136,11 +148,78 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { } + /* + * PATHS + */ + @Override - public String getBasePath() { + public String getContext() { return getBaseDn().toString(); } + @Override + public String getName() { + return nameToSimple(getBaseDn(), "."); + } + + @Override + public String getRolePath(Role role) { + return nameToRelativePath(((DirectoryUser) role).getDn()); + } + + @Override + public String getRoleSimpleName(Role role) { + LdapName dn = LdapNameUtils.toLdapName(role.getName()); + String name = LdapNameUtils.getLastRdnValue(dn); + return name; + } + + protected String nameToRelativePath(LdapName dn) { + LdapName name = LdapNameUtils.relativeName(getBaseDn(), dn); + return nameToSimple(name, "/"); + } + + protected String nameToSimple(LdapName name, String separator) { + StringJoiner path = new StringJoiner(separator); + for (int i = 0; i < name.size(); i++) { + path.add(name.getRdn(i).getValue().toString()); + } + return path.toString(); + + } + + protected LdapName pathToName(String path) { + try { + LdapName name = (LdapName) getBaseDn().clone(); + String[] segments = path.split("/"); + Rdn parentRdn = null; + for (String segment : segments) { + // TODO make attr names configurable ? + String attr = LdapAttrs.ou.name(); + if (parentRdn != null) { + if (getUserBaseRdn().equals(parentRdn)) + attr = LdapAttrs.uid.name(); + else if (getGroupBaseRdn().equals(parentRdn)) + attr = LdapAttrs.cn.name(); + else if (getSystemRoleBaseRdn().equals(parentRdn)) + attr = LdapAttrs.cn.name(); + } + Rdn rdn = new Rdn(attr, segment); + name.add(rdn); + parentRdn = rdn; + } + return name; + } catch (InvalidNameException e) { + throw new IllegalStateException("Cannot get role " + path, e); + } + + } + + @Override + public Role getRoleByPath(String path) { + return doGetRole(pathToName(path)); + } + @Override public Optional getRealm() { Object realm = getProperties().get(UserAdminConf.realm.name()); @@ -149,6 +228,10 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { return Optional.of(realm.toString()); } + /* + * EDITION + */ + protected boolean isEditing() { return xaResource.wc() != null; } @@ -240,23 +323,6 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { @Override public Role[] getRoles(String filter) throws InvalidSyntaxException { -// UserDirectoryWorkingCopy wc = getWorkingCopy(); -// Filter f = filter != null ? FrameworkUtil.createFilter(filter) : null; -// List res = doGetRoles(getBaseDn(), f, true); -// if (wc != null) { -// for (Iterator it = res.iterator(); it.hasNext();) { -// DirectoryUser user = it.next(); -// LdapName dn = user.getDn(); -// if (wc.getDeletedUsers().containsKey(dn)) -// it.remove(); -// } -// for (DirectoryUser user : wc.getNewUsers().values()) { -// if (f == null || f.match(user.getProperties())) -// res.add(user); -// } -// // no need to check modified users, -// // since doGetRoles was already based on the modified attributes -// } List res = getRoles(getBaseDn(), filter, true); return res.toArray(new Role[res.size()]); } @@ -281,19 +347,19 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { } // if non deep we also search users and groups - if (!deep) { - try { - if (!(searchBase.endsWith(new LdapName(getUserBase())) - || searchBase.endsWith(new LdapName(getGroupBase())))) { - LdapName usersBase = (LdapName) ((LdapName) searchBase.clone()).add(getUserBase()); - res.addAll(getRoles(usersBase, filter, false)); - LdapName groupsBase = (LdapName) ((LdapName) searchBase.clone()).add(getGroupBase()); - res.addAll(getRoles(groupsBase, filter, false)); - } - } catch (InvalidNameException e) { - throw new IllegalStateException("Cannot search users and groups", e); - } - } +// if (!deep) { +// try { +// if (!(searchBase.endsWith(new LdapName(getUserBase())) +// || searchBase.endsWith(new LdapName(getGroupBase())))) { +// LdapName usersBase = (LdapName) ((LdapName) searchBase.clone()).add(getUserBase()); +// res.addAll(getRoles(usersBase, filter, false)); +// LdapName groupsBase = (LdapName) ((LdapName) searchBase.clone()).add(getGroupBase()); +// res.addAll(getRoles(groupsBase, filter, false)); +// } +// } catch (InvalidNameException e) { +// throw new IllegalStateException("Cannot search users and groups", e); +// } +// } return res; } @@ -371,7 +437,7 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { } 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); @@ -385,14 +451,14 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { 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; @@ -434,34 +500,89 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { /* * HIERARCHY */ +// @Override +// public int getHierarchyChildCount() { +// return 0; +// } +// +// @Override +// public HierarchyUnit getHierarchyChild(int i) { +// throw new IllegalArgumentException("No child hierarchy unit available"); +// } +// +// @Override +// public HierarchyUnit getParent() { +// return null; +// } +// +// @Override +// public int getHierarchyUnitType() { +// return 0; +// } +// +// @Override +// public String getHierarchyUnitName() { +// String name = LdapNameUtils.getLastRdnValue(baseDn); +// // TODO check ou, o, etc. +// return name; +// } + @Override - public int getHierarchyChildCount() { - return 0; + public HierarchyUnit getHierarchyUnit(String path) { + throw new UnsupportedOperationException(); } @Override - public HierarchyUnit getHierarchyChild(int i) { - throw new IllegalArgumentException("No child hierarchy unit available"); + public HierarchyUnit getHierarchyUnit(Role role) { + throw new UnsupportedOperationException(); } +// @Override +// public List getHierarchyUnitRoles(String filter, boolean deep) { +// try { +// return getRoles(getBaseDn(), filter, deep); +// } catch (InvalidSyntaxException e) { +// throw new IllegalArgumentException("Cannot filter " + filter + " " + getBaseDn(), e); +// } +// } + @Override - public int getHierarchyUnitType() { - return 0; + public Iterable getDirectHierarchyUnits(boolean functionalOnly) { + throw new UnsupportedOperationException(); } - @Override - public String getHierarchyUnitName() { - String name = baseDn.getRdn(baseDn.size() - 1).getValue().toString(); - // TODO check ou, o, etc. - return name; + /* + * ROLES CREATION + */ + protected DirectoryUser newUser(LdapName name, Attributes attrs) { + // TODO support devices, applications, etc. + return new LdifUser.LdifPerson(this, name, attrs); } - @Override - public List getRoles(String filter, boolean deep) { + protected DirectoryGroup newGroup(LdapName name, Attributes attrs) { + if (LdapNameUtils.getParentRdn(name).equals(getSystemRoleBaseRdn())) + return new LdifGroup.LdifSystemPermissions(this, name, 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 { - return getRoles(getBaseDn(), filter, deep); - } catch (InvalidSyntaxException e) { - throw new IllegalArgumentException("Cannot filter " + filter + " " + getBaseDn(), e); + 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); } } @@ -518,12 +639,14 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { } protected int roleType(LdapName dn) { - if (dn.startsWith(groupBaseDn)) + Rdn technicalRdn = LdapNameUtils.getParentRdn(dn); + if (getGroupBaseRdn().equals(technicalRdn) || getSystemRoleBaseRdn().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. */ @@ -531,8 +654,8 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { return userObjectClass; } - public String getUserBase() { - return userBase; + Rdn getUserBaseRdn() { + return userBaseRdn; } protected String newUserObjectClass(LdapName dn) { @@ -543,11 +666,15 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { return groupObjectClass; } - public String getGroupBase() { - return groupBase; + Rdn getGroupBaseRdn() { + return groupBaseRdn; + } + + Rdn getSystemRoleBaseRdn() { + return systemRoleBaseRdn; } - public LdapName getBaseDn() { + LdapName getBaseDn() { return (LdapName) baseDn.clone(); }