X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.security.core%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FLdifUserAdmin.java;h=9bf558b313b274a035d272a4db62d0f87db01381;hb=e91af5c65a42b3ff98400caa552965cdb3f730e6;hp=098243638a9cdba82c8f9f2bf2ede3e2988024e3;hpb=25071ab6bcb2df1fa4057c2c04137f2d606772e7;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java index 098243638..9bf558b31 100644 --- a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java +++ b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java @@ -5,10 +5,9 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.URI; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Dictionary; +import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -18,81 +17,49 @@ import java.util.TreeMap; import javax.naming.InvalidNameException; import javax.naming.NamingEnumeration; import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; -import javax.transaction.xa.XAException; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; import org.apache.commons.io.IOUtils; 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; /** User admin implementation using LDIF file(s) as backend. */ public class LdifUserAdmin extends AbstractUserDirectory { - SortedMap users = new TreeMap(); - SortedMap groups = new TreeMap(); + SortedMap users = new TreeMap(); + SortedMap groups = new TreeMap(); - private Map> userIndexes = new LinkedHashMap>(); + private Map> userIndexes = new LinkedHashMap>(); - // private Map> directMemberOf = new - // TreeMap>(); - private XaRes xaRes = new XaRes(); - - public LdifUserAdmin(String uri) { - this(uri, readOnlyDefault(uri)); + public LdifUserAdmin(String uri, String baseDn) { + this(fromUri(uri, baseDn)); } - public LdifUserAdmin(String uri, boolean isReadOnly) { - setReadOnly(isReadOnly); - try { - setUri(new URI(uri)); - } catch (URISyntaxException e) { - throw new UserDirectoryException("Invalid URI " + uri, e); - } - - if (!isReadOnly && !getUri().getScheme().equals("file")) - throw new UnsupportedOperationException(getUri().getScheme() - + " not supported read-write."); - - } - - public LdifUserAdmin(URI uri, boolean isReadOnly) { - setReadOnly(isReadOnly); - setUri(uri); - if (!isReadOnly && !getUri().getScheme().equals("file")) - throw new UnsupportedOperationException(getUri().getScheme() - + " not supported read-write."); - + public LdifUserAdmin(Dictionary properties) { + super(properties); } public LdifUserAdmin(InputStream in) { + super(new Hashtable()); load(in); setReadOnly(true); setUri(null); } - private static boolean readOnlyDefault(String uriStr) { - URI uri; - try { - uri = new URI(uriStr); - } catch (Exception e) { - throw new UserDirectoryException("Invalid URI " + uriStr, e); - } - if (uri.getScheme().equals("file")) { - File file = new File(uri); - return !file.canWrite(); - } - return true; + private static Dictionary fromUri(String uri, String baseDn) { + Hashtable res = new Hashtable(); + res.put(LdapProperties.uri.getFullName(), uri); + res.put(LdapProperties.baseDn.getFullName(), baseDn); + return res; } public void init() { try { + if (getUri().getScheme().equals("file")) { + File file = new File(getUri()); + if (!file.exists()) + return; + } load(getUri().toURL().openStream()); } catch (Exception e) { throw new UserDirectoryException("Cannot open URL " + getUri(), e); @@ -124,6 +91,9 @@ public class LdifUserAdmin extends AbstractUserDirectory { protected void load(InputStream in) { try { + users.clear(); + groups.clear(); + LdifParser ldifParser = new LdifParser(); SortedMap allEntries = ldifParser.read(in); for (LdapName key : allEntries.keySet()) { @@ -148,14 +118,14 @@ public class LdifUserAdmin extends AbstractUserDirectory { // indexes for (String attr : getIndexedUserProperties()) - userIndexes.put(attr, new TreeMap()); + userIndexes.put(attr, new TreeMap()); - for (LdifUser user : users.values()) { + for (DirectoryUser user : users.values()) { Dictionary properties = user.getProperties(); for (String attr : getIndexedUserProperties()) { Object value = properties.get(attr); if (value != null) { - LdifUser otherUser = userIndexes.get(attr).put( + DirectoryUser otherUser = userIndexes.get(attr).put( value.toString(), user); if (otherUser != null) throw new UserDirectoryException("User " + user @@ -178,17 +148,7 @@ public class LdifUserAdmin extends AbstractUserDirectory { groups = null; } - @Override - public Role getRole(String name) { - LdapName key; - try { - key = new LdapName(name); - } catch (InvalidNameException e) { - // TODO implements default base DN - throw new IllegalArgumentException("Badly formatted role name: " - + name, e); - } - + protected DirectoryUser daoGetRole(LdapName key) { if (groups.containsKey(key)) return groups.get(key); if (users.containsKey(key)) @@ -196,148 +156,56 @@ public class LdifUserAdmin extends AbstractUserDirectory { return null; } - @Override - public Authorization getAuthorization(User user) { - return new LdifAuthorization((LdifUser) user, - getAllRoles((LdifUser) user)); - } - - @Override - public Role createRole(String name, int type) { - try { - LdapName dn = new LdapName(name); - if (users.containsKey(dn) || groups.containsKey(dn)) - throw new UserDirectoryException("Already a role " + name); - - BasicAttributes attrs = new BasicAttributes(); - attrs.put("dn", dn.toString()); - Rdn nameRdn = dn.getRdn(dn.size() - 1); - // TODO deal with multiple attr RDN - attrs.put(nameRdn.getType(), nameRdn.getValue()); - LdifUser newRole; - if (type == Role.USER) { - newRole = new LdifUser(this, dn, attrs); - users.put(dn, newRole); - } else if (type == Role.GROUP) { - newRole = new LdifGroup(this, dn, attrs); - groups.put(dn, (LdifGroup) newRole); - } else - throw new UserDirectoryException("Unsupported type " + type); - return newRole; - } catch (InvalidNameException e) { - throw new UserDirectoryException("Cannot create role " + name, e); - } + protected Boolean daoHasRole(LdapName dn) { + return users.containsKey(dn) || groups.containsKey(dn); } - @Override - public boolean removeRole(String name) { - try { - LdapName dn = new LdapName(name); - LdifUser role = null; - if (users.containsKey(dn)) - role = users.remove(dn); - else if (groups.containsKey(dn)) - role = groups.remove(dn); - else - throw new UserDirectoryException("There is no role " + name); - if (role == null) - return false; - for (LdifGroup group : getDirectGroups(role)) { - // group.directMembers.remove(role); - group.getAttributes().get(getMemberAttributeId()) - .remove(dn.toString()); - } - if (role instanceof LdifGroup) { - LdifGroup group = (LdifGroup) role; - // for (Role user : group.directMembers) { - // if (user instanceof LdifUser) - // directMemberOf.get(((LdifUser) user).getDn()).remove( - // group); - // } - } - return true; - } catch (InvalidNameException e) { - throw new UserDirectoryException("Cannot create role " + name, e); - } - } + // @Override + // public boolean removeRole(String name) { + // LdapName dn = toDn(name); + // LdifUser role = null; + // if (users.containsKey(dn)) + // role = users.remove(dn); + // else if (groups.containsKey(dn)) + // role = groups.remove(dn); + // else + // throw new UserDirectoryException("There is no role " + name); + // if (role == null) + // return false; + // for (LdifGroup group : getDirectGroups(role)) { + // group.getAttributes().get(getMemberAttributeId()) + // .remove(dn.toString()); + // } + // return true; + // } - @Override - public Role[] getRoles(String filter) throws InvalidSyntaxException { - ArrayList res = new ArrayList(); - if (filter == null) { + protected List doGetRoles(Filter f) { + ArrayList res = new ArrayList(); + if (f == null) { res.addAll(users.values()); res.addAll(groups.values()); } else { - Filter f = FrameworkUtil.createFilter(filter); - for (LdifUser user : users.values()) + // Filter f = FrameworkUtil.createFilter(filter); + for (DirectoryUser user : users.values()) if (f.match(user.getProperties())) res.add(user); - for (LdifUser group : groups.values()) + for (DirectoryUser group : groups.values()) if (f.match(group.getProperties())) res.add(group); } - return res.toArray(new Role[res.size()]); + return res; } - @Override - public User getUser(String key, String value) { - // TODO check value null or empty - if (key != null) { - if (!userIndexes.containsKey(key)) - return null; - return userIndexes.get(key).get(value); - } - - // Try all indexes - List collectedUsers = new ArrayList( - getIndexedUserProperties().size()); - // try dn - LdifUser user = null; - try { - user = (LdifUser) getRole(value); - if (user != null) - collectedUsers.add(user); - } catch (Exception e) { - // silent - } - for (String attr : userIndexes.keySet()) { - user = userIndexes.get(attr).get(value); - if (user != null) - collectedUsers.add(user); - } - - if (collectedUsers.size() == 1) - return collectedUsers.get(0); - return null; - // throw new UnsupportedOperationException(); + protected void doGetUser(String key, String value, + List collectedUsers) { + assert key != null; + DirectoryUser user = userIndexes.get(key).get(value); + if (user != null) + collectedUsers.add(user); } - // protected void loadMembers(LdifGroup group) { - // group.directMembers = new ArrayList(); - // for (LdapName ldapName : group.getMemberNames()) { - // LdifUser role = null; - // if (groups.containsKey(ldapName)) - // role = groups.get(ldapName); - // else if (users.containsKey(ldapName)) - // role = users.get(ldapName); - // else { - // if (getExternalRoles() != null) - // role = (LdifUser) getExternalRoles().getRole( - // ldapName.toString()); - // if (role == null) - // throw new ArgeoUserAdminException("No role found for " - // + ldapName); - // } - // // role.directMemberOf.add(group); - // // if (!directMemberOf.containsKey(role.getDn())) - // // directMemberOf.put(role.getDn(), new ArrayList()); - // // directMemberOf.get(role.getDn()).add(group); - // group.directMembers.add(role); - // } - // } - @Override - protected List getDirectGroups(User user) { + protected List getDirectGroups(User user) { LdapName dn; if (user instanceof LdifUser) dn = ((LdifUser) user).getDn(); @@ -349,85 +217,61 @@ public class LdifUserAdmin extends AbstractUserDirectory { + user.getName(), e); } - List directGroups = new ArrayList(); + List directGroups = new ArrayList(); for (LdapName name : groups.keySet()) { - LdifGroup group = groups.get(name); + DirectoryGroup group = groups.get(name); if (group.getMemberNames().contains(dn)) directGroups.add(group); } return directGroups; - // if (directMemberOf.containsKey(dn)) - // return Collections.unmodifiableList(directMemberOf.get(dn)); - // else - // return Collections.EMPTY_LIST; } @Override - public XAResource getXAResource() { - return xaRes; - } - - private class XaRes implements XAResource { - - @Override - public void commit(Xid xid, boolean onePhase) throws XAException { - save(); - } - - @Override - public void end(Xid xid, int flags) throws XAException { - // TODO Auto-generated method stub - - } - - @Override - public void forget(Xid xid) throws XAException { - // TODO Auto-generated method stub - - } - - @Override - public int getTransactionTimeout() throws XAException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public boolean isSameRM(XAResource xares) throws XAException { - // TODO Auto-generated method stub - return false; - } - - @Override - public int prepare(Xid xid) throws XAException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public Xid[] recover(int flag) throws XAException { - // TODO Auto-generated method stub - return null; + protected void prepare(WorkingCopy wc) { + // delete + for (LdapName dn : wc.getDeletedUsers().keySet()) { + if (users.containsKey(dn)) + users.remove(dn); + else if (groups.containsKey(dn)) + groups.remove(dn); + else + throw new UserDirectoryException("User to delete no found " + + dn); } - - @Override - public void rollback(Xid xid) throws XAException { - // TODO Auto-generated method stub - + // add + for (LdapName dn : wc.getNewUsers().keySet()) { + DirectoryUser user = wc.getNewUsers().get(dn); + if (Role.USER == user.getType()) + users.put(dn, user); + else if (Role.GROUP == user.getType()) + groups.put(dn, (DirectoryGroup) user); + else + throw new UserDirectoryException("Unsupported role type " + + user.getType() + " for new user " + dn); } - - @Override - public boolean setTransactionTimeout(int seconds) throws XAException { - // TODO Auto-generated method stub - return false; + // modify + for (LdapName dn : wc.getModifiedUsers().keySet()) { + Attributes modifiedAttrs = wc.getModifiedUsers().get(dn); + DirectoryUser user; + if (users.containsKey(dn)) + user = users.get(dn); + else if (groups.containsKey(dn)) + user = groups.get(dn); + else + throw new UserDirectoryException("User to modify no found " + + dn); + user.publishAttributes(modifiedAttrs); } + } - @Override - public void start(Xid xid, int flags) throws XAException { - // TODO Auto-generated method stub - - } + @Override + protected void commit(WorkingCopy wc) { + save(); + } + @Override + protected void rollback(WorkingCopy wc) { + init(); } }