Permission Grant Filter Group Design

This page outlines the initial (and evolving) design details for fine-grained permission grants as they relate to the actual hierarchy (or filter) and the groups contained within. The intent is to provide a starting point for the design which can provoke further discussions among the uPortal community. In the end, the hope is that a consensus can be reached on a final design

If you'd like to see a use case regarding a fine-grained permission grant outlined with screenshots and didn't come to this page directly from it, take a look at the parent page Permissions Enhancements.

Filter Group Design Overview

A fine-grained permission grant is a hierarchy of 'filter' groups that determines the rights or permission that a subset of users has regarding some activity within the portal. The filter is a hierarchical set of logical connectives (AND/OR/NOT) that encompass some subset of attribute/operator/value combinations (Gender=male, GPA > 3.0) that themselves define either person attributes or person membership within a group.

A filter hierarchy has its own restrictions (discussed in Filter Group Membership Limitations) that limit its structure. Using the example on the 'Permissions Enhancements' page, let's look at the filter structure for publishing a channel to the following subset of users:

( AND
  Gender=male
  GPA > 3.0
  ( OR
    Group=Chemistry Major
    Group=Engineering Major
  )
)

The above filter in English states 'Publish this channel to males that have a GPA > 3.0 AND that are either Chemistry Majors OR Engineering Majors'.

The above hierarchy consists of Filter Groups (AND, OR), Person Attribute Groups (Gender=male, GPA > 3.0) and finally person-bucket groups (Group=Chemistry Major, Group=Engineering Major). So looking again at the structure, we have the following group types:

( AND ----------------------------------------- Filter Group
  Gender=male --------------------------------- PAGS Group
  GPA > 3.0 ----------------------------------- PAGS Group
  ( OR ---------------------------------------- Filter Group
    Group=Chemistry Major --------------------- Person-bucket Group
    Group=Engineering Major ------------------- Person-bucket Group
  )
)

A Person Attributes Group (PAGS) http://www.uportal.org/implementors/services/personAttributesGroupStore.html is not actually a PAGS group until the filter group has been saved. Prior to this, person attributes are presented by their respective plug-in using attributes configured in the Person Directory http://www.uportal.org/implementors/properties/PersonDirs.xml.html. During the hierarchy persistence transaction, the aov (attribute/operator/value) will be handed to the plug-in where it will then be stored as a new PAGS group. Upon successful group creation, the plug-in will then return the new PAGS group id to be stored as a member of the filter group.

Note: Neither the plug-in implementation design nor the runtime configuration of PAGS is covered in this particular discussion but will addressed in the future as a separate item.

When a filter is saved, the Filter Groups are stored by unique group key 'filter.id'. Additionally, the group membership hierarchy is created, consisting of references to each member group using its group key such as 'pags.id', 'local.id', and also filter.id. Finally, a reference to the associated operator will be saved for each filter group.

When the grant itself is stored in UP_PERMISSION, the PRINCIPAL_KEY will contain the group id (filter.id) of the topmost Filter Group in the hierarchy. During the authorization process, the principal requesting the authorization will be doing so against the filter group identified by that filter id in the grant. So, the person represented by the principal will be asking 'am I a member of the topmost filter group'. This request will be passed down the filter membership hierarchy and asked of each group type.

Filter Group Detailed Design

The following new interfaces and objects will be created for managing the new group type.

Interfaces

org.jasig.portal.IEntityFilterGroup

This group type provides APIs for accessing or modifying the group's associated operator (AND/OR/NOT, etc.). Evaluation of an authorization principal will be accomplished by calling the isMemberOf API, passing in the filter group.

public interface IEntityFilterGroup extends IEntityGroup
/**
 * Returns the operator instance associated with this filter group.
 **/
public IOperator getOperator()
/**
 * Sets the operator instance for this group.
 **/
public void setOperator( IOperator operator )
org.jasig.portal.groups.filter.IOperator

This interface defines the contract for an operator (AND/OR/NOT, etc.). An instance of this type will perform its operation (isApplicable) on behalf of an IAuthorizationPrincipal, against members of the operator's referring IEntityFilterGroup. This means that an AND operator's instance would have to ensure that the principal was a member of every group member of the referring IEntityFilterGroup, while an OR operator would be satisfied by the principal being a member of at least one group.

public interface IOperator
/**
 * Returns human-readable text representation of the operator implementation.  
 * Examples would be 'AND' and 'OR'.
 **/
public String getText()
/**
 * Evaluates the principal against the operator's referring filter group's members.  
 * Returns true if the principal is successfully evaluated against this operator.
 **/
public boolean isApplicable( IAuthorizationPrincipal principal )
/**
 * Returns the maximum number of member groups supported for evaluation of the operator.  
 * For example, an IOperator implementation of NOT would only support 1 member group to evaluate.  
 * A NULL implementation would support 0 member groups, while AND and OR implementations would 
 * support any number of member groups. 
 **/
public int maxAllowedMembers()

Interface Implementations

The IEntityFilterGroup implementation:

org.jasig.portal.groups.filter.EntityFilterGroupImpl
	implements IEntityFilterGroup

The initial set of IOperator implementations to be provided:

org.jasig.portal.groups.filter.operators.AndOperator
	implements IOperator
org.jasig.portal.groups.filter.operators.OrOperator
	implements IOperator
org.jasig.portal.groups.filter.operators.NotOperator
	implements IOperator

Group Store Objects

Store implementations for the new IEntityFilterGroup type:

org.jasig.portal.groups.filter.FilterEntityStoreFactory
	implements IEntityStoreFactory
org.jasig.portal.groups.filter.FilterEntitySearcherFactory
	implements IEntitySearcherFactory
org.jasig.portal.groups.filter.FilterEntityGroupStoreFactory
	implements IEntityGroupStoreFactory
org.jasig.portal.groups.filter.FilterEntityGroupStore
	implements IEntityGroupStore, IEntityStore, IEntitySearcher

Storage (Database Tables)

The new filter group type will make use of the existing UP_GROUP and UP_GROUP_MEMBERSHIP tables to store the group itself and its membership hierarchy respectively. However, two new database tables will have to be created to allow persistence of an IEntityFilterGroup's associated IOperator type. UP_FILTER_GROUP_OPERATOR is the join table for associating a filter group to its operator type. UP_FILTER_GROUP_OPERATOR_TYPE will be used for registration of new operator types by providing the implementation's class name. Obviously some type of tool will be needed to register new types....TBD.

UP_FILTER_GROUP_OPERATOR (both columns make up the primary key)
	GROUP_ID - Filter group id
	OPERATOR_ID - Operator numeric id

UP_FILTER_GROUP_OPERATOR_TYPE (OPERATOR_ID is the primary key)
	OPERATOR_ID - Operator numeric id
	CLASS - class name of operator implementation

Filter Group Membership Limitations

The following limitations apply to an IEntityFilterGroup and its group membership:

  • Filter groups cannot be members of other group types, such as a member of a PAGS group, yet these other group types can be members of filter groups.
  • Filter Groups may only belong to 0 or 1 parent filter groups.

Exposing a Group's Composition

In order to allow the display of a group's makeup or attributes in the filter hierarchy, such as the PAGS group that would represent 'Gender=male', it will be necessary to store this definition for future retrieval. One thought is to create a table that would store both the group id and this aov (attribute/operator/value) combination. This information would be accessed directly by the FilterEntityGroupStore to display within the UI to represent the associated group. One problem with this approach is that there would then be duplication of data. A bigger problem is the synchronization of the data between stores. If the group composition were to change within the PAGS configuration, then any data stored in the filter store would no longer be a valid representation of the associated group id. This then brings up the question, should modification of a group created within the filter 'application' be allowed? Doing so changes the definition of the filter and ultimately its intended audience.

Since the information representing that group must be stored and managed by the owning store anyway, why not allow it to be exposed by the group? This could be via a new API in the current org.jasig.portal.groups.IEntityGroup interface. Thus, adding an method to the IEntityGroup interface that would return a String representation of the group's makeup:

public String getComposition()

So for the PAGS group mentioned above, the return value from this method call would be 'gender=male'. For groups that are managed by the Groups Manager, the return for a person-bucket group from this API would be along the lines of 'group=faculty'.