Name

sn_cd.cd_ContentDelegationUtils

Description

API audience & content delegation

Script

var cd_ContentDelegationUtils = Class.create();
cd_ContentDelegationUtils.prototype = {
  initialize: function() {
  },
  
  /** Return ref qual with contents delegated to current user
  * @return content allowed for current user
  */
  getMyDelegatedContent: function() {
  	return this._getMyDelegatedRecords('sn_cd_content_base');
  },
  
  /** Return ref qual with block contents delegated to current user
  * @return content allowed for current user
  */
  getMyDelegatedBlockContent: function() {
  	return this._getMyDelegatedRecords('sn_cd_block');
  },
  
  /** Return ref qual with link contents delegated to current user
  * @return content allowed for current user
  */
  getMyDelegatedLinkContent: function() {
  	return this._getMyDelegatedRecords('sn_cd_url_asset');
  },
  
  /** Return ref qual with audiences delegated to current user
  * @return audiences allowed for current user
  */
  getMyDelegatedAudience: function() {
  	return this._getMyDelegatedRecords('sn_cd_audience');
  },
  
  _getMyDelegatedRecords: function (tableName){
  	var isCDPropertyOn = tableName == "sn_cd_audience" ? gs.getProperty('sn_cd.activate_audience_delegation_controls') == 'true' : gs.getProperty('sn_cd.activate_content_authoring_controls') == 'true';
  	
  	if (!isCDPropertyOn)
  		return '';
  	if (gs.getUser().hasRole('sn_cd.content_admin')) 
  		return '';
  	
  	var object = this._getDelegatedTablesAndField(tableName);
  	if (!object)
  		return;
  	
  	var fieldName = object.fieldName;
  	var delegatedUserTable = object.delegatedUserTable;
  	var delegatedGroupTable = object.delegatedGroupTable;
  	
  	if (tableName == 'sn_cd_audience') {
  		fieldName = 'audience';
  		delegatedUserTable = 'sn_cd_audience_delegated_user';
  		delegatedGroupTable = 'sn_cd_audience_delegated_group';
  	} else {
  		delegatedUserTable = 'sn_cd_content_authoring_user';
  		delegatedGroupTable = 'sn_cd_content_authoring_group';
  		if (tableName == 'sn_cd_content_base') 
  			fieldName = 'content';
  		else if (tableName == 'sn_cd_url_asset') 
  			fieldName = 'link_content';
  		else if (tableName == 'sn_cd_block') 
  			fieldName = 'block_content';
  		else
  			return;
  	}
  	
  	var notMyDelegations = [];
  	var allowedRecords = [];
  	var myGroups = gs.getUser().getMyGroups();
  	
  	var gr = new GlideRecord(delegatedUserTable);
  	gr.addQuery('user', gs.getUserID());
  	gr.query();
  	while (gr.next())
  		allowedRecords.push(gr.getValue(fieldName));
  	
  	if (myGroups.length > 0) {
  		gr = new GlideRecord(delegatedGroupTable);
  		gr.addQuery('group', 'IN', myGroups);
  		gr.query();
  		while(gr.next())
  			allowedRecords.push(gr.getValue(fieldName));
  	}
  	
  	var allDelegatedRecords = new GlideAggregate(delegatedUserTable);
  	allDelegatedRecords.groupBy(fieldName);
  	for (var i = 0; i<allowedRecords.length; i++)
  		allDelegatedRecords.addQuery(fieldName, '!=', allowedRecords[i]);
  	allDelegatedRecords.query();   
  	while (allDelegatedRecords.next()) 
  		notMyDelegations.push(allDelegatedRecords.getValue(fieldName));

  	allDelegatedRecords = new GlideAggregate(delegatedGroupTable);
  	allDelegatedRecords.groupBy(fieldName);
  	for (i = 0; i < allowedRecords.length; i++)
  		allDelegatedRecords.addQuery(fieldName, '!=', allowedRecords[i]);
  	allDelegatedRecords.query();   
  	while (allDelegatedRecords.next())  
  		notMyDelegations.push(allDelegatedRecords.getValue(fieldName));
  	
  	allowedRecords = [];
  	gr = new GlideRecord(tableName);
  	for (i = 0; i < notMyDelegations.length; i++)
  		gr.addQuery('sys_id', '!=', notMyDelegations[i]);
  	gr.query();
  	while(gr.next())
  		allowedRecords.push(gr.getUniqueValue());
  	return 'sys_idIN' + allowedRecords;
  },
  
  /** Return list of topics current user is not authorized to that user is attempting to modify
   * @param current & previous [sn_cd_content_visibility]
   * @return array of topics not part of the current users delegation
   */
  getModifiedRestrictedTopics: function(current, previous) {
  	var currentArr = current.topic.toString().split(',');
  	var previousArr = previous.topic.toString().split(',');
  	var diff = this._arrayDiff(currentArr, previousArr);
  	return this.getRestrictedTopicsFromList(diff);
  },
  
  /** Return page that current user is not authorized to that user is attempting to modify
   * @param current [sn_cd_content_visibility]
   * @return page not part of the current users delegation
   */
  getModifiedRestrictedPage: function(current, previous) {
  	var currentArr = current.sp_page.toString().split(',');
  	var previousArr = previous.sp_page.toString().split(',');
  	var diff = this._arrayDiff(currentArr, previousArr);
  	return this.getRestrictedRecordsFromList(diff, 'sp_page');
  },
  
  /** Return list of audiences current user is not delegated to
  * @param current & previous glideRecords 
  * @return array of audiences not part of current users delegation
  */
  getModifiedRestrictedAudiences: function (current, previous) {
  	var currentArr = current.audience.toString().split(',');
  	var previousArr = previous.audience.toString().split(',');
  	var diff = this._arrayDiff(currentArr, previousArr);
  	return this.getRestrictedAudiencesFromList(diff);
  },
  
  _arrayDiff: function (currentValues, previousValues) {
  	var a = [], diff = [];
  	for (var i = 0; i < currentValues.length; i++) 
  		a[currentValues[i]] = true;
  	for (i = 0; i < previousValues.length; i++) {
  		if (a[previousValues[i]]) 
  			delete a[previousValues[i]];
  		else 
  			a[previousValues[i]] = true;
  	}
  	for (var k in a)
  		diff.push(k);
  	return diff;
  },
  
  /** Return list of topics current user is not authorized to
   * @param topicIds
   * @return array of topics not part of the current users authorization
   */
  getRestrictedTopicsFromList: function(topicIds) {
  	var restrictedTopics = [];
  	for (var i = 0; i < topicIds.length; i++)
  		if (!this._isMyDelegatedRecord(topicIds[i], 'topic'))
  			restrictedTopics.push(topicIds[i]);
  	// Get display names for error message
  	var topicDisplayValues = [];
  	var topicGr = new GlideRecord('topic');
  	topicGr.addQuery('sys_id', 'IN', restrictedTopics);
  	topicGr.query();
  	while (topicGr.next())
  		topicDisplayValues.push(topicGr.getDisplayValue());
  	return topicDisplayValues;
  },
  
  /** Return list of records current user is not authorized to
   * @param sysIds
   * @return array of records not part of the current users authorization
   */
  getRestrictedRecordsFromList: function(sysIds, tableName) {
  	var restrictedRecords = [];
  	for (var i = 0; i < sysIds.length; i++)
  		if (!this._isMyDelegatedRecord(sysIds[i], tableName))
  			restrictedRecords.push(sysIds[i]);
  	
  	// Get display names for error message
  	var recordDisplayValues = [];
  	var tableGr = new GlideRecord(tableName);
  	tableGr.addQuery('sys_id', 'IN', restrictedRecords);
  	tableGr.query();
  	while (tableGr.next())
  		recordDisplayValues.push(tableGr.getDisplayValue());
  	
  	return recordDisplayValues;
  },
  
  /** Return list of audiences current user is not delegated to
  * @param audienceIds 
  * @return array of audiences not part of current users delegation
  */
  getRestrictedAudiencesFromList: function(audienceIds) {
  	var notAllowedAudiences = [], audienceDisplayValue = [];
  	for(var i=0; i<audienceIds.length; i++) {
  		if(!this._isMyDelegatedRecord(audienceIds[i], 'sn_cd_audience'))
  			notAllowedAudiences.push(audienceIds[i]);
  	}
  	
  	var gr = new GlideRecord('sn_cd_audience');
  	gr.addQuery('sys_id', 'IN', notAllowedAudiences);
  	gr.query(); 
  	while (gr.next())
  		audienceDisplayValue.push(gr.getDisplayValue());
  	return audienceDisplayValue;
  },
  
  aclCheck: function(contentId, tableName, operation) {
  	if (gs.getUser().hasRole('sn_cd.content_admin'))
  		return true;
  	var isCDPropertyOn = gs.getProperty('sn_cd.activate_content_authoring_controls') == 'true';
  	if (isCDPropertyOn && gs.getUser().hasRole('sn_cd.content_manager'))
  		return this.isMyContentDelegation(contentId, tableName);
  	return operation === "write" ? gs.getUser().hasRole('sn_cd.content_manager') : gs.getUser().hasRole('sn_cd.content_approver') || gs.getUser().hasRole('sn_cd.content_manager');
  },
  
  /** Return list of content current user is delegated to
  * @param audienceIds 
  * @return true if content is part of current users delegation
  */
  isMyContentDelegation: function(sysId, tableName) {
  	return this._isMyDelegatedRecord(sysId, tableName);
  },
  
  _isMyDelegatedRecord: function(sysId, tableName) {
  	var object = this._getDelegatedTablesAndField(tableName);
  	if (!object)
  		return true;
  	
  	var fieldName = object.fieldName;
  	var delegatedUserTable = object.delegatedUserTable;
  	var delegatedGroupTable = object.delegatedGroupTable;
  	
  	var gr = new GlideRecord(delegatedUserTable);
  	gr.addQuery('user', gs.getUserID());
  	gr.addQuery(fieldName, sysId);
  	gr.addNotNullQuery(fieldName);
  	gr.setLimit(1);
  	gr.query();
  	if (gr.hasNext()) 
  		return true;
  	
  	var myGroups = gs.getUser().getMyGroups();
  	if (myGroups.length > 0) {
  		gr = new GlideRecord(delegatedGroupTable);
  		gr.addQuery('group', 'IN', myGroups);
  		gr.addQuery(fieldName, sysId);
  		gr.addNotNullQuery(fieldName);
  		gr.setLimit(1);
  		gr.query();
  		if(gr.hasNext()) 
  			return true;
  	}
  	
  	var hasNoDelegations = true;
  	gr = new GlideRecord(delegatedUserTable);
  	gr.addQuery(fieldName, sysId);
  	gr.addNotNullQuery(fieldName);
  	gr.setLimit(1);
  	gr.query();
  	if (gr.hasNext())
  		hasNoDelegations = false;
  	
  	gr = new GlideRecord(delegatedGroupTable);
  	gr.addQuery(fieldName, sysId);
  	gr.addNotNullQuery(fieldName);
  	gr.setLimit(1);
  	gr.query();
  	if (gr.hasNext())
  		hasNoDelegations = false;
  	return hasNoDelegations;
  },
  
  /** Return ref qual with groups containing content publishing roles
  * @return groups with content manager/admin roles
  */
  getGroupsWithContentPublishingRoles: function() {
  	var gr = new GlideRecord('sys_group_has_role');
  	var roles = ['d4c0514cb3730300f5302ddc16a8dce1','0880114cb3730300f5302ddc16a8dcf4']; // sn_cd.content manager, sn_cd.content_admin 
  	if (new GlidePluginManager().isActive('com.sn_content_automation'))
  		roles.push('052f31a8b3001300f5302ddc16a8dceb'); // sn_ca.campaign_manager
  	gr.addQuery('role','IN', roles);
  	gr.addNotNullQuery('roles');
  	gr.query();
  	var allowedGroups = [];
  	while(gr.next()) 
  		allowedGroups.push(gr.getValue('group'));
  	return 'sys_idIN' + allowedGroups;
  },
  
  _getDelegatedTablesAndField: function(tableName) {
  	var fieldName ='', delegatedUserTable = '', delegatedGroupTable = '';
  	if (tableName == 'sn_cd_audience') {
  		fieldName = 'audience';
  		delegatedUserTable = 'sn_cd_audience_delegated_user';
  		delegatedGroupTable = 'sn_cd_audience_delegated_group';
  	} else {
  		delegatedUserTable = 'sn_cd_content_authoring_user';
  		delegatedGroupTable = 'sn_cd_content_authoring_group';
  		if (tableName == 'sn_cd_content_base') 
  			fieldName = 'content';
  		else if (tableName == 'sn_cd_url_asset') 
  			fieldName = 'link_content';
  		else if (tableName == 'sn_cd_block') 
  			fieldName = 'block_content';
  		else if (tableName == 'topic')
  			fieldName = 'topic';
  		else if (tableName == 'sp_page')
  			fieldName = 'page';
  		else
  			return '';
  	}
  	return {fieldName: fieldName, delegatedUserTable: delegatedUserTable, delegatedGroupTable: delegatedGroupTable};
  },
  type: 'cd_ContentDelegationUtils'
};

Sys ID

fd2e8d06c31310102920b8889d40ddc2

Offical Documentation

Official Docs: