* @return <code>true</code> if functional, <code>false</code> is technical
* (e.g. People, Groups, etc.)
*/
- boolean isFunctional();
+ default boolean isFunctional() {
+ return isType(Type.FUNCTIONAL);
+ }
+
+ boolean isType(Type type);
/**
* The base of this organisational unit within the hierarchy. This would
/** Its metadata (typically LDAP attributes). */
Dictionary<String, Object> getProperties();
+
+ enum Type {
+ PEOPLE, //
+ GROUPS, //
+ ROLES, //
+ FUNCTIONAL;
+ }
}
return role.implied(currentSubject(), context);
}
- /** Implies this {@link SystemRole} in this context. */
+ /** Implies this role name, also independently of the context. */
public final static boolean implies(String role, String context) {
return SystemRole.implied(NamespaceUtils.parsePrefixedName(role), currentSubject(), context);
}
package org.argeo.cms.auth;
+import static org.argeo.api.acr.RuntimeNamespaceContext.getNamespaceContext;
+
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.ArgeoNamespace;
+import org.argeo.api.acr.NamespaceUtils;
+import org.argeo.cms.directory.ldap.LdapNameUtils;
+
+/** Simplifies analysis of system roles. */
public class RoleNameUtils {
+ public static String getLastRdnValue(String dn) {
+ return LdapNameUtils.getLastRdnValue(dn);
+// // we don't use LdapName for portability with Android
+// // TODO make it more robust
+// String[] parts = dn.split(",");
+// String[] rdn = parts[0].split("=");
+// return rdn[1];
+ }
+
+ public static QName getLastRdnAsName(String dn) {
+ String cn = getLastRdnValue(dn);
+ QName roleName = NamespaceUtils.parsePrefixedName(getNamespaceContext(), cn);
+ return roleName;
+ }
- /*
- * UTILITIES
- */
- public final static String getLastRdnValue(String dn) {
- // we don't use LdapName for portability with Android
- // TODO make it more robust
- String[] parts = dn.split(",");
- String[] rdn = parts[0].split("=");
- return rdn[1];
+ public static boolean isSystemRole(QName roleName) {
+ return roleName.getNamespaceURI().equals(ArgeoNamespace.ROLE_NAMESPACE_URI);
}
- public final static String getParent(String dn) {
+ public static String getParent(String dn) {
int index = dn.indexOf(',');
return dn.substring(index + 1);
}
/** Up two levels. */
- public final static String getContext(String dn) {
+ public static String getContext(String dn) {
return getParent(getParent(dn));
}
}
import org.argeo.api.cms.CmsConstants;
import org.argeo.cms.internal.auth.ImpliedByPrincipal;
+/** A programmatic role. */
public interface SystemRole {
QName getName();
+ /** Whether this role is implied for this authenticated user. */
default boolean implied(Subject subject, String context) {
return implied(getName(), subject, context);
}
+ /** Whether this role is implied for this distinguished name. */
+ default boolean implied(String dn, String context) {
+ String roleContext = RoleNameUtils.getContext(dn);
+ QName roleName = RoleNameUtils.getLastRdnAsName(dn);
+ return roleContext.equalsIgnoreCase(context) && getName().equals(roleName);
+ }
+
+ /**
+ * Whether this role is implied for this authenticated subject. If context is
+ * <code>null</code>, it is not considered; this should be used to build user
+ * interfaces, but not to authorise.
+ */
static boolean implied(QName name, Subject subject, String context) {
Set<ImpliedByPrincipal> roles = subject.getPrincipals(ImpliedByPrincipal.class);
for (ImpliedByPrincipal role : roles) {
}
}
return false;
-
}
}
}
@Override
- public boolean isFunctional() {
- return true;
+ public boolean isType(Type type) {
+ return Type.FUNCTIONAL.equals(type);
}
@Override
/** LDIF/LDAP based implementation of {@link HierarchyUnit}. */
public class LdapHierarchyUnit extends DefaultLdapEntry implements HierarchyUnit {
- private final boolean functional;
+// private final boolean functional;
+
+ private final Type type;
public LdapHierarchyUnit(AbstractLdapDirectory directory, LdapName dn) {
super(directory, dn);
Rdn rdn = LdapNameUtils.getLastRdn(dn);
- functional = !(directory.getUserBaseRdn().equals(rdn) || directory.getGroupBaseRdn().equals(rdn)
- || directory.getSystemRoleBaseRdn().equals(rdn));
+ if (directory.getUserBaseRdn().equals(rdn))
+ type = Type.PEOPLE;
+ else if (directory.getGroupBaseRdn().equals(rdn))
+ type = Type.GROUPS;
+ else if (directory.getSystemRoleBaseRdn().equals(rdn))
+ type = Type.ROLES;
+ else
+ type = Type.FUNCTIONAL;
+// functional = !(directory.getUserBaseRdn().equals(rdn) || directory.getGroupBaseRdn().equals(rdn)
+// || directory.getSystemRoleBaseRdn().equals(rdn));
}
@Override
}
@Override
- public boolean isFunctional() {
- return functional;
+ public boolean isType(Type type) {
+ return this.type.equals(type);
}
@Override
package org.argeo.cms.internal.auth;
-import static org.argeo.api.acr.RuntimeNamespaceContext.getNamespaceContext;
-
import java.security.Principal;
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
-import org.argeo.api.acr.ArgeoNamespace;
-import org.argeo.api.acr.NamespaceUtils;
import org.argeo.cms.auth.RoleNameUtils;
import org.osgi.service.useradmin.Authorization;
*/
public final class ImpliedByPrincipal implements Principal {
private final String name;
- private Set<Principal> causes = new HashSet<Principal>();
-
- private QName roleName;
-// private int type = Role.ROLE;
+ private final QName roleName;
+ private final boolean systemRole;
+ private final String context;
- private boolean systemRole = false;
- private String context;
+ private Set<Principal> causes = new HashSet<Principal>();
public ImpliedByPrincipal(String name, Principal userPrincipal) {
this.name = name;
- String cn = RoleNameUtils.getLastRdnValue(name);
- roleName = NamespaceUtils.parsePrefixedName(getNamespaceContext(), cn);
- if (roleName.getNamespaceURI().equals(ArgeoNamespace.ROLE_NAMESPACE_URI)) {
- systemRole = true;
- }
+ roleName = RoleNameUtils.getLastRdnAsName(name);
+ systemRole = RoleNameUtils.isSystemRole(roleName);
context = RoleNameUtils.getContext(name);
-// try {
-// this.name = new LdapName(name);
-// } catch (InvalidNameException e) {
-// throw new IllegalArgumentException("Badly formatted role name", e);
-// }
if (userPrincipal != null)
causes.add(userPrincipal);
}
-// public ImpliedByPrincipal(LdapName name, Principal userPrincipal) {
-// this.name = name;
-// if (userPrincipal != null)
-// causes.add(userPrincipal);
-// }
-
public String getName() {
return name;
}
- /*
- * USER ADMIN
- */
-// public boolean addMember(Principal user) {
-// throw new UnsupportedOperationException();
-// }
-//
-// public boolean removeMember(Principal user) {
-// throw new UnsupportedOperationException();
-// }
-//
-// public boolean isMember(Principal member) {
-// return causes.contains(member);
-// }
-//
-// public Enumeration<? extends Principal> members() {
-// return Collections.enumeration(causes);
-// }
-//
-//
-// /** Type of {@link Role}, if known. */
-// public int getType() {
-// return type;
-// }
-//
-// /** Not supported for the time being. */
-// public Dictionary<String, Object> getProperties() {
-// throw new UnsupportedOperationException();
-// }
-
/*
* OBJECT
*/
@Override
public boolean equals(Object obj) {
- // if (this == obj)
- // return true;
if (obj instanceof ImpliedByPrincipal) {
ImpliedByPrincipal that = (ImpliedByPrincipal) obj;
// TODO check members too?
@Override
public String toString() {
- // return name.toString() + " implied by " + causes;
return name.toString();
}
}