- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-30-2014 11:12 AM
How to reference current record fields in an encoded query for a Before/Query business rule
We would be to use a Before/Query business rule that would filter the records based on the user's role. We can do this from an ACL but this is problematic, because most records will be blocked by the ACL and will result in only a couple of records on each of the list pages. Each page will include a "Number of rows removed from this list by Security constraints" message, where the user must page forward through many screens to find the few records that they need to access.
There does not seem to be a way to build the query based on a value in the "current" record object. The "current" record object can be accessed in the ACL script, but it
cannot be accessed from the script in the before Before/Query business rule.
For example:
Assume that a record has a field titled "Role"
How do you build a query string such as gs.hasRole(current.role)?
This will work in the ACL, but there does not appear to be a way to get it into an encoded record query for the Before/Query business rule.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-02-2014 12:45 PM
Hi @Robert Barnes
Thanks for clarifying your question.
Since you would like to make roles dynamic I would use a function to find all the roles and adding it into the query.
Following is something that can be done:
var encodedQuery = '';
var userRoles = _getLoggedInUserRoles();
encodedQuery = encodedQuery + '^ORrolesCONTAINS'+userRoles;
current.addEncodedQuery(encodedQuery);
function _getLoggedInUserRoles(){
userRoles = [];
var grHasRole = new GlideRecord('sys_user_has_role');
grHasRole.addQuery('user',gs.getUserID());
grHasRole.query();
while(grHasRole.next()) {
userRoles.push(grHasRole.role.name);
}
return userRoles;
}
I hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-01-2014 07:11 AM
Since you want to use before query business rule, you need to apply addQuery function.
For Ex:
if (!gs.hasRole("admin") && gs.getSession().isInteractive()) {
//Check to see if this is a query for a specific ID
if (current.getEncodedQuery().indexOf('sys_id=') != 0) {
current.addQuery("operational_status", "1");
}
}
I hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-01-2014 01:02 PM
That is similar to how we are currently doing it.
The following code sample assumes that the table as a field column titled "roles". The scenario is that each data record can be associated with one or more roles. The user should only be able to access records for which they have a role.
[code]
var encodedQuery = '';
if ( gs.hasRole('role1') ) {
encodedQuery = encodedQuery + '^ORrolesCONTAINSrole1';
}
if ( gs.hasRole('role2') ) {
encodedQuery = encodedQuery + '^ORrolesCONTAINSrole2';
}
if ( gs.hasRole('role3') ) {
encodedQuery = encodedQuery + '^ORrolesCONTAINSrole3';
}
current.addEncodedQuery(encodedQuery);
[/code]
The code above actually works but, we would like a more transparent query that does not require ongoing maintenance as new roles are added. The following example illustrates the objective, but there does not seem to be a way to pass a reference to the current object field into a function.
[code]
var encodedQuery = 'gs.hasRole(current.roles)=true';
//var encodedQuery = 'gs.hasRole(roles)=true'; // also fails
current.addEncodedQuery(encodedQuery);
[/code]
if the encoded queries above are printed afterwards it will display the following
NULL=true
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-02-2014 12:45 PM
Hi @Robert Barnes
Thanks for clarifying your question.
Since you would like to make roles dynamic I would use a function to find all the roles and adding it into the query.
Following is something that can be done:
var encodedQuery = '';
var userRoles = _getLoggedInUserRoles();
encodedQuery = encodedQuery + '^ORrolesCONTAINS'+userRoles;
current.addEncodedQuery(encodedQuery);
function _getLoggedInUserRoles(){
userRoles = [];
var grHasRole = new GlideRecord('sys_user_has_role');
grHasRole.addQuery('user',gs.getUserID());
grHasRole.query();
while(grHasRole.next()) {
userRoles.push(grHasRole.role.name);
}
return userRoles;
}
I hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-02-2014 01:29 PM
That is a good suggestion and the same approach has been confirmed by others. The only additional point is that some users have a significant number of roles so we had to tweek the _getLoggedInUserRoles to filter out the standard out of the box roles so that it only returned roles that were for the record level security.