Access Control

Access control provents data from being accessed by unauthorized users. Access control can be enforced using XML, annotation or API.

Access Control XML

Each module can provide an access control XML file ac.xml that describes the permissions required to access instances of an entity type. Its entry name in module jar is [module]/conf/ac.xml.

For example, ExampleHR module:


<access-control>

	<entityType name="EMP">
	  	<entity accessType="CREATE" accessControl="OWNER|USER{CreateEMP}" />
  		<entity accessType="DELETE" accessControl="USER{DeleteEMP}" />
  		<entity accessType="EDIT" accessControl="OWNER|USER{EditEMP}" />
  		<entity accessType="VIEW" accessControl="OWNER|USER{ViewEMP}" />
  		<entity accessType="EXPORT" accessControl="USER{ExportEMP}" />
  		
		<properties accessType="EDIT" mode="EDIT" accessControl="SUSER{CreateEMP}" >	
			<property>name</property>		
			<property>nid</property>
		</properties>  		  		
  	</entityType>
  	
  	<action name="ApproveExpenseClaims" accessControl="USER{ApproveEC}">
  	<action name="ViewExpenseReport" accessControl="USER{CreateEC}">

</access-control>
accessType can be CREATE, DELETE, EDIT, VIEW, QUERY, EXPORT. accessControl is a list of accessControl items (separated by |, OR relationship) and each item is a user type followed by a list of permissions(optional). For example:
USER
USER{Permission1}
USER{Permission1,Permission2}
PUBLIC|USER{Permission1,Permission2}
NOBODY
ANONYMOUS|OWNER|USER{Permission}
If a user matches the user type and owns any one of the permissions (if any) of any accessControl item, then the user is authorized to access instances of the entityType.

User types

For the OWNER user type to be effective, the entity type must implement OwnerAware interface.

For the ExampleHR example above, entity type Employee is mapped to DataType(ExampleHR, EMP). The permissions required to access employees as follows:

If the access control for an entity type is not specified, then it is accessible to all public users by default.

In addition to access controls for entity types, access controls can be enforced for an action to be taken by current user. If the user is not authorized to take the action, the choices are:

Access Control Accessor

A module can define any permissions as needed. Permissions can be assigned to a Role that can be assigned to a User. To check if a user has a certain permission, use AccessControlAccessorWrapper API.

	// create AccessControlAccessorWrapper
	AccessControlContext acContext = ;
	AccessControlAccessorWrapper acAccessor = new AccessControlAccessorWrapper(
		AccessControlAccessor.getInstance(), acContext);
		
	// create AccessControlAccessorWrapper from viewConfig or backingBean
	// AccessControlAccessorWrapper acAccessor = viewConfig.getAccessControlAccessor(true);
	// AccessControlAccessorWrapper acAccessor = backingBean.getAccessControlAccessor();
		
	BackingBeanContext context = BackingBeanContext.getInstance();
	User currentUser = context.getAuthenticatedUser();	    
	if (acAccessor.isUserHasPermission(currentUser, moduleName, permissionName)) {
		...
	}
	
	if (acAccessor.canUserAccessType(currentUser, AccessType.EDIT, entityType)) {
		...
	}
	
	if (acAccessor.canUserTakeAction(currentUser, actionName)) {
		...
	}		
  } 

Super Permissions

If a user can manage an entity type, it implies that the user can create, delete and edit instances of the entity type. In other words, Manage[TypeName] is a super permssion of Create[TypeName], Edit[TypeName], and View[TypeName]. Similarly, Edit[TypeName] is a super permssion of View[TypeName].

Override Access Control

To override the permissions defined in XML, or enforce a different access control logic, override the following methods as needed in its EntityBackingBean.

	protected boolean isHasCreatePermission() 
	protected boolean isHasDeletePermission(PersistenceDataBackingBean<T> backingBean, T entity) 
	protected boolean isHasEditPermission(PersistenceDataBackingBean<T> backingBean, T entity)
	protected boolean isHasViewPermission(PersistenceDataBackingBean<T> backingBean, T entity)
Access controls can also be set in the ViewConfig of EntityBackingBean or EntityListBackingBean. For example,

	EntityViewConfig viewConfig = new EntityViewConfig(ViewType.ENTITY);
	viewConfig.setHasCreatePermission(false);
	viewConfig.setHasDeletePermission(false);
	viewConfig.setHasEditPermission(false);
	viewConfig.setHasViewPermission(true);

Property Access Control

Access controls for the properties of an entity type can be specified under its entityType element in the ac.xml file as the example above.

	<properties accessType="EDIT" mode="EDIT" accessControl="SUSER{CreateEMP}" >	
		<property>name</property>		
		<property>nid</property>
	</properties>
The mode specifies when the access control will be activated. Its value can be CREATE, EDIT, VIEW, QUERY or ALL. All mode means that the access control will be activated in all modes.

For the example above, to edit employee name and nid, the user needs to be a system user with CreateEMP permission.

Property visibility and edit control can be specified using annotation. For example,

    @Property(name="approver", view={ViewType.ENTITY},
    		mode={ModeType.VIEW, ModeType.EDIT, ModeType.QUERY}, 
    		editable=EditControl.QUERY_ONLY,
    		query=@Query(groupByProperty=true, orderByProperty=true)),
The property "approver" will be visible in VIEW, EDIT and QUERY modes, but not in CREATE mode. It is editable only in Query mode for search. The default value for editable is EditControl.ACCESS_CONTROL, using the property access control in XML file.

The editable control of a property can be overridden by calling setEditable(Boolean) method:


	EntityProperty entityProperty = ...;
	entityProperty.setEditable(true or false);