[security-dev] IdentityManager review - queries

Shane Bryzak sbryzak at redhat.com
Mon Oct 29 04:38:14 EDT 2012


I've started reviewing the IdentityManager interface to see where we can 
improve the API.  The first area I'd like to visit is the Query API, of 
which I've come to the conclusion that we need to do some serious 
redesign - the current API is non-intuitive, too verbose and not future 
proof.

What I'd like to do is throw it all out and start again, replacing it 
with a new cleaner API that looks something like this:

public interface IdentityManager {
     // <snip other methods>

     <T extends IdentityType> IdentityQuery<T> createQuery();
}

public interface IdentityQuery<T extends IdentityType> {
     public enum Param {id, key, created, expired, enabled, firstName, 
lastName, email, name, parent, memberOf};

     public enum Operator { equals, notEquals, greaterThan, lessThan };

     IdentityQuery<T> reset();

     IdentityQuery<T> setParameter(Param param, Object value);

     IdentityQuery<T> setParameter(Param param, Operator operator, 
Object value);

     IdentityQuery<T> setAttributeParameter(String attributeName, Object 
value);

     IdentityQuery<T> setAttributeParameter(String attributeName, 
Operator operator, Object value);

     IdentityQuery<T> setRange(Range range);

     List<T> getResultList();
}

This unified API basically replaces the 4 separate existing interfaces 
we currently have; UserQuery, RoleQuery, GroupQuery and 
MembershipQuery.  I've put together a few usage scenarios to show how it 
might work:

1) Find users with first name 'John':

List<User> users = identityManager.<User>createQuery()
     .setParameter(Param.firstName, "John")
     .getResultList();

2) Find all expired users:

List<User> users = identityManager.<User>createQuery()
     .setParameter(Param.expired, Operator.lessThan, new Date())
     .getResultList();

3) Find all users that are a member of the "Superuser" group

List<User> users = identityManager.<User>createQuery()
     .setParameter(Param.memberOf, identityManager.getGroup("Superuser"))
     .getResultList();

4) Find all sub-groups of the "Employees" group:

List<Group> groups = identityManager.<Group>createQuery()
     .setParameter(Param.memberOf, identityManager.getGroup("Employees"))
     .getResultList();

5) Find all disabled roles:

List<Role> roles = identityManager.<Role>createQuery()
     .setParameter(Param.enabled, false)
     .getResultList();

6) Find all Users, Groups and Roles that have been granted the "Payroll 
Officer" role in the "Human Resources" group:

List<IdentityType> identities = identityManager.<IdentityType>createQuery()
     .setParameter(Param.memberOf, identityManager.getGroup("Human 
Resources"))
     .setParameter(Param.memberOf, identityManager.getRole("Payroll 
Officer"))
     .getResultList();

7) Find all Users that have an attribute named "Citizenship" with a 
value of "Greenland":

List<User> users = identityManager.<User>createQuery()
     .setAttributeParameter("Citizenship", "Greenland")
     .getResultList();

I'm *pretty* certain that this API is at least as capable as what we 
currently have, if not more so, and IMHO provides a far simpler and more 
versatile design (being able to select different IdentityTypes in a 
single query I think is a big plus).  I'd love to hear any feedback on 
whether you like it, hate it or can think of any improvements to the 
design to make it better for our developers. Also, please think 
especially about additional usage scenarios and whether or not there are 
any particular use cases which might be problematic for this API.


Thanks!
Shane


More information about the security-dev mailing list