Name

global.FlowDesignerContentFiltering

Description

Evaluate Flow Designer resource filter rules against a record in a Flow Designer content table

Script

var FlowDesignerContentFiltering = Class.create();
FlowDesignerContentFiltering.prototype = {
  initialize: function() {},
  
  canCreate: function(contentGr) {
  	return this._isAllowedByContentFiltering(contentGr);
  },
  
  canRead: function(contentGr) {
  	return this._isAllowedByContentFiltering(contentGr);
  },
  
  _isAllowedByContentFiltering: function(contentGr){
  	if (gs.getProperty('com.glide.hub.flow.disable_content_filtering', 'false') == 'true')
  		return true;


  	if (contentGr.sys_created_by == gs.getUserName())
  		return true;
  	
  	var tableHierarchy = this._getTableHierarchyFor(contentGr);
  	if (this._isBlacklisted(contentGr, tableHierarchy, true))
  		return false;
  	
  	if (this._isWhiteListed(contentGr, tableHierarchy))
  		return true;
  	
  	return false;
  },
  
  _isBlacklisted: function(contentGr, tableHierarchy) {
  	if (this._evaluateFilterRules(contentGr, tableHierarchy, true))
  		return true;
  	
  	return false;
  },
  
  _isWhiteListed: function(contentGr, tableHierarchy) {
  	if (this._evaluateFilterRules(contentGr, tableHierarchy, false))
  		return true;
  	
  	return false;
  },
  
  _evaluateFilterRules: function(contentGr, tableHierarchy, isBlackList) {		
  	var gr = new GlideRecord('sys_hub_resource_filter_rule');
  	gr.addQuery('resource.table', 'IN', tableHierarchy);
  	var qc = gr.addQuery('sys_scope', 'global');
  	qc.addOrCondition('sys_scope', contentGr.sys_scope);
  	
  	if (isBlackList)
  		gr.addQuery('filter_type','blacklist');
  	else
  		gr.addQuery('filter_type', '!=', 'blacklist').addOrCondition('filter_type', '');
  	
  	gr.addActiveQuery();
  	gr.query();
  	while(gr.next()) {
  		if (!gr.resource)
  			continue;

  		if (!this._evaluateUserRoles(gr))
  			continue;
  		
  		var conditionEmpty = GlideStringUtil.nil(gr.resource.conditions);
  		var conditionTrue = GlideFilter.checkRecord(contentGr, gr.resource.conditions);
  		var tagsSatisfied = this._hasRequiredLabelEntries(gr, contentGr, tableHierarchy);
  		if ((conditionEmpty || conditionTrue) && tagsSatisfied) {
  			return true;
  		}
  	}
  	
  	return false;
  },
  
  _evaluateUserRoles: function(ruleGr) {
  	if (GlideStringUtil.nil(ruleGr.role))
  		return false;
  	
  	return gs.getSession().hasRole(ruleGr.role);
  },
  
  _getTableHierarchyFor: function(contentGr) {
  	// We could expand to sibling extended tables by using
  	// tableUtils.getAbsoluteBase() before calling getHierarchy()
  	
  	var tableUtils = new TableUtils(contentGr.getTableName());
  	var tableHierarchy = tableUtils.getHierarchy();
  	return GlideStringUtil.join(tableHierarchy);
  },
  
  _getTagsFor: function(contentGr, tableHierarchy) {
  	var tagMap = {};
  	var labelEntries = new GlideRecord('label_entry');
  	labelEntries.addQuery('table', 'IN', tableHierarchy);
  	labelEntries.addQuery('table_key', contentGr.getUniqueValue());
  	labelEntries.query();
  	while(labelEntries.next())
  		tagMap[labelEntries.label] = true;
  	
  	return tagMap;
  },
  
  _hasRequiredLabelEntries: function(ruleGr, contentGr, tableHierarchy) {
  	if (!ruleGr.resource || !ruleGr.resource.resource_tags)
  		return true;
  	
  	this.tagMap = this.tagMap || this._getTagsFor(contentGr, tableHierarchy); //Memoize tag map
  	var resourceTags = ruleGr.resource.resource_tags.split(',');
  	for (var i = 0; i < resourceTags.length; i++) {
  		if (!this.tagMap[resourceTags[i]])
  			return false;
  	}
  	
  	return true;
  },
  
  type: 'FlowDesignerContentFiltering'
};

Sys ID

52a2e9510f230010f4166fe7c4767e1f

Offical Documentation

Official Docs: