X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.security.core%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FAbstractUserDirectory.java;fp=org.argeo.security.core%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FAbstractUserDirectory.java;h=0000000000000000000000000000000000000000;hb=e66b9893b0e511f8ab295e3cee42b7dc966f1597;hp=3f5bf850d55a890093804df97993f27f1eb809e4;hpb=8260f4470f514ea347ca53f5b4dfc632c4a4de66;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java deleted file mode 100644 index 3f5bf850d..000000000 --- a/org.argeo.security.core/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java +++ /dev/null @@ -1,426 +0,0 @@ -package org.argeo.osgi.useradmin; - -import static org.argeo.osgi.useradmin.LdifName.inetOrgPerson; -import static org.argeo.osgi.useradmin.LdifName.objectClass; -import static org.argeo.osgi.useradmin.LdifName.organizationalPerson; -import static org.argeo.osgi.useradmin.LdifName.person; -import static org.argeo.osgi.useradmin.LdifName.top; - -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; - -import javax.naming.InvalidNameException; -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttribute; -import javax.naming.directory.BasicAttributes; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.osgi.framework.Filter; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Authorization; -import org.osgi.service.useradmin.Role; -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 { - private final static Log log = LogFactory.getLog(AbstractUserDirectory.class); - - private final Hashtable properties; - private final LdapName baseDn; - private final String userObjectClass, userBase, groupObjectClass, groupBase; - - private final boolean readOnly; - private final URI uri; - - private UserAdmin externalRoles; - private List indexedUserProperties = Arrays - .asList(new String[] { LdifName.uid.name(), LdifName.mail.name(), LdifName.cn.name() }); - - private String memberAttributeId = "member"; - private List credentialAttributeIds = Arrays.asList(new String[] { LdifName.userPassword.name() }); - - // JTA - private TransactionManager transactionManager; - private WcXaResource xaResource = new WcXaResource(this); - - public AbstractUserDirectory(Dictionary props) { - properties = new Hashtable(); - for (Enumeration keys = props.keys(); keys.hasMoreElements();) { - String key = keys.nextElement(); - properties.put(key, props.get(key)); - } - - String uriStr = UserAdminConf.uri.getValue(properties); - if (uriStr == null) - uri = null; - else - try { - uri = new URI(uriStr); - } catch (URISyntaxException e) { - throw new UserDirectoryException("Badly formatted URI " + uriStr, e); - } - - try { - baseDn = new LdapName(UserAdminConf.baseDn.getValue(properties)); - } catch (InvalidNameException e) { - throw new UserDirectoryException("Badly formated base DN " + UserAdminConf.baseDn.getValue(properties), e); - } - String readOnlyStr = UserAdminConf.readOnly.getValue(properties); - if (readOnlyStr == null) { - readOnly = readOnlyDefault(uri); - properties.put(UserAdminConf.readOnly.name(), Boolean.toString(readOnly)); - } else - readOnly = new Boolean(readOnlyStr); - - userObjectClass = UserAdminConf.userObjectClass.getValue(properties); - userBase = UserAdminConf.userBase.getValue(properties); - groupObjectClass = UserAdminConf.groupObjectClass.getValue(properties); - groupBase = UserAdminConf.groupBase.getValue(properties); - } - - /** Returns the groups this user is a direct member of. */ - protected abstract List getDirectGroups(LdapName dn); - - protected abstract Boolean daoHasRole(LdapName dn); - - protected abstract DirectoryUser daoGetRole(LdapName key); - - protected abstract List doGetRoles(Filter f); - - public void init() { - - } - - public void destroy() { - - } - - protected boolean isEditing() { - return xaResource.wc() != null; - } - - protected UserDirectoryWorkingCopy getWorkingCopy() { - UserDirectoryWorkingCopy wc = xaResource.wc(); - if (wc == null) - return null; - return wc; - } - - 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); - } catch (Exception e) { - throw new UserDirectoryException("Cannot enlist " + xaResource, e); - } - } else { - } - } - - protected List getAllRoles(DirectoryUser user) { - List allRoles = new ArrayList(); - if (user != null) { - collectRoles(user, allRoles); - allRoles.add(user); - } else - collectAnonymousRoles(allRoles); - return allRoles; - } - - private void collectRoles(DirectoryUser user, List allRoles) { - for (LdapName groupDn : getDirectGroups(user.getDn())) { - // TODO check for loops - DirectoryUser group = doGetRole(groupDn); - allRoles.add(group); - collectRoles(group, allRoles); - } - } - - private void collectAnonymousRoles(List allRoles) { - // TODO gather anonymous roles - } - - // USER ADMIN - @Override - public Role getRole(String name) { - return doGetRole(toDn(name)); - } - - protected DirectoryUser doGetRole(LdapName dn) { - UserDirectoryWorkingCopy wc = getWorkingCopy(); - DirectoryUser user = daoGetRole(dn); - if (wc != null) { - if (user == null && wc.getNewUsers().containsKey(dn)) - user = wc.getNewUsers().get(dn); - else if (wc.getDeletedUsers().containsKey(dn)) - user = null; - } - return user; - } - - @SuppressWarnings("unchecked") - @Override - public Role[] getRoles(String filter) throws InvalidSyntaxException { - UserDirectoryWorkingCopy wc = getWorkingCopy(); - Filter f = filter != null ? FrameworkUtil.createFilter(filter) : null; - List res = doGetRoles(f); - 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 - } - return res.toArray(new Role[res.size()]); - } - - @Override - public User getUser(String key, String value) { - // TODO check value null or empty - List collectedUsers = new ArrayList(getIndexedUserProperties().size()); - if (key != null) { - doGetUser(key, value, collectedUsers); - } else { - // try dn - DirectoryUser user = null; - try { - user = (DirectoryUser) getRole(value); - if (user != null) - collectedUsers.add(user); - } catch (Exception e) { - // silent - } - // try all indexes - for (String attr : getIndexedUserProperties()) - doGetUser(attr, value, collectedUsers); - } - if (collectedUsers.size() == 1) - return collectedUsers.get(0); - else if (collectedUsers.size() > 1) - log.warn(collectedUsers.size() + " users for " + (key != null ? key + "=" : "") + value); - return null; - } - - protected void doGetUser(String key, String value, List collectedUsers) { - try { - Filter f = FrameworkUtil.createFilter("(" + key + "=" + value + ")"); - List users = doGetRoles(f); - collectedUsers.addAll(users); - } catch (InvalidSyntaxException e) { - throw new UserDirectoryException("Cannot get user with " + key + "=" + value, e); - } - } - - @Override - public Authorization getAuthorization(User user) { - return new LdifAuthorization((DirectoryUser) user, getAllRoles((DirectoryUser) user)); - } - - @Override - public Role createRole(String name, int type) { - checkEdit(); - UserDirectoryWorkingCopy wc = getWorkingCopy(); - LdapName dn = toDn(name); - if ((daoHasRole(dn) && !wc.getDeletedUsers().containsKey(dn)) || wc.getNewUsers().containsKey(dn)) - throw new UserDirectoryException("Already a role " + name); - BasicAttributes attrs = new BasicAttributes(true); - // attrs.put(LdifName.dn.name(), dn.toString()); - Rdn nameRdn = dn.getRdn(dn.size() - 1); - // TODO deal with multiple attr RDN - attrs.put(nameRdn.getType(), nameRdn.getValue()); - if (wc.getDeletedUsers().containsKey(dn)) { - wc.getDeletedUsers().remove(dn); - wc.getModifiedUsers().put(dn, attrs); - } else { - wc.getModifiedUsers().put(dn, attrs); - DirectoryUser newRole = newRole(dn, type, attrs); - wc.getNewUsers().put(dn, newRole); - } - return getRole(name); - } - - protected DirectoryUser newRole(LdapName dn, int type, Attributes attrs) { - LdifUser newRole; - BasicAttribute objClass = new BasicAttribute(objectClass.name()); - if (type == Role.USER) { - String userObjClass = newUserObjectClass(dn); - objClass.add(userObjClass); - if (inetOrgPerson.name().equals(userObjClass)) { - objClass.add(organizationalPerson.name()); - objClass.add(person.name()); - } else if (organizationalPerson.name().equals(userObjClass)) { - objClass.add(person.name()); - } - objClass.add(top.name()); - attrs.put(objClass); - newRole = new LdifUser(this, 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); - } else - throw new UserDirectoryException("Unsupported type " + type); - return newRole; - } - - @Override - public boolean removeRole(String name) { - checkEdit(); - UserDirectoryWorkingCopy wc = getWorkingCopy(); - LdapName dn = toDn(name); - boolean actuallyDeleted; - if (daoHasRole(dn) || wc.getNewUsers().containsKey(dn)) { - DirectoryUser user = (DirectoryUser) getRole(name); - wc.getDeletedUsers().put(dn, user); - actuallyDeleted = true; - } else {// just removing from groups (e.g. system roles) - actuallyDeleted = false; - } - for (LdapName groupDn : getDirectGroups(dn)) { - DirectoryUser group = doGetRole(groupDn); - group.getAttributes().get(getMemberAttributeId()).remove(dn.toString()); - } - return actuallyDeleted; - } - - // TRANSACTION - protected void prepare(UserDirectoryWorkingCopy wc) { - - } - - protected void commit(UserDirectoryWorkingCopy wc) { - - } - - protected void rollback(UserDirectoryWorkingCopy wc) { - - } - - // UTILITIES - protected LdapName toDn(String name) { - try { - return new LdapName(name); - } catch (InvalidNameException e) { - throw new UserDirectoryException("Badly formatted name", e); - } - } - - // GETTERS - protected String getMemberAttributeId() { - return memberAttributeId; - } - - protected List getCredentialAttributeIds() { - return credentialAttributeIds; - } - - protected URI getUri() { - return uri; - } - - protected List getIndexedUserProperties() { - return indexedUserProperties; - } - - protected void setIndexedUserProperties(List indexedUserProperties) { - this.indexedUserProperties = indexedUserProperties; - } - - private static boolean readOnlyDefault(URI uri) { - if (uri == null) - return true; - if (uri.getScheme().equals("file")) { - File file = new File(uri); - if (file.exists()) - return !file.canWrite(); - else - return !file.getParentFile().canWrite(); - } - return true; - } - - public boolean isReadOnly() { - return readOnly; - } - - protected UserAdmin getExternalRoles() { - return externalRoles; - } - - public LdapName getBaseDn() { - // always clone so that the property is not modified by reference - return (LdapName) baseDn.clone(); - } - - /** dn can be null, in that case a default should be returned. */ - public String getUserObjectClass() { - return userObjectClass; - } - - public String getUserBase() { - return userBase; - } - - protected String newUserObjectClass(LdapName dn) { - return getUserObjectClass(); - } - - public String getGroupObjectClass() { - return groupObjectClass; - } - - public String getGroupBase() { - return groupBase; - } - - public Dictionary getProperties() { - return properties; - } - - public void setExternalRoles(UserAdmin externalRoles) { - this.externalRoles = externalRoles; - } - - public void setTransactionManager(TransactionManager transactionManager) { - this.transactionManager = transactionManager; - } - - public WcXaResource getXaResource() { - return xaResource; - } - -}