import javax.naming.directory.BasicAttributes;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
+import javax.transaction.xa.XAResource;
-import org.argeo.osgi.transaction.WorkControl;
import org.argeo.util.naming.LdapAttrs;
import org.argeo.util.naming.LdapObjs;
+import org.argeo.util.transaction.WorkControl;
+import org.argeo.util.transaction.WorkingCopyProcessor;
+import org.argeo.util.transaction.WorkingCopyXaResource;
+import org.argeo.util.transaction.XAResourceProvider;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.useradmin.UserAdmin;
/** Base class for a {@link UserDirectory}. */
-abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
+abstract class AbstractUserDirectory
+ implements UserAdmin, UserDirectory, WorkingCopyProcessor<DirectoryUserWorkingCopy>, XAResourceProvider {
static final String SHARED_STATE_USERNAME = "javax.security.auth.login.name";
static final String SHARED_STATE_PASSWORD = "javax.security.auth.login.password";
private final Hashtable<String, Object> properties;
private final LdapName baseDn;
// private final LdapName userBaseDn, groupBaseDn;
- private final Rdn userBaseRdn, groupBaseRdn;
- private final String userObjectClass, userBase, groupObjectClass, groupBase;
+ private final Rdn userBaseRdn, groupBaseRdn, systemRoleBaseRdn;
+ private final String userObjectClass, groupObjectClass;
private final boolean readOnly;
private final boolean disabled;
// Transaction
// private TransactionManager transactionManager;
private WorkControl transactionControl;
- private WcXaResource xaResource = new WcXaResource(this);
+ private WorkingCopyXaResource<DirectoryUserWorkingCopy> xaResource = new WorkingCopyXaResource<>(this);
private String forcedPassword;
forcedPassword = UserAdminConf.forcedPassword.getValue(properties);
userObjectClass = UserAdminConf.userObjectClass.getValue(properties);
- userBase = UserAdminConf.userBase.getValue(properties);
+ String userBase = UserAdminConf.userBase.getValue(properties);
groupObjectClass = UserAdminConf.groupObjectClass.getValue(properties);
- groupBase = UserAdminConf.groupBase.getValue(properties);
+ String groupBase = UserAdminConf.groupBase.getValue(properties);
+ String systemRoleBase = UserAdminConf.systemRoleBase.getValue(properties);
try {
baseDn = new LdapName(UserAdminConf.baseDn.getValue(properties));
userBaseRdn = new Rdn(userBase);
// userBaseDn = new LdapName(userBase + "," + baseDn);
groupBaseRdn = new Rdn(groupBase);
// groupBaseDn = new LdapName(groupBase + "," + baseDn);
+ systemRoleBaseRdn = new Rdn(systemRoleBase);
} catch (InvalidNameException e) {
throw new IllegalArgumentException("Badly formated base DN " + UserAdminConf.baseDn.getValue(properties),
e);
disabled = false;
}
+ /*
+ * ABSTRACT METHODS
+ */
+
/** Returns the groups this user is a direct member of. */
protected abstract List<LdapName> getDirectGroups(LdapName dn);
protected abstract AbstractUserDirectory scope(User user);
+ protected abstract HierarchyUnit doGetHierarchyUnit(LdapName dn);
+
+ protected abstract Iterable<HierarchyUnit> doGetDirectHierarchyUnits(LdapName searchBase, boolean functionalOnly);
+
+ /*
+ * INITIALIZATION
+ */
+
public void init() {
}
*/
@Override
- public String getGlobalId() {
+ public String getContext() {
return getBaseDn().toString();
}
try {
LdapName name = (LdapName) getBaseDn().clone();
String[] segments = path.split("/");
- String parentSegment = null;
+ Rdn parentRdn = null;
for (String segment : segments) {
- String attr = "ou";
- if (parentSegment != null) {
- if (getUserBase().equals(parentSegment))
- attr = "uid";
- else if (getGroupBase().equals(parentSegment))
- attr = "cn";
+ // TODO make attr names configurable ?
+ String attr = LdapAttrs.ou.name();
+ if (parentRdn != null) {
+ if (getUserBaseRdn().equals(parentRdn))
+ attr = LdapAttrs.uid.name();
+ else if (getGroupBaseRdn().equals(parentRdn))
+ attr = LdapAttrs.cn.name();
+ else if (getSystemRoleBaseRdn().equals(parentRdn))
+ attr = LdapAttrs.cn.name();
}
Rdn rdn = new Rdn(attr, segment);
name.add(rdn);
-
- // TODO make it more robust using RDNs
- parentSegment = rdn.toString();
+ parentRdn = rdn;
}
return name;
} catch (InvalidNameException e) {
return xaResource.wc() != null;
}
- protected UserDirectoryWorkingCopy getWorkingCopy() {
- UserDirectoryWorkingCopy wc = xaResource.wc();
+ protected DirectoryUserWorkingCopy getWorkingCopy() {
+ DirectoryUserWorkingCopy wc = xaResource.wc();
if (wc == null)
return null;
return wc;
}
protected DirectoryUser doGetRole(LdapName dn) {
- UserDirectoryWorkingCopy wc = getWorkingCopy();
+ DirectoryUserWorkingCopy wc = getWorkingCopy();
DirectoryUser user;
try {
user = daoGetRole(dn);
user = null;
}
if (wc != null) {
- if (user == null && wc.getNewUsers().containsKey(dn))
- user = wc.getNewUsers().get(dn);
- else if (wc.getDeletedUsers().containsKey(dn))
+ if (user == null && wc.getNewData().containsKey(dn))
+ user = wc.getNewData().get(dn);
+ else if (wc.getDeletedData().containsKey(dn))
user = null;
}
return user;
}
List<DirectoryUser> getRoles(LdapName searchBase, String filter, boolean deep) throws InvalidSyntaxException {
- UserDirectoryWorkingCopy wc = getWorkingCopy();
+ DirectoryUserWorkingCopy wc = getWorkingCopy();
Filter f = filter != null ? FrameworkUtil.createFilter(filter) : null;
List<DirectoryUser> res = doGetRoles(searchBase, f, deep);
if (wc != null) {
for (Iterator<DirectoryUser> it = res.iterator(); it.hasNext();) {
DirectoryUser user = it.next();
LdapName dn = user.getDn();
- if (wc.getDeletedUsers().containsKey(dn))
+ if (wc.getDeletedData().containsKey(dn))
it.remove();
}
- for (DirectoryUser user : wc.getNewUsers().values()) {
+ for (DirectoryUser user : wc.getNewData().values()) {
if (f == null || f.match(user.getProperties()))
res.add(user);
}
@Override
public Role createRole(String name, int type) {
checkEdit();
- UserDirectoryWorkingCopy wc = getWorkingCopy();
+ DirectoryUserWorkingCopy wc = getWorkingCopy();
LdapName dn = toLdapName(name);
- if ((daoHasRole(dn) && !wc.getDeletedUsers().containsKey(dn)) || wc.getNewUsers().containsKey(dn))
+ if ((daoHasRole(dn) && !wc.getDeletedData().containsKey(dn)) || wc.getNewData().containsKey(dn))
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);
// 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);
+ if (wc.getDeletedData().containsKey(dn)) {
+ wc.getDeletedData().remove(dn);
+ wc.getModifiedData().put(dn, attrs);
return getRole(name);
} else {
- wc.getModifiedUsers().put(dn, attrs);
+ wc.getModifiedData().put(dn, attrs);
DirectoryUser newRole = newRole(dn, type, attrs);
- wc.getNewUsers().put(dn, newRole);
+ wc.getNewData().put(dn, newRole);
return newRole;
}
}
@Override
public boolean removeRole(String name) {
checkEdit();
- UserDirectoryWorkingCopy wc = getWorkingCopy();
+ DirectoryUserWorkingCopy wc = getWorkingCopy();
LdapName dn = toLdapName(name);
boolean actuallyDeleted;
- if (daoHasRole(dn) || wc.getNewUsers().containsKey(dn)) {
+ if (daoHasRole(dn) || wc.getNewData().containsKey(dn)) {
DirectoryUser user = (DirectoryUser) getRole(name);
- wc.getDeletedUsers().put(dn, user);
+ wc.getDeletedData().put(dn, user);
actuallyDeleted = true;
} else {// just removing from groups (e.g. system roles)
actuallyDeleted = false;
return actuallyDeleted;
}
- // TRANSACTION
- protected void prepare(UserDirectoryWorkingCopy wc) {
-
- }
-
- protected void commit(UserDirectoryWorkingCopy wc) {
-
- }
-
- protected void rollback(UserDirectoryWorkingCopy wc) {
-
+ /*
+ * TRANSACTION
+ */
+ @Override
+ public DirectoryUserWorkingCopy newWorkingCopy() {
+ return new DirectoryUserWorkingCopy();
}
/*
* 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.getLastRdnValue(baseDn);
-// // TODO check ou, o, etc.
-// return name;
-// }
-
@Override
public HierarchyUnit getHierarchyUnit(String path) {
- throw new UnsupportedOperationException();
+ LdapName dn = pathToName(path);
+ return doGetHierarchyUnit(dn);
}
@Override
public HierarchyUnit getHierarchyUnit(Role role) {
- throw new UnsupportedOperationException();
- }
-
- void isFunctionalHierarchyUnit(HierarchyUnit hu) {
-
+ LdapName dn = LdapNameUtils.toLdapName(role.getName());
+ LdapName huDn = LdapNameUtils.getParent(dn);
+ HierarchyUnit hierarchyUnit = doGetHierarchyUnit(huDn);
+ if (hierarchyUnit == null)
+ throw new IllegalStateException("No hierarchy unit found for " + role);
+ return hierarchyUnit;
}
-// @Override
-// public List<? extends Role> getHierarchyUnitRoles(String filter, boolean deep) {
-// try {
-// return getRoles(getBaseDn(), filter, deep);
-// } catch (InvalidSyntaxException e) {
-// throw new IllegalArgumentException("Cannot filter " + filter + " " + getBaseDn(), e);
-// }
-// }
-
@Override
- public Iterable<HierarchyUnit> getRootHierarchyUnits(boolean functionalOnly) {
- throw new UnsupportedOperationException();
+ public Iterable<HierarchyUnit> getDirectHierarchyUnits(boolean functionalOnly) {
+ return doGetDirectHierarchyUnits(baseDn, functionalOnly);
}
/*
}
protected DirectoryGroup 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
protected int roleType(LdapName dn) {
Rdn technicalRdn = LdapNameUtils.getParentRdn(dn);
- if (groupBaseRdn.equals(technicalRdn))
+ if (getGroupBaseRdn().equals(technicalRdn) || getSystemRoleBaseRdn().equals(technicalRdn))
return Role.GROUP;
else if (userBaseRdn.equals(technicalRdn))
return Role.USER;
return userObjectClass;
}
- @Deprecated
- String getUserBase() {
- return userBase;
- }
-
Rdn getUserBaseRdn() {
return userBaseRdn;
}
return groupObjectClass;
}
- @Deprecated
- String getGroupBase() {
- return groupBase;
- }
-
Rdn getGroupBaseRdn() {
return groupBaseRdn;
}
+ Rdn getSystemRoleBaseRdn() {
+ return systemRoleBaseRdn;
+ }
+
LdapName getBaseDn() {
return (LdapName) baseDn.clone();
}
this.transactionControl = transactionControl;
}
- public WcXaResource getXaResource() {
+ public XAResource getXaResource() {
return xaResource;
}