
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
User criteria is one of the wonderful features SN provided, but it is opened to only a set of tables. It is a handy configuration to grant access to the record against user information like companies, roles, groups.
Recently there was a requirement where we need to grant read access to records dynamically. After a little research, I found out that there are similar needs by many developers. Below are some of scenarios that I came across
- Catalogs
- News
- Announcements(Fixed in London)
Here is what I had implemented
1. Create a m2m relation between User Criteria and desired table (u_news). Navigate to sys_m2m.LIST and submit the details as shown in the screenshot
2. Add the user criteria related list to News form by Configure > Related Lists
3. Create a script include
Name: UserCriteria
Client callable: False
Script
var UserCriteria = Class.create();
UserCriteria.prototype = {
initialize: function() {
},
canAccess: function(table, record, id){
//Get all the user criteria's for the seleted record
var usr_crit = new GlideRecord(table);
usr_crit.addQuery(record, id);
usr_crit.query();
// Grant access to record If there are no user criteria's for the record
if(usr_crit.getRowCount() == 0)
return true;
while (usr_crit.next()) {
var crit = new GlideRecord('user_criteria');
crit.addQuery('sys_id', usr_crit.u_user_criteria);
crit.addActiveQuery();
crit.query();
while(crit.next()){
//Get company, location and department information of the current user.
var gr = new GlideRecord('sys_user');
gr.addQuery('sys_id', gs.getUserID());
gr.query();
var company, location, department = '';
if(gr.next()){
company = gr.company;
location = gr.location;
department = gr.department;
}
var groups = [];
groups = crit.group.toString();
var evaluator = new GlideScopedEvaluator();
var match_arr = [];
// Check if the current user is one of the users in user criteria
if(crit.user != ''){
if(crit.user.indexOf(gs.getUserID()) > -1)
match_arr.push(true);
else
match_arr.push(false);
}
// Check if the Groups of a user belong to is one of groups in user criteria
if(crit.group!= ''){
match_arr.push(this._isMyGroup(groups));
}
// Check if logged in user roles is one of roles in user criteria
if(crit.role != ''){
match_arr.push(gs.hasRole(crit.role.getDisplayValue()));
}
// Check if the logged in user company is one of companies in user criteria
if(crit.company != '' && company != ''){
if(crit.company.indexOf(company) > -1)
match_arr.push(true);
else
match_arr.push(false);
}
// Check if the logged in user location is one of locations in user criteria
if(crit.location != '' && location != ''){
if(crit.location.indexOf(location) > -1)
match_arr.push(true);
else
match_arr.push(false);
}
// Check if the logged in user department is one of departments in user criteria
if(crit.department != '' && department != ''){
if(crit.department.indexOf(department) > -1)
match_arr.push(true);
else
match_arr.push(false);
}
//execute the script in user criteria
if(crit.advanced == true){
match_arr.push(evaluator.evaluateScript(crit, 'script', ''));
}
var matched;
//If Match all, in user criteria is marked false, then any one of fields match is enough
if(crit.match_all == false){
if(match_arr.indexOf(true) > -1)
matched = true;
else
matched = false;
}
// If Match all is marked true then all of the values should be true
else{
if(match_arr.every(this._isValueTrue) == true)
matched = true;
else
matched = false;
}
// Matching one of the user criteria should return the value. No need to execute the rest of the user criteria
if(matched == true){
return true;
}
}
}
// If none of the user criteria matches then return false
return false;
},
_isMyGroup: function(groupIDs){
var groups_arr = groupIDs.split(',');
for(i=0; i<groups_arr.length; i++){
if(gs.getUser().isMemberOf(groups_arr[i]))
return true;
}
return false;
},
// Function to verify if all the values in an array are true
_isValueTrue: function (currentValue) {
return currentValue == true;
},
type: 'UserCriteria'
};
4. Create a read acl to restrict read access to the record and use the below script
answer = new UserCriteria().canAccess('u_m2m_news_user_criteria', 'u_news', current.sys_id);
/* canAccess menthod accepts the following input paramenters
table: M2M table name
record: Field name of News reference field on M2M table
id: sys_id of news record
*/
5. Use GlideRecordSecure for reference qualifers and glide queries, as GlideRecordSecure enforce read ACL rules.
Hope this helps!!
- 4,731 Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.