Use of Seam Security/drools to selectively load a list?
johnechesher Mar 8, 2007 4:01 PMI have an application where I want users to be able to add other new users IF the new user's role is "less than" that of the current user. By "less than" I mean that the user roles are hierarchical, as in the following roles hierarchy:
Super Admin (can add users w/ role of "Company Admin" or "Client Admin") ===> Company Admin (can add users w/ role of "Client Admin") ===> Client Admin (cannot add users)
So, on the "Add Users" page, I would like to load up a ListBox of possible roles for the new user with only the roles that the current user is permitted to add. Plus, I would like to do this in a way that is defined outside the Java code, to make maintenance easier, as lower level roles will change over time. I thought I would use drools/JBoss Rules to do this. Here's my code:
This is the ListBox in the view:
<h:selectOneListbox id="roleSelection" value="#{userRole.role}"> <f:selectItems value="#{maintainUsersAndContacts.roleList}" required="true" /> </h:selectOneListbox>
Here is the method (in a session bean) that loads SelectItems into an array
public ArrayList<SelectItem> getRoleList() { ArrayList<SelectItem> roleNames = new ArrayList<SelectItem>(); ArrayList<UserRole> roles = (ArrayList<UserRole>) entityManager.createQuery("from UserRole").getResultList(); for (UserRole r : roles) { if ( ( ! r.getDisabled()) && ( ! r.getRole().equals("Super Admin"))) { if (identity.hasPermission("user", "create", "false")) { roleNames.add(new SelectItem(r.getRole())); } } } return roleNames; }
And here are my drools rules that would apply to this functionality: (Sorry if way off - I'm a drools newbie ;-)
rule CanAddUserOfThisRole no-loop activation-group "permissions" when c: PermissionCheck(name == "user", action == "create", granted == false) Role(name == "Super Admin") then c.grant(); modify(c); end; rule CanAddUserOfThisRole2 no-loop activation-group "permissions" when c: PermissionCheck(name == "user", action == "create", granted == false) Role(usersRole : name) UserRole(newRole : role -> (newRole.getRole().equals("Client Admin") && usersRole.equals("Company Admin"))) then c.grant(); modify(c); end;
I haven't finished this, as it also involves code changes that will ripple through my project, however, when I reached this point, I started wondering how drools was going to know what "Role" object I was referring to in the following section of the drools code:
UserRole(newRole : role ->
After reading the Security section of the Seam Ref Doc thoroughly, I am now guessing that I am trying to do something that is not possible using the current Seam-1.2-drools integration, but I thought I would reach out to the Seam community for opinions before I abandon the idea.
Is this possible? If so, how do I go about it? Manually outject a Role object immediately before the permission check?
If not possible as I proposed it, does anyone have another idea of how to implement? (Note, after previewing my own post, the idea came to me to put an indicator on the UserRole object indicating it's "place" within the hierarchy. So, if it can't be done with Drools somehow, I'll probably go that route...)
Thanks