X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.util%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FAbstractUserDirectory.java;h=889f9cfa79fd3829bf4ab6ed6aee79b09626fc7b;hb=4c7e1885b8bf3c93fa0919ace122e3f289a925ea;hp=7279877e0e8ec46690a7f95b72ba062b234f8a34;hpb=9f729eeb8255a9d800ad2506735dda8cc215a135;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 7279877e0..889f9cfa7 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java @@ -1,11 +1,11 @@ package org.argeo.osgi.useradmin; -import static org.argeo.naming.LdapAttrs.objectClass; -import static org.argeo.naming.LdapObjs.extensibleObject; -import static org.argeo.naming.LdapObjs.inetOrgPerson; -import static org.argeo.naming.LdapObjs.organizationalPerson; -import static org.argeo.naming.LdapObjs.person; -import static org.argeo.naming.LdapObjs.top; +import static org.argeo.util.naming.LdapAttrs.objectClass; +import static org.argeo.util.naming.LdapObjs.extensibleObject; +import static org.argeo.util.naming.LdapObjs.inetOrgPerson; +import static org.argeo.util.naming.LdapObjs.organizationalPerson; +import static org.argeo.util.naming.LdapObjs.person; +import static org.argeo.util.naming.LdapObjs.top; import java.io.File; import java.net.URI; @@ -17,10 +17,12 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.Optional; import javax.naming.InvalidNameException; import javax.naming.NameNotFoundException; import javax.naming.NamingEnumeration; +import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; @@ -28,8 +30,8 @@ import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; -import org.argeo.naming.LdapAttrs; import org.argeo.osgi.transaction.WorkControl; +import org.argeo.util.naming.LdapAttrs; import org.osgi.framework.Filter; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; @@ -39,7 +41,7 @@ import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; /** Base class for a {@link UserDirectory}. */ -public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { +abstract class AbstractUserDirectory implements UserAdmin, UserDirectory { static final String SHARED_STATE_USERNAME = "javax.security.auth.login.name"; static final String SHARED_STATE_PASSWORD = "javax.security.auth.login.password"; @@ -67,6 +69,8 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory private WorkControl transactionControl; private WcXaResource xaResource = new WcXaResource(this); + private String forcedPassword; + AbstractUserDirectory(URI uriArg, Dictionary props, boolean scoped) { this.scoped = scoped; properties = new Hashtable(); @@ -86,6 +90,8 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory uri = uriStr; } + forcedPassword = UserAdminConf.forcedPassword.getValue(properties); + userObjectClass = UserAdminConf.userObjectClass.getValue(properties); userBase = UserAdminConf.userBase.getValue(properties); groupObjectClass = UserAdminConf.groupObjectClass.getValue(properties); @@ -95,7 +101,8 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory userBaseDn = new LdapName(userBase + "," + baseDn); groupBaseDn = new LdapName(groupBase + "," + baseDn); } catch (InvalidNameException e) { - throw new UserDirectoryException("Badly formated base DN " + UserAdminConf.baseDn.getValue(properties), e); + throw new IllegalArgumentException("Badly formated base DN " + UserAdminConf.baseDn.getValue(properties), + e); } String readOnlyStr = UserAdminConf.readOnly.getValue(properties); if (readOnlyStr == null) { @@ -117,7 +124,7 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory protected abstract DirectoryUser daoGetRole(LdapName key) throws NameNotFoundException; - protected abstract List doGetRoles(Filter f); + protected abstract List doGetRoles(LdapName searchBase, Filter f, boolean deep); protected abstract AbstractUserDirectory scope(User user); @@ -129,6 +136,19 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory } + @Override + public String getBasePath() { + return getBaseDn().toString(); + } + + @Override + public Optional getRealm() { + Object realm = getProperties().get(UserAdminConf.realm.name()); + if (realm == null) + return Optional.empty(); + return Optional.of(realm.toString()); + } + protected boolean isEditing() { return xaResource.wc() != null; } @@ -141,20 +161,11 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory } protected void checkEdit() { -// Transaction transaction; -// try { -// transaction = transactionManager.getTransaction(); -// } catch (SystemException e) { -// throw new UserDirectoryException("Cannot get transaction", e); -// } -// if (transaction == null) -// throw new UserDirectoryException("A transaction needs to be active in order to edit"); if (xaResource.wc() == null) { try { -// transaction.enlistResource(xaResource); transactionControl.getWorkContext().registerXAResource(xaResource, null); } catch (Exception e) { - throw new UserDirectoryException("Cannot enlist " + xaResource, e); + throw new IllegalStateException("Cannot enlist " + xaResource, e); } } else { } @@ -185,8 +196,8 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory if (group != null) allRoles.add(group); } - } catch (Exception e) { - throw new UserDirectoryException("Cannot get memberOf groups for " + user, e); + } catch (NamingException e) { + throw new IllegalStateException("Cannot get memberOf groups for " + user, e); } } else { for (LdapName groupDn : getDirectGroups(user.getDn())) { @@ -207,7 +218,7 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory // USER ADMIN @Override public Role getRole(String name) { - return doGetRole(toDn(name)); + return doGetRole(toLdapName(name)); } protected DirectoryUser doGetRole(LdapName dn) { @@ -229,9 +240,31 @@ public 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()]); + } + + List getRoles(LdapName searchBase, String filter, boolean deep) throws InvalidSyntaxException { UserDirectoryWorkingCopy wc = getWorkingCopy(); Filter f = filter != null ? FrameworkUtil.createFilter(filter) : null; - List res = doGetRoles(f); + List res = doGetRoles(searchBase, f, deep); if (wc != null) { for (Iterator it = res.iterator(); it.hasNext();) { DirectoryUser user = it.next(); @@ -246,7 +279,22 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory // no need to check modified users, // since doGetRoles was already based on the modified attributes } - return res.toArray(new Role[res.size()]); + + // 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); + } + } + return res; } @Override @@ -256,7 +304,7 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory if (key != null) { doGetUser(key, value, collectedUsers); } else { - throw new UserDirectoryException("Key cannot be null"); + throw new IllegalArgumentException("Key cannot be null"); } if (collectedUsers.size() == 1) { @@ -271,10 +319,10 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory protected void doGetUser(String key, String value, List collectedUsers) { try { Filter f = FrameworkUtil.createFilter("(" + key + "=" + value + ")"); - List users = doGetRoles(f); + List users = doGetRoles(getBaseDn(), f, true); collectedUsers.addAll(users); } catch (InvalidSyntaxException e) { - throw new UserDirectoryException("Cannot get user with " + key + "=" + value, e); + throw new IllegalArgumentException("Cannot get user with " + key + "=" + value, e); } } @@ -288,7 +336,7 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory try { DirectoryUser directoryUser = (DirectoryUser) scopedUserAdmin.getRole(user.getName()); if (directoryUser == null) - throw new UserDirectoryException("No scoped user found for " + user); + throw new IllegalStateException("No scoped user found for " + user); LdifAuthorization authorization = new LdifAuthorization(directoryUser, scopedUserAdmin.getAllRoles(directoryUser)); return authorization; @@ -302,9 +350,9 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory public Role createRole(String name, int type) { checkEdit(); UserDirectoryWorkingCopy wc = getWorkingCopy(); - LdapName dn = toDn(name); + LdapName dn = toLdapName(name); if ((daoHasRole(dn) && !wc.getDeletedUsers().containsKey(dn)) || wc.getNewUsers().containsKey(dn)) - throw new UserDirectoryException("Already a role " + name); + throw new IllegalArgumentException("Already a role " + name); BasicAttributes attrs = new BasicAttributes(true); // attrs.put(LdifName.dn.name(), dn.toString()); Rdn nameRdn = dn.getRdn(dn.size() - 1); @@ -346,7 +394,7 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory attrs.put(objClass); newRole = new LdifGroup(this, dn, attrs); } else - throw new UserDirectoryException("Unsupported type " + type); + throw new IllegalArgumentException("Unsupported type " + type); return newRole; } @@ -354,7 +402,7 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory public boolean removeRole(String name) { checkEdit(); UserDirectoryWorkingCopy wc = getWorkingCopy(); - LdapName dn = toDn(name); + LdapName dn = toLdapName(name); boolean actuallyDeleted; if (daoHasRole(dn) || wc.getNewUsers().containsKey(dn)) { DirectoryUser user = (DirectoryUser) getRole(name); @@ -383,12 +431,52 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory } - // UTILITIES - protected LdapName toDn(String name) { + /* + * 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.getLastRdnAsString(baseDn); + // TODO check ou, o, etc. + return name; + } + + @Override + public HierarchyUnit getHierarchyUnit(String path) { + return null; + } + + @Override + public HierarchyUnit getHierarchyUnit(Role role) { + return null; + } + + @Override + public List getRoles(String filter, boolean deep) { try { - return new LdapName(name); - } catch (InvalidNameException e) { - throw new UserDirectoryException("Badly formatted name", e); + return getRoles(getBaseDn(), filter, deep); + } catch (InvalidSyntaxException e) { + throw new IllegalArgumentException("Cannot filter " + filter + " " + getBaseDn(), e); } } @@ -494,6 +582,10 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory // this.transactionManager = transactionManager; // } + public String getForcedPassword() { + return forcedPassword; + } + public void setTransactionControl(WorkControl transactionControl) { this.transactionControl = transactionControl; } @@ -506,4 +598,24 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory return scoped; } + @Override + public int hashCode() { + return baseDn.hashCode(); + } + + @Override + public String toString() { + return "User Directory " + baseDn.toString(); + } + + /* + * STATIC UTILITIES + */ + static LdapName toLdapName(String name) { + try { + return new LdapName(name); + } catch (InvalidNameException e) { + throw new IllegalArgumentException(name + " is not an LDAP name", e); + } + } }