Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Stardust/Knowledge Base/Customization/Portal/Role Based Stardust UI Customization Using Spring Bean Post-processor

Introduction

In this article, we will see how you can customize role based access to the Stardust Portal UI components using spring bean post processor approach.

In the Stardust portal framework, perspectives, launch panels, and views are implemented and controlled by spring backing beans. The spring beans take care of UI component visibility (like launch panel links) and role based access permissions.

If you need to change the default UI access policy, you can use spring bean post processor to access UI component backing beans and change the required or restricted roles. You can achieve things like:

  • Restrict access to X perspective for users with role R1;
  • Restrict access to users with role R2 to view V1; or
  • Hide launch panels, say managements view from BCC perspective, to users with role R2.

Now let us see all this in action with illustrative example;

Spring Bean Post-processor

As you know, once we create a class implementing spring’s BeanPostProcessor and define it as a bean in a spring context file. The post processor has two call back methods, one before bean initialization and second after bean initialization.

The spring framework will invoke your post processor for every bean in the given spring context during context initialization.

In this case, we will use the bean post processor's after initialization method to access initialized Stardust Portal UI beans and change default access permissions as per our needs.

The following section shows how to customize UI access rights with select use cases and code snippets. The complete spring bean post processor code is given at the end.

Customizing Perspective Access

By default, Business Control Center perspective is available all roles. But if you want to change this default behavior and hide BCC perspective to a role, say “Role 2”. This can be achieved using bean post process as shown in the follow code snippet below; Where, SidsIssueModel is a model id and Role_2 is role id for which we want to add restrictions.

...
 
             if (bean instanceof PerspectiveDefinition) {
			PerspectiveDefinition perspectiveBean = (PerspectiveDefinition) bean;			
			if (perspectiveBean.getName().equals("ippBccPerspective")) {
				perspectiveBean.setExcludeRoles(perspectiveBean
							.getExcludeRoles() + ",{SidsIssueModel}Role_2");			
			}
		}

With this, users having role id 'Role_2' will not be able to see link to BCC perspective.


Restricting Views

There are common views, meaning one view is available in multiple perspective of the Stardust portal. Thus they are shared. The examples of common views are document view, document search view, and process instance details view. They are available in workflow, BCC, and admin perspectieves.

Now, consider that we want to restrict the process instance details view and document search view to “Role 2”. The code snippets below show how.

...
 
             if (bean instanceof ViewDefinition) {			
			ViewDefinition view = (ViewDefinition) bean;			
			if(view.getName().equals("documentSearchView") 
                           || view.getName().equals("processInstanceDetailsView") ){
				view.setExcludeRoles(view.getExcludeRoles()+ ",{SidsIssueModel}Role_2");
			}			
		}

Note that links to these views remain active in the portal. But when you click on them, you get a custom message saying, you do not have access to the given view, and thus the access is restricted to the view.


Restricting Launch Panels

Now, we will see how to restrict access to launch panels. Consider that we want to restrict Role 2 users from accessing management views launch panel of the BCC perspective. Here is the code snippet that does it.

...
 
            if (bean instanceof LaunchPanel) {
			LaunchPanel lp = (LaunchPanel) bean;
			if(lp.getName().equals("managementViews")){
				lp.setExcludeRoles(lp.getExcludeRoles()+ ",{SidsIssueModel}Role_2");				
			}
		}

With this, users having role id 'Role_2' will not be able to see the management views link on the BCC perspective.


Example Implementation 1

package com.test;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
 
import com.infinity.bpm.portal.common.LaunchPanel;
import com.infinity.bpm.portal.common.PerspectiveDefinition;
import com.infinity.bpm.portal.common.ViewDefinition;
 
public class PortalUIPostProcessor implements BeanPostProcessor {
 
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanId)
			throws BeansException {
 
		if (bean instanceof PerspectiveDefinition) {
			PerspectiveDefinition perspectiveBean = (PerspectiveDefinition) bean;			
			if (perspectiveBean.getName().equals("ippBccPerspective")) {
				perspectiveBean.setExcludeRoles(perspectiveBean
							.getExcludeRoles() + ",{SidsIssueModel}Role_2");				
			}
		}
 
		if (bean instanceof ViewDefinition) {			
			ViewDefinition view = (ViewDefinition) bean;			
			if(view.getName().equals("documentSearchView") 
                           || view.getName().equals("processInstanceDetailsView") ){
				view.setExcludeRoles(view.getExcludeRoles()+ ",{SidsIssueModel}Role_2");
			}			
		}
 
		if (bean instanceof LaunchPanel) {
			LaunchPanel lp = (LaunchPanel) bean;
			if(lp.getName().equals("managementViews")){
				lp.setExcludeRoles(lp.getExcludeRoles()+ ",{SidsIssueModel}Role_2");				
			}
		}
 
 
		return bean;
	}
 
	@Override
	public Object postProcessBeforeInitialization(Object bean, String arg1)
			throws BeansException {
		return bean;
	}
}

Example Implementation 2

This post processor overrides the required roles for the different portal perspectives and externalizes the configuration into its own spring configuration. The benefit is that a project can maintain this customization independent of the original product. The original portal jar does not have to be modified.

<bean id="requiredRolesPostProcessor" class="org.eclipse.stardust.portal.postproc.RequiredRolesPostProcessor">
  <property name="bccRequiredRoles" value="BCC"/>
  <!--	
  <property name="adminRequiredRoles" value="Administrator"/>
  <property name="workflowRequiredRoles" value=""/>
  -->
</bean>
package org.eclipse.stardust.portal.postproc;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
 
import com.infinity.bpm.portal.common.IPerspectiveDefinition;
import com.infinity.bpm.portal.common.log.LogManager;
import com.infinity.bpm.portal.common.log.Logger;
 
public class RequiredRolesPostProcessor implements BeanPostProcessor {
 
	private String bccRequiredRoles;
	private String adminRequiredRoles;
	private String workflowRequiredRoles;
 
	public static final Logger log = LogManager
			.getLogger(RequiredRolesPostProcessor.class);
 
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
 
		if (bean instanceof IPerspectiveDefinition) {
			// ippAdminPerspective requires Administrator
			// ippBccPerspective requires null
			// WorkflowExecution requires null
			log.debug("RequiredRolesPostProcessor configured.");
 
			IPerspectiveDefinition pd = (IPerspectiveDefinition) bean;
			String requireRoles = pd.getRequiredRoles();
 
			if (pd.getName().equals("ippBccPerspective")
					&& (getBccRequiredRoles() != null)
					&& !getBccRequiredRoles().equals(requireRoles)) {
				log
						.info("Overriding required roles for ippBccPerspectivePerspective ("
								+ requireRoles
								+ ") with: "
								+ getBccRequiredRoles());
				pd.setRequiredRoles(getBccRequiredRoles());
			}
 
			if (pd.getName().equals("ippAdminPerspective")
					&& (getAdminRequiredRoles() != null)
					&& !getAdminRequiredRoles().equals(requireRoles)) {
				log.info("Overriding required roles for ippAdminPerspective ("
						+ requireRoles + ") with: " + getAdminRequiredRoles());
				pd.setRequiredRoles(getAdminRequiredRoles());
			}
 
			if (pd.getName().equals("WorkflowExecution")
					&& (getWorkflowRequiredRoles() != null)
					&& !getWorkflowRequiredRoles().equals(requireRoles)) {
				log
						.info("Overriding required roles for WorkflowExecutionPerspective ("
								+ requireRoles
								+ ") with: "
								+ getWorkflowRequiredRoles());
				pd.setRequiredRoles(getWorkflowRequiredRoles());
			}
		}
 
		return bean;
	}
 
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
 
		return bean;
	}
 
	public String getBccRequiredRoles() {
		return bccRequiredRoles;
	}
 
	public void setBccRequiredRoles(String bccRequiredRoles) {
		this.bccRequiredRoles = bccRequiredRoles;
	}
 
	public String getAdminRequiredRoles() {
		return adminRequiredRoles;
	}
 
	public void setAdminRequiredRoles(String adminRequiredRoles) {
		this.adminRequiredRoles = adminRequiredRoles;
	}
 
	public String getWorkflowRequiredRoles() {
		return workflowRequiredRoles;
	}
 
	public void setWorkflowRequiredRoles(String workflowRequiredRoles) {
		this.workflowRequiredRoles = workflowRequiredRoles;
	}
 
}

Back to the top