Skip to Content
Technical Articles

How to use the SDK to create a Security Rights Overview of an Enterprise System

Overview

The security rights and limits on an Enterprise system can be quite complicated and it can be difficult to get an overview of how your security is set up.  I created this sample to get an overview of how the rights / limits are set up on an Enterprise system.

Note: If you are just interested in the security rights for a single object / user, then a better tool to use is the BI Platform Support Tool.  If you run the tool and go to Landscape Tools -> Security Analyzer you can browse through the objects on your Enterprise system one by one and see what the rights are for specific users / groups on those objects.

This sample is written against SAP BusinessObjects Enterprise 4.2 SP6, but it should work with all BI 4.1 and BI 4.2 patch levels.  It will not work with Enterprise XI 3.1

Download Links:

The JSP code is pasted at the bottom of this blog.  Both the code and the sample crystal report can be downloaded from kbase 2831004

The Open Source Jackcess tool can be downloaded from here.

How Does it Work

This sample uses the open source tool Jackcess to create a MS Access database.  It then uses the Enterprise Platform SDK to scan all objects on the Enterprise system and populates the database with the rights and limits that are set.  That database can then be reported off of to get an overview of the security for the Enterprise system.  I have included a sample Crystal Report which demonstrates how to do this.

How to Use It

  1. Download the Jackess jar file from here  (Look for the “Download Latest Version” button)
  2. Copy the Jackcess jar file into the AdminTools lib folder on your Enterprise Server (C:\Program Files (x86)\SAP BusinessObjects\tomcat\webapps\AdminTools\WEB-INF\lib)
  3. Restart Tomcat (Whenever you add a file to the lib directory you must restart the app server. Adding or modifying a jsp file as per step 4 does not require a restart)
  4. Download the jsp sample page and copy it into the AdminTools folder (C:\Program Files (x86)\SAP BusinessObjects\tomcat\webapps\AdminTools)
  5. Edit the JSP sample page and modify the following section:
    String username = "Administrator";
    String password = "Password1";
    String cmsname  = "<MyServer>";
    String authType = "secEnterprise";
    String dbPath = "C:\\Program Files (x86)\\SAP BusinessObjects\\tomcat\\webapps\\AdminTools\\secScan.mdb";​

    You will need to change the logon credentials and cmsname to match your Enterprise system. You will also need to change the dbPath variable to where you want the Access Database to be created.

    Note: If a DB file already exists in the file location, it will be overwritten when the sample runs.

  6. Run the sample by opening a browser and going to http://MyServer:8080/AdminTools/jsp_securityscan.jsp
  7. Download the sample Crystal Report from kbase 2831004
  8. Create a 32 Bit ODBC DSN called “SecScan” for MS Access that points to the secScan.mdb database file created in step 6.
  9. Launch the sample Crystal Report (SecurityReport.rpt) and refresh it.

The Code

<%@page import="com.crystaldecisions.sdk.exception.SDKException" %>
<%@page import="com.crystaldecisions.sdk.occa.infostore.*" %>
<%@page import="com.crystaldecisions.sdk.framework.*" %>
<%@page import="com.crystaldecisions.sdk.plugin.desktop.common.*" %>
<%@page import="com.crystaldecisions.sdk.plugin.desktop.user.*" %>
<%@page import="com.crystaldecisions.sdk.occa.infostore.IRightID" %>
<%@page import="com.crystaldecisions.sdk.occa.infostore.IObjectPrincipal" %>
<%@page import="com.crystaldecisions.sdk.occa.infostore.ISecurityRights" %>
<%@page import="com.crystaldecisions.sdk.occa.infostore.ISecurityRight" %>
<%@page import="com.crystaldecisions.sdk.occa.infostore.CeSecurityID" %>
<%@page import="com.crystaldecisions.sdk.plugin.desktop.usergroup.*" %>

<%@page import="com.healthmarketscience.jackcess.*" %>
<%@page import="com.healthmarketscience.jackcess.util.*" %>

<%@page import="java.sql.*" %>
<%@page import="java.util.*" %>
<%@page import="java.io.*" %>
  
<%
// Special notes:
// Access stores true as -1 and false as 0

// User Credentials
String username = "Administrator";
String password = "Password1";
String cmsname  = "<MyServer>";
String authType = "secEnterprise";
String dbPath = "C:\\Program Files (x86)\\SAP BusinessObjects\\tomcat\\webapps\\AdminTools\\secScan.mdb";


IEnterpriseSession enterpriseSession  = null;
IInfoStore infoStore;
IInfoObjects boInfoObjects; 

int max_id;
String writeToFile;
  
enterpriseSession = CrystalEnterprise.getSessionMgr().logon(username, password, cmsname, authType);
infoStore = (IInfoStore)enterpriseSession.getService("", "InfoStore");

// Create the new database
com.healthmarketscience.jackcess.Database db = DatabaseBuilder.create(Database.FileFormat.V2000, new File(dbPath));

Table UserGroupTable = new TableBuilder("UsersAndGroups")
	.addColumn(new ColumnBuilder("UserID", DataType.LONG))
    .addColumn(new ColumnBuilder("Name", DataType.TEXT))
    .addColumn(new ColumnBuilder("IsUser", DataType.BOOLEAN))
	.setPrimaryKey("UserID")
    .toTable(db);

Table UserGroupMemberShipTable = new TableBuilder("UserGroupMemberShip")
	.addColumn(new ColumnBuilder("UserID", DataType.LONG))
    .addColumn(new ColumnBuilder("MemberOf", DataType.LONG))
    .toTable(db);

Table EnterpriseObjectsTable = new TableBuilder("EnterpriseObjects")
	.addColumn(new ColumnBuilder("ObjectID", DataType.LONG))
    .addColumn(new ColumnBuilder("ObjectName", DataType.TEXT))
	.addColumn(new ColumnBuilder("ObjectKind", DataType.TEXT))
	.setPrimaryKey("ObjectID")
    .toTable(db);
	
Table AccessLevelsTable = new TableBuilder("AccessLevels")
	.addColumn(new ColumnBuilder("LevelID", DataType.LONG))
    .addColumn(new ColumnBuilder("LevelName", DataType.TEXT))
	.setPrimaryKey("LevelID")
    .toTable(db);
	
Table ExplicitSecurityRightTable = new TableBuilder("ExplicitSecurityRight")
	.addColumn(new ColumnBuilder("SecurityRightID", DataType.LONG))
    .addColumn(new ColumnBuilder("SecurityRightName", DataType.TEXT))
	.addColumn(new ColumnBuilder("UserID", DataType.LONG))
	.addColumn(new ColumnBuilder("ObjectID", DataType.LONG))
	.addColumn(new ColumnBuilder("isGranted", DataType.BOOLEAN))
    .toTable(db);

Table AccessLevelSecurityRightTable = new TableBuilder("AccessLevelSecurityRight")
	.addColumn(new ColumnBuilder("LevelID", DataType.LONG))
	.addColumn(new ColumnBuilder("UserID", DataType.LONG))
	.addColumn(new ColumnBuilder("ObjectID", DataType.LONG))
    .toTable(db);
	
Table LimitsTable = new TableBuilder("Limits")
	.addColumn(new ColumnBuilder("UserID", DataType.LONG))
	.addColumn(new ColumnBuilder("ObjectID", DataType.LONG))
	.addColumn(new ColumnBuilder("LimitPluginType", DataType.TEXT))
	.addColumn(new ColumnBuilder("LimitDescription", DataType.TEXT))
	.addColumn(new ColumnBuilder("LimitScope", DataType.TEXT))
	.addColumn(new ColumnBuilder("LimitValue", DataType.LONG))
    .toTable(db);

Relationship.JoinType dbJoin = Relationship.JoinType.INNER;
	
Relationship rel1 = new RelationshipBuilder("UsersAndGroups", "UserGroupMemberShip")
     .addColumns("UserID", "UserID")
	 .setJoinType(dbJoin)
     .toRelationship(db);
	 
Relationship rel2 = new RelationshipBuilder("UsersAndGroups", "ExplicitSecurityRight")
     .addColumns("UserID", "UserID")
	 .setJoinType(dbJoin)
     .toRelationship(db);	 
	 
Relationship rel3 = new RelationshipBuilder("EnterpriseObjects", "ExplicitSecurityRight")
     .addColumns("ObjectID", "ObjectID")
	 .setJoinType(dbJoin)
     .toRelationship(db);	
	
Relationship rel4 = new RelationshipBuilder("UsersAndGroups", "AccessLevelSecurityRight")
     .addColumns("UserID", "UserID")
	 .setJoinType(dbJoin)
     .toRelationship(db);	 
	 
Relationship rel5 = new RelationshipBuilder("EnterpriseObjects", "AccessLevelSecurityRight")
     .addColumns("ObjectID", "ObjectID")
	 .setJoinType(dbJoin)
     .toRelationship(db);	

Relationship rel6 = new RelationshipBuilder("AccessLevels", "AccessLevelSecurityRight")
     .addColumns("LevelID", "LevelID")
	 .setJoinType(dbJoin)
     .toRelationship(db);	
	 
Relationship rel7 = new RelationshipBuilder("UsersAndGroups", "Limits")
     .addColumns("UserID", "UserID")
	 .setJoinType(dbJoin)
     .toRelationship(db);	
	 
Relationship rel8 = new RelationshipBuilder("EnterpriseObjects", "Limits")
     .addColumns("ObjectID", "ObjectID")
	 .setJoinType(dbJoin)
     .toRelationship(db);	
	
// Start with Users
max_id = 0;

for(;;) { 
	boInfoObjects = (IInfoObjects)infoStore.query("Select * FROM CI_SYSTEMOBJECTS WHERE SI_PROGID = 'CrystalEnterprise.User' And SI_ID > " + max_id +  " ORDER BY SI_ID ASC");
                                               
    if(boInfoObjects.size() == 0) 
		break;

	for(Iterator boCount = boInfoObjects.iterator(); boCount.hasNext(); ) {
		IInfoObject boObject = (IInfoObject)boCount.next();
		
		UserGroupTable.addRow(boObject.getID(), boObject.getTitle(),true);

        IUser boUser=(IUser)boObject;
        Set groupIDs = boUser.getGroups();
		for(Iterator boGroupCount = groupIDs.iterator(); boGroupCount.hasNext(); ) {
			int boGroupID = (int)boGroupCount.next();
			UserGroupMemberShipTable.addRow(boObject.getID(), boGroupID);
		}
		max_id = boObject.getID();
	}
}

// Now do the groups
max_id = 0;

for(;;) { 
	boInfoObjects = (IInfoObjects)infoStore.query("Select * FROM CI_SYSTEMOBJECTS WHERE SI_PROGID = 'CrystalEnterprise.UserGroup' And SI_ID > " + max_id +  " ORDER BY SI_ID ASC");
                                               
    if(boInfoObjects.size() == 0) 
		break;

	for(Iterator boCount = boInfoObjects.iterator(); boCount.hasNext(); ) {
		IInfoObject boObject = (IInfoObject)boCount.next();
			
		UserGroupTable.addRow(boObject.getID(), boObject.getTitle(),false);

        IUserGroup boGroup=(IUserGroup)boObject;
        Set groupIDs = boGroup.getParentGroups();
		for(Iterator boGroupCount = groupIDs.iterator(); boGroupCount.hasNext(); ) {
			int boGroupID = (int)boGroupCount.next();
			UserGroupMemberShipTable.addRow(boObject.getID(), boGroupID);
		}
	
		max_id = boObject.getID();
	}
}

// Now retrieve all Access Levels (roles)
max_id = 0;

for(;;) { 
	boInfoObjects = (IInfoObjects)infoStore.query("Select * FROM CI_SYSTEMOBJECTS WHERE SI_PROGID = 'CrystalEnterprise.CustomRole' And SI_ID > " + max_id +  " ORDER BY SI_ID ASC");
                                               
    if(boInfoObjects.size() == 0) 
		break;

	for(Iterator boCount = boInfoObjects.iterator(); boCount.hasNext(); ) {
		IInfoObject boObject = (IInfoObject)boCount.next();
			
		AccessLevelsTable.addRow(boObject.getID(), boObject.getTitle());
		max_id = boObject.getID();
	}
}

// Now loop through all the infoobjects on the system

max_id = 0;

	for(;;) { 
        boInfoObjects = (IInfoObjects)infoStore.query("Select * FROM CI_INFOOBJECTS where SI_ID > " + max_id +  " ORDER BY SI_ID ASC");
                                               
        if(boInfoObjects.size() == 0) 
            break;

		for(Iterator boCount = boInfoObjects.iterator() ; boCount.hasNext() ; ) {
            IInfoObject boObject = (IInfoObject)boCount.next();
            
			// First add the object to the EnterpriseObject table
			EnterpriseObjectsTable.addRow(boObject.getID(), boObject.getTitle(),boObject.getKind());
			
			// Get SecurityInfo for the object
			ISecurityInfo2 objSecurity = boObject.getSecurityInfo2();
			
			// Get Explicit Security Principals 
			IExplicitPrincipals boExplicitPrincipals = objSecurity.getExplicitPrincipals();
			
			// Loop through all principals (users or groups) who have explicit rights / roles / limits on this object
			for(Iterator iPrincipal = boExplicitPrincipals.iterator(); iPrincipal.hasNext(); ) {
				IExplicitPrincipal boExplicitPrincipal = (IExplicitPrincipal)iPrincipal.next();
    
				// Loop through all roles on the object for the specific principal (This is not inherited roles - only explicit ones)
				for(Iterator irole = boExplicitPrincipal.getRoles().iterator(); irole.hasNext(); ) {
					IExplicitRole boExplicitRole = (IExplicitRole)irole.next();
					AccessLevelSecurityRightTable.addRow(boExplicitRole.getID(), boExplicitPrincipal.getID(), boObject.getID());
				}
				
				// Loop through all rights on the object for the specific principal (This is not inherited rights - only explicit ones)
				for(Iterator iright = boExplicitPrincipal.getRights().iterator(); iright.hasNext(); ) {
					IExplicitRight boExplicitRight = (IExplicitRight)iright.next();
					ExplicitSecurityRightTable.addRow(boExplicitRight.getID(), boExplicitRight.getDescription(Locale.getDefault()), boExplicitPrincipal.getID(), boObject.getID(), boExplicitRight.isGranted());
				}
				
				// Loop through all limits on the object for the specific principal (This is not inherited limits - only explicit ones)
				for(Iterator ilimit = boExplicitPrincipal.getLimits().iterator(); ilimit.hasNext(); ) {
					IExplicitLimit boExplicitLimit = (IExplicitLimit)ilimit.next();
					LimitsTable.addRow(boExplicitPrincipal.getID(), boObject.getID(), boExplicitLimit.getApplicableKind(), boExplicitLimit.getDescription(Locale.getDefault()), boExplicitLimit.getScope(), boExplicitLimit.getValue());
				}
			}
            max_id = boObject.getID();
        }
	}

	db.close();
	out.println("Job Completed");
%>

 

Screenshots of what an example report looks like

1 Comment
You must be Logged on to comment or reply to a post.