Using the Permissions Service in Red Hat Web Application Framework

This document explains how to use the permissions service for controlling user access to ACSObjects.

API Overview

All Java classes that are related to the permissions system can be found in the com.arsdigita.kernel.permissions package.

The classes that make up the permissions system include the following:

Granting Access

Granting access to a party is accomplished by creating a PermissionDescriptor and passing it to PermissionService.grantPermission. The following example grants "read" privilege on MyACSObject "50" to Group "5":

import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.OID;

OID acsObject = new OID("example.MyACSObject",
                        new BigDecimal(50));

OID party = new OID("com.arsdigita.kernel.Group", new BigDecimal(5));


PermissionDescriptor perm =
    new PermissionDescriptor(PrivilegeDescriptor.READ,
                             acsObject, party);

PermissionService.grantPermission(perm);

The next example grants "admin" privilege on all objects to User "100":

import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.UniversalPermissionDescriptor;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.OID;

OID party = new OID("com.arsdigita.kernel.User", new BigDecimal(100));


PermissionDescriptor perm =
    new UniversalPermissionDescriptor(PrivilegeDescriptor.ADMIN,
                                      party);

PermissionService.grantPermission(perm);
  

Revoking Access

Revoking a privilege on an object from a party is accomplished by creating a PermissionDescriptor and passing it to PermissionService.revokePermission. The following example revokes "read" privilege on MyACSObject "50" from Group "5":

import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.OID;

OID acsObject = new OID("example.MyACSObject",
                        new BigDecimal(50));

OID party = new OID("com.arsdigita.kernel.Group", new BigDecimal(5));


PermissionDescriptor perm =
    new PermissionDescriptor(PrivilegeDescriptor.READ,
                             acsObject, party);

PermissionService.revokePermission(perm);
  

The next example revokes "admin" privilege on all objects from User "100":

import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.UniversalPermissionDescriptor;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.OID;

OID party = new OID("com.arsdigita.kernel.User", new BigDecimal(100));

PermissionDescriptor perm =
    new UniversalPermissionDescriptor(PrivilegeDescriptor.ADMIN,
                                      party);

PermissionService.revokePermission(perm);
  

Basic Access Check

The basic access check indicate whether a user has a privilege on an object. User X has privilege Y on object Z if either of the following is true:

To perform this check, you create a PermissionDescriptor and pass it to PermissionService.checkPermission. The following example checks "read" privilege on MyACSObject "50" for User "100":

import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.OID;

OID acsObject = new OID("example.MyACSObject",
                        new BigDecimal(50));

OID party = new OID("com.arsdigita.kernel.User", new BigDecimal(100));

PermissionDescriptor perm =
    new PermissionDescriptor(PrivilegeDescriptor.READ,
                             acsObject, party);

if (PermissionService.checkPermission(perm)) {
    // user 100 has read access on object 50
} else {
    // user 100 does NOT have read access on object 50.
    // You might handle this case by displaying an 
    // "access forbidden" message.
}
  

As the previous examples have shown, operations performed on PermissionDescriptor can also be performed on UniversalPermissionDescriptor when dealing with universal access control (that is, access to all objects). The same applies for PermissionService.checkPermission(). The following example checks whether user "100" has "admin" privilege universally:

import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.UniversalPermissionDescriptor;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.OID;

OID party = new OID("com.arsdigita.kernel.User", new BigDecimal(100));


PermissionDescriptor perm =
    new PermissionDescriptor(PrivilegeDescriptor.ADMIN,
                             party);

if (PermissionService.checkPermission(perm)) {
    // user 100 has admin access universally (that is, on all objects).
} else {
// user 100 does not universal admin access universally.
    // You might handle this case by displaying an 
    // "access forbidden" message.
}
  

Allowed Targets Check

The allowed targets check is performed on a DomainCollection or DataCollection in order to filter the result set of domain/data objects to only those on which a given user has a given privilege. The rules for determining whether a given user has a given privilege on an object are described above in "Basic Access Check."

You can be perform this filtering by using either PermissionService.filterObjects(DomainCollection, PrivilegeDescriptor, Party) or PermissionService.filterObjects(DataCollection, PrivilegeDescriptor, Party). The following example retrieves all MyACSObjects on which User "100" has "read" privilege:

import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.SessionManager;

DataCollection objects = SessionManager.getSession()
    .retrieve("example.MyACSObject");

OID party = new OID("com.arsdigita.kernel.User", new BigDecimal(100));


PermissionService.filterObjects(object, PrivilegeDescriptor.READ, party);

// iterate over filtered results
while (objects.next()) {
    ...
}
  

Setting the Access Control Context of an ACSObject

An ACSObject can inherit permissions from another ACSObject, which is called its context. To set the context of an object, use PermissionService.setContext(object, context). The context may be set to null to signify that the object should not inherit permissions from any other object. Note that universal permissions still apply to any object, even if its context is null.

Defining New Privileges

There are 4 pre-defined privileges in the system, similar to file system privileges:

Application developers may cautiously define new privileges to represent specific "actions" in the context of an application. For example, a content management system may support "publishing" a content item that is in final draft, but this operation should be restricted to certain parties for each content item. To accomplish this, the content management application creates a "publish" privilege from its initializer, as illustrated by the following code fragment.

if (PrivilegeDescriptor.get("publish") == null) {
    PrivilegeDescriptor.createPrivilege("publish");
}