X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.util%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FDirectoryUserAdmin.java;h=003aad11d8e1e6ea6e3ab9212b3c38db061755e9;hb=f3ea14abccc33b1c3326417a87c91145be776c72;hp=9f6d62d7a64600e85224c717786c0379335868fe;hpb=dc27b57704278684e72efcaf72b01c5b91df39f8;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/DirectoryUserAdmin.java b/org.argeo.util/src/org/argeo/osgi/useradmin/DirectoryUserAdmin.java index 9f6d62d7a..003aad11d 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/DirectoryUserAdmin.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/DirectoryUserAdmin.java @@ -8,9 +8,10 @@ import static org.argeo.util.naming.LdapObjs.person; import static org.argeo.util.naming.LdapObjs.top; import java.net.URI; -import java.nio.channels.UnsupportedAddressTypeException; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Dictionary; +import java.util.Hashtable; import java.util.Iterator; import java.util.List; @@ -21,16 +22,19 @@ import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; +import javax.security.auth.Subject; +import javax.security.auth.kerberos.KerberosTicket; +import org.argeo.util.CurrentSubject; import org.argeo.util.directory.DirectoryConf; import org.argeo.util.directory.DirectoryDigestUtils; import org.argeo.util.directory.HierarchyUnit; import org.argeo.util.directory.ldap.AbstractLdapDirectory; +import org.argeo.util.directory.ldap.LdapDao; import org.argeo.util.directory.ldap.LdapEntry; import org.argeo.util.directory.ldap.LdapEntryWorkingCopy; import org.argeo.util.directory.ldap.LdapNameUtils; import org.argeo.util.directory.ldap.LdifDao; -import org.argeo.util.naming.LdapObjs; import org.osgi.framework.Filter; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; @@ -66,7 +70,13 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm */ protected AbstractLdapDirectory scope(User user) { - throw new UnsupportedAddressTypeException(); + if (getDirectoryDao() instanceof LdapDao) { + return scopeLdap(user); + } else if (getDirectoryDao() instanceof LdifDao) { + return scopeLdif(user); + } else { + throw new IllegalStateException("Unsupported DAO " + getDirectoryDao().getClass()); + } } protected DirectoryUserAdmin scopeLdap(User user) { @@ -74,7 +84,7 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm String username = (String) credentials.get(SHARED_STATE_USERNAME); if (username == null) username = user.getName(); - Dictionary properties = cloneProperties(); + Dictionary properties = cloneConfigProperties(); properties.put(Context.SECURITY_PRINCIPAL, username.toString()); Object pwdCred = credentials.get(SHARED_STATE_PASSWORD); byte[] pwd = (byte[]) pwdCred; @@ -84,7 +94,9 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm } else { properties.put(Context.SECURITY_AUTHENTICATION, "GSSAPI"); } - return new DirectoryUserAdmin(null, properties, true); + DirectoryUserAdmin scopedDirectory = new DirectoryUserAdmin(null, properties, true); + scopedDirectory.init(); + return scopedDirectory; } protected DirectoryUserAdmin scopeLdif(User user) { @@ -102,13 +114,14 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm } else { throw new IllegalStateException("Password is required"); } - Dictionary properties = cloneProperties(); + Dictionary properties = cloneConfigProperties(); properties.put(DirectoryConf.readOnly.name(), "true"); DirectoryUserAdmin scopedUserAdmin = new DirectoryUserAdmin(null, properties, true); // scopedUserAdmin.groups = Collections.unmodifiableNavigableMap(groups); // scopedUserAdmin.users = Collections.unmodifiableNavigableMap(users); // FIXME do it better ((LdifDao) getDirectoryDao()).scope((LdifDao) scopedUserAdmin.getDirectoryDao()); + scopedUserAdmin.init(); return scopedUserAdmin; } @@ -126,25 +139,31 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm @Override public Role getRoleByPath(String path) { - return (Role) doGetRole(pathToName(path)); + LdapEntry entry = doGetRole(pathToName(path)); + if (!(entry instanceof Role)) { + throw new IllegalStateException("Path must be a UserAdmin Role."); + } else { + return (Role) entry; + } } protected List getAllRoles(DirectoryUser user) { List allRoles = new ArrayList(); if (user != null) { - collectRoles(user, allRoles); + collectRoles((LdapEntry) user, allRoles); allRoles.add(user); } else collectAnonymousRoles(allRoles); return allRoles; } - private void collectRoles(DirectoryUser user, List allRoles) { + private void collectRoles(LdapEntry user, List allRoles) { List allEntries = new ArrayList<>(); - LdapEntry entry = (LdapEntry) user; + LdapEntry entry = user; collectGroups(entry, allEntries); for (LdapEntry e : allEntries) { - allRoles.add((Role) e); + if (e instanceof Role) + allRoles.add((Role) e); } // Attributes attrs = user.getAttributes(); // // TODO centralize attribute name @@ -260,21 +279,51 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm @Override public Authorization getAuthorization(User user) { - if (user == null || user instanceof DirectoryUser) { - return new LdifAuthorization(user, getAllRoles((DirectoryUser) user)); + if (user == null) {// anonymous + return new LdifAuthorization(user, getAllRoles(null)); + } + LdapName userName = toLdapName(user.getName()); + if (isExternal(userName) && user instanceof LdapEntry) { + List allRoles = new ArrayList(); + collectRoles((LdapEntry) user, allRoles); + return new LdifAuthorization(user, allRoles); } else { - // bind - DirectoryUserAdmin scopedUserAdmin = (DirectoryUserAdmin) scope(user); - try { - DirectoryUser directoryUser = (DirectoryUser) scopedUserAdmin.getRole(user.getName()); - if (directoryUser == null) - throw new IllegalStateException("No scoped user found for " + user); - LdifAuthorization authorization = new LdifAuthorization(directoryUser, - scopedUserAdmin.getAllRoles(directoryUser)); - return authorization; - } finally { - scopedUserAdmin.destroy(); + + Subject currentSubject = CurrentSubject.current(); + if (currentSubject != null // + && getRealm().isPresent() // + && !currentSubject.getPrivateCredentials(Authorization.class).isEmpty() // + && !currentSubject.getPrivateCredentials(KerberosTicket.class).isEmpty()) // + { + // TODO not only Kerberos but also bind scope with kept password ? + Authorization auth = currentSubject.getPrivateCredentials(Authorization.class).iterator().next(); + // bind with authenticating user + DirectoryUserAdmin scopedUserAdmin = Subject.doAs(currentSubject, + (PrivilegedAction) () -> (DirectoryUserAdmin) scope( + new AuthenticatingUser(auth.getName(), new Hashtable<>()))); + return getAuthorizationFromScoped(scopedUserAdmin, user); } + + if (user instanceof DirectoryUser) { + return new LdifAuthorization(user, getAllRoles((DirectoryUser) user)); + } else { + // bind with authenticating user + DirectoryUserAdmin scopedUserAdmin = (DirectoryUserAdmin) scope(user); + return getAuthorizationFromScoped(scopedUserAdmin, user); + } + } + } + + private Authorization getAuthorizationFromScoped(DirectoryUserAdmin scopedUserAdmin, User user) { + try { + DirectoryUser directoryUser = (DirectoryUser) scopedUserAdmin.getRole(user.getName()); + if (directoryUser == null) + throw new IllegalStateException("No scoped user found for " + user); + LdifAuthorization authorization = new LdifAuthorization(directoryUser, + scopedUserAdmin.getAllRoles(directoryUser)); + return authorization; + } finally { + scopedUserAdmin.destroy(); } } @@ -283,7 +332,7 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm checkEdit(); LdapEntryWorkingCopy wc = getWorkingCopy(); LdapName dn = toLdapName(name); - if ((getDirectoryDao().daoHasEntry(dn) && !wc.getDeletedData().containsKey(dn)) + if ((getDirectoryDao().entryExists(dn) && !wc.getDeletedData().containsKey(dn)) || wc.getNewData().containsKey(dn)) throw new IllegalArgumentException("Already a role " + name); BasicAttributes attrs = new BasicAttributes(true); @@ -380,17 +429,11 @@ public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdm */ protected LdapEntry newUser(LdapName name, Attributes attrs) { // TODO support devices, applications, etc. - return new LdifUser.LdifPerson(this, name, attrs); + return new LdifUser(this, name, attrs); } protected LdapEntry 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); + return new LdifGroup(this, name, attrs); }