import org.argeo.osgi.useradmin.TokenUtils;
import org.argeo.util.directory.ldap.IpaUtils;
import org.argeo.util.naming.LdapAttrs;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
import org.osgi.service.useradmin.Authorization;
import org.osgi.service.useradmin.Group;
import org.osgi.service.useradmin.User;
LdapAttrs.uid.name(), LdapAttrs.employeeNumber.name(), LdapAttrs.authPassword.name() });
// private state
- private BundleContext bc;
+// private BundleContext bc;
private User authenticatedUser = null;
private Locale locale;
Map<String, ?> options) {
this.subject = subject;
try {
- bc = FrameworkUtil.getBundle(UserAdminLoginModule.class).getBundleContext();
+// bc = FrameworkUtil.getBundle(UserAdminLoginModule.class).getBundleContext();
this.callbackHandler = callbackHandler;
this.sharedState = (Map<String, Object>) sharedState;
} catch (Exception e) {
String dName = getProperty(user, LdapAttrs.displayName.name());
if (isEmpty(dName))
dName = getProperty(user, LdapAttrs.cn.name());
+ if (isEmpty(dName))
+ dName = getProperty(user, LdapAttrs.uid.name());
if (isEmpty(dName))
dName = getUserLocalId(user.getName());
return dName;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
return res.size() == 1 ? res.get(0) : null;
}
+ /** Builds an authorisation by scanning all referentials. */
@Override
public Authorization getAuthorization(User user) {
if (user == null) {// anonymous
for (LdapName otherBaseDn : businessRoles.keySet()) {
if (otherBaseDn.equals(userReferentialOfThisUser.getBaseDn()))
continue;
- DirectoryUserAdmin otherUserAdmin = businessRoles.get(otherBaseDn);
+ DirectoryUserAdmin otherUserAdmin = userAdminToUse(user, businessRoles.get(otherBaseDn));
+ if (otherUserAdmin == null)
+ continue;
Authorization auth = otherUserAdmin.getAuthorization(retrievedUser);
allRoles.addAll(Arrays.asList(auth.getRoles()));
}
// integrate system roles
- final DirectoryUserAdmin userAdminToUse;// possibly scoped when authenticating
- if (user instanceof DirectoryUser) {
- userAdminToUse = userReferentialOfThisUser;
- } else if (user instanceof AuthenticatingUser) {
- userAdminToUse = (DirectoryUserAdmin) userReferentialOfThisUser.scope(user);
- } else {
- throw new IllegalArgumentException("Unsupported user type " + user.getClass());
- }
+ final DirectoryUserAdmin userAdminToUse = userAdminToUse(retrievedUser, userReferentialOfThisUser);
+ Objects.requireNonNull(userAdminToUse);
try {
Set<String> sysRoles = new HashSet<String>();
}
}
+ /** Decide whether to scope or not */
+ private DirectoryUserAdmin userAdminToUse(User user, DirectoryUserAdmin userAdmin) {
+ if (user instanceof DirectoryUser) {
+ return userAdmin;
+ } else if (user instanceof AuthenticatingUser) {
+ return userAdmin.scope(user).orElse(null);
+ } else {
+ throw new IllegalArgumentException("Unsupported user type " + user.getClass());
+ }
+
+ }
+
/**
* Enrich with application-specific roles which are strictly programmatic, such
* as anonymous/user semantics.
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
+import java.util.Optional;
import javax.naming.Context;
import javax.naming.InvalidNameException;
public class DirectoryUserAdmin extends AbstractLdapDirectory implements UserAdmin, UserDirectory {
private UserAdmin externalRoles;
- // private List<String> indexedUserProperties = Arrays
- // .asList(new String[] { LdapAttrs.uid.name(), LdapAttrs.mail.name(),
- // LdapAttrs.cn.name() });
// Transaction
-// private TransactionManager transactionManager;
public DirectoryUserAdmin(URI uriArg, Dictionary<String, ?> props) {
this(uriArg, props, false);
}
* ABSTRACT METHODS
*/
- protected AbstractLdapDirectory scope(User user) {
+ protected Optional<DirectoryUserAdmin> scope(User user) {
if (getDirectoryDao() instanceof LdapDao) {
return scopeLdap(user);
} else if (getDirectoryDao() instanceof LdifDao) {
}
}
- protected DirectoryUserAdmin scopeLdap(User user) {
+ protected Optional<DirectoryUserAdmin> scopeLdap(User user) {
Dictionary<String, Object> credentials = user.getCredentials();
String username = (String) credentials.get(SHARED_STATE_USERNAME);
if (username == null)
}
DirectoryUserAdmin scopedDirectory = new DirectoryUserAdmin(null, properties, true);
scopedDirectory.init();
- return scopedDirectory;
+ // check connection
+ if (!scopedDirectory.getDirectoryDao().checkConnection())
+ return Optional.empty();
+ return Optional.of(scopedDirectory);
}
- protected DirectoryUserAdmin scopeLdif(User user) {
+ protected Optional<DirectoryUserAdmin> scopeLdif(User user) {
Dictionary<String, Object> credentials = user.getCredentials();
String username = (String) credentials.get(SHARED_STATE_USERNAME);
if (username == null)
Dictionary<String, Object> 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());
+ // no need to check authentication
scopedUserAdmin.init();
- return scopedUserAdmin;
+ return Optional.of(scopedUserAdmin);
}
@Override
if (e instanceof Role)
allRoles.add((Role) e);
}
-// Attributes attrs = user.getAttributes();
-// // TODO centralize attribute name
-// Attribute memberOf = attrs.get(LdapAttrs.memberOf.name());
-// // if user belongs to this directory, we only check memberOf
-// if (memberOf != null && user.getDn().startsWith(getBaseDn())) {
-// try {
-// NamingEnumeration<?> values = memberOf.getAll();
-// while (values.hasMore()) {
-// Object value = values.next();
-// LdapName groupDn = new LdapName(value.toString());
-// DirectoryUser group = doGetRole(groupDn);
-// if (group != null)
-// allRoles.add(group);
-// }
-// } catch (NamingException e) {
-// throw new IllegalStateException("Cannot get memberOf groups for " + user, e);
-// }
-// } else {
-// for (LdapName groupDn : getDirectoryDao().getDirectGroups(user.getDn())) {
-// // TODO check for loops
-// DirectoryUser group = doGetRole(groupDn);
-// if (group != null) {
-// allRoles.add(group);
-// collectRoles(group, allRoles);
-// }
-// }
-// }
}
private void collectAnonymousRoles(List<Role> allRoles) {
// no need to check modified users,
// since doGetRoles was already based on the modified attributes
}
-
- // 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;
}
// 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>) () -> (DirectoryUserAdmin) scope(
- new AuthenticatingUser(auth.getName(), new Hashtable<>())));
+ DirectoryUserAdmin scopedUserAdmin = CurrentSubject.callAs(currentSubject, () -> {
+ return scope(new AuthenticatingUser(auth.getName(), new Hashtable<>())).orElseThrow();
+ });
return getAuthorizationFromScoped(scopedUserAdmin, user);
}
return new LdifAuthorization(user, getAllRoles((DirectoryUser) user));
} else {
// bind with authenticating user
- DirectoryUserAdmin scopedUserAdmin = (DirectoryUserAdmin) scope(user);
+ DirectoryUserAdmin scopedUserAdmin = scope(user).orElseThrow();
return getAuthorizationFromScoped(scopedUserAdmin, user);
}
}
@Override
public boolean removeRole(String name) {
return removeEntry(LdapNameUtils.toLdapName(name));
-// checkEdit();
-// LdapEntryWorkingCopy wc = getWorkingCopy();
-// LdapName dn = toLdapName(name);
-// boolean actuallyDeleted;
-// if (getDirectoryDao().daoHasEntry(dn) || wc.getNewData().containsKey(dn)) {
-// DirectoryUser user = (DirectoryUser) getRole(name);
-// wc.getDeletedData().put(dn, user);
-// actuallyDeleted = true;
-// } else {// just removing from groups (e.g. system roles)
-// actuallyDeleted = false;
-// }
-// for (LdapName groupDn : getDirectoryDao().getDirectGroups(dn)) {
-// LdapEntry group = doGetRole(groupDn);
-// group.getAttributes().get(getMemberAttributeId()).remove(dn.toString());
-// }
-// return actuallyDeleted;
}
/*
this.externalRoles = externalRoles;
}
-// public void setTransactionManager(TransactionManager transactionManager) {
-// this.transactionManager = transactionManager;
-// }
-
/*
* STATIC UTILITIES
*/
final static String extractDisplayName(User user) {
Dictionary<String, Object> props = user.getProperties();
- Object displayName = props.get(LdapAttrs.displayName);
+ Object displayName = props.get(LdapAttrs.displayName.name());
if (displayName == null)
- displayName = props.get(LdapAttrs.cn);
+ displayName = props.get(LdapAttrs.cn.name());
if (displayName == null)
- displayName = props.get(LdapAttrs.uid);
+ displayName = props.get(LdapAttrs.uid.name());
if (displayName == null)
displayName = user.getName();
if (displayName == null)
}
@Override
- public Boolean entryExists(LdapName dn) {
+ public boolean entryExists(LdapName dn) {
return osUserDn.equals(dn);
}
+ @Override
+ public boolean checkConnection() {
+ return true;
+ }
+
@Override
public LdapEntry doGetEntry(LdapName key) throws NameNotFoundException {
if (osUserDn.equals(key))
@Override
public void init() {
// TODO Auto-generated method stub
-
+
}
@Override
public void destroy() {
// TODO Auto-generated method stub
-
+
}
@Override
throw new IllegalStateException(name + " doe not exist in " + getDirectory().getBaseDn(), e);
}
}
-
+
}
} else {
// user doesn't have the right to retrieve role, but we know it exists
// otherwise memberOf would not work
-// Attributes a = new BasicAttributes();
-// a.put(LdapNameUtils.getLastRdn(groupDn).getType(),
-// LdapNameUtils.getLastRdn(groupDn).getValue());
-// a.put(LdapAttrs.objectClass.name(), LdapObjs.groupOfNames.name());
group = newGroup(groupDn);
allRoles.add(group);
}
public class LdapDao extends AbstractLdapDirectoryDao {
private LdapConnection ldapConnection;
-// public LdapUserAdmin(Dictionary<String, ?> properties) {
-// this(properties, false);
-// }
-
public LdapDao(AbstractLdapDirectory directory) {
super(directory);
}
ldapConnection.destroy();
}
-// @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();
-// Dictionary<String, Object> properties = cloneProperties();
-// properties.put(Context.SECURITY_PRINCIPAL, username.toString());
-// Object pwdCred = credentials.get(SHARED_STATE_PASSWORD);
-// byte[] pwd = (byte[]) pwdCred;
-// if (pwd != null) {
-// char[] password = DirectoryDigestUtils.bytesToChars(pwd);
-// properties.put(Context.SECURITY_CREDENTIALS, new String(password));
-// } else {
-// properties.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
-// }
-// return new LdapUserAdmin(properties, true);
-// }
-
-// protected InitialLdapContext getLdapContext() {
-// return initialLdapContext;
-// }
+ @Override
+ public boolean checkConnection() {
+ try {
+ return ldapConnection.entryExists(getDirectory().getBaseDn());
+ } catch (NamingException e) {
+ return false;
+ }
+ }
@Override
- public Boolean entryExists(LdapName dn) {
+ public boolean entryExists(LdapName dn) {
try {
return ldapConnection.entryExists(dn);
} catch (NameNotFoundException e) {
}
}
-// protected boolean isGroup(LdapName dn) {
-// Rdn technicalRdn = LdapNameUtils.getParentRdn(dn);
-// if (getDirectory().getGroupBaseRdn().equals(technicalRdn)
-// || getDirectory().getSystemRoleBaseRdn().equals(technicalRdn))
-// return true;
-// else if (getDirectory().getUserBaseRdn().equals(technicalRdn))
-// return false;
-// else
-// throw new IllegalArgumentException(
-// "Cannot find role type, " + technicalRdn + " is not a technical RDN for " + dn);
-// }
-
@Override
public Attributes doGetAttributes(LdapName name) {
try {
import org.argeo.util.transaction.WorkingCopyProcessor;
public interface LdapDirectoryDao extends WorkingCopyProcessor<LdapEntryWorkingCopy> {
- Boolean entryExists(LdapName dn);
+ boolean checkConnection();
+
+ boolean entryExists(LdapName dn);
LdapEntry doGetEntry(LdapName name) throws NameNotFoundException;
}
@Override
- public Boolean entryExists(LdapName dn) {
+ public boolean checkConnection() {
+ return true;
+ }
+
+ @Override
+ public boolean entryExists(LdapName dn) {
return entries.containsKey(dn);// || groups.containsKey(dn);
}