API Docs for: 1.0.0
Show:

File: scotts\classes\CWTPortalUtil.js

var CWTPortalUtil = Class.create();
/**
 * Class to assist with portal management
 * 
 * @class CWTPortalUtil
 * @constructor
 * @module ScriptIncludes
 * @author Alexander Anderson (cwt_alexander)
 * @see https://scottsdev.service-now.com/sys_script_include.do?sys_id=7b81ed3ddb1af7405cacd7795e96197f
 * @param {GlideRecord | String} sp_portal Reference to the Service Portal or
 * 		the SysID of the portal to use.
 */
(function() {

	/**
	 * Determine if a value should be considered true.
	 * 
	 * Due to a variety of ways of true/false values being returned by service now, this
	 * method exists to level set to a JavaScript boolean value for use.
	 * @method isFalse
	 * @private
	 * @static
	 * @param {Object | String | Boolean | Number} value
	 * @return {Boolean} True if the value is considered as trying to be "true", false otherwise.
	 */
	var isTrue = function(value) {
		return value == "1" || value == "true" || value === "t" || value === true;
	};
	
	/**
	 * Determine if a value should be considered false.
	 * 
	 * Due to a variety of ways of true/false values being returned by service now, this
	 * method exists to level set to a JavaScript boolean value for use.
	 * @method isFalse
	 * @private
	 * @static
	 * @param {Object | String | Boolean | Number} value
	 * @return {Boolean} True if the value is considered as trying to be "false", false otherwise.
	 */
	var isFalse = function(value) {
		return value == "0" || value == "false" || value === "f" || value === false;
	};
	
	
	
	CWTPortalUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	    "type": "CWTPortalUtil",
		"initialize": function(sp_portal) {
			this.sp = new GlideRecord("sp_portal");
			this.sp.get(sp_portal);
		},
		
		/**
		 * 
		 * @method hasAccess
		 * @param {String} [sys_id] Optional SysID of the user to check for access to
		 * 		the current portal. Defaults to the current user. 
		 * @return {Boolean} True if the user is directly listed as a content creator, false otherwise.
		 */
		"hasAccess": function(sys_id) {
			var user = new GlideRecord("sys_user"),
				managers,
				lookup;
			
			sys_id = sys_id || gs.getUserID();
			user.get(sys_id);
			
			if(isTrue(user.getValue("active"))) {
				managers = this.sp.getValue("u_content_creators");
				if(managers && managers.indexOf && managers.indexOf(sys_id) !== -1) {
					return true;
				} else {
					lookup = new GlideRecord("sys_user_has_role");
					lookup.addQuery("user", sys_id);
					lookup.addQuery("role.name", "admin");
					lookup.query();
					return lookup.next();
				}
			}
			
			return false;
		}
	});
	
	/**
	 * 
	 * @method hasAccessTo
	 * @param {GlideRecord | String} portal_id Indicates the Portal to be considered for access.
	 * @param {Array} [admin_roles] Optional array of Role SysIDs that should be considered for administrative override.
	 * @param {GlideRecord | String} [user_id] Optional indicator for the User to be considered for access. Defaults
	 * 		to the sessions current User.
	 * @return {Boolean} True if the user has access, false otherwise.
	 */
	CWTPortalUtil.hasAccessTo = function(portal_id, admin_roles, user_id) {
		var portal = new GlideRecord("sp_portal"),
			user = new GlideRecord("sys_user"),
			managers,
			lookup;
		
		user_id = user_id || gs.getUserID();
		user.get(user_id);
		
		if(portal_id instanceof GlideRecord) {
			portal = portal_id;
		} else {
			portal.get(portal_id);
		}
		
		
		if(isTrue(user.getValue("active"))) {
			managers = portal.getValue("u_content_creators");
			if(managers && managers.indexOf && managers.indexOf(user_id) !== -1) {
				return true;
			} else {
				lookup = new GlideRecord("sys_user_has_role");
				lookup.addQuery("user", user_id);
				lookup.addQuery("role.name", "admin");
				lookup.query();
				if(lookup.next()) {
					return true;
				} else if(admin_roles) {
					lookup = new GlideRecord("sys_user_has_role");
					lookup.addQuery("user", user_id);
					lookup.query();
					while(lookup.next()) {
						if(admin_roles.indexOf(lookup.getValue("role") !== -1)) {
							return true;
						}
					}
				}
			}
		}
		
		return false;
	};

	/**
	 * Checks access to a portal against the portal's Content Creator's list.
	 * 
	 * This method handles checking the parental relationship of the passed object and will navigate any needed
	 * relationship lookups to find the related portal.
	 * @method hasPortalAccess
	 * @param {GlideRecord} record
	 * @param {Array} [admin_roles] Optional array of Role SysIDs that should be considered for administrative override.
	 * @param {GlideRecord | String} [user_id] Optional indicator for the User to be considered for access. Defaults
	 * 		to the sessions current User.
	 * @return {Boolean} True if the user has access, false otherwise.
	 */
	CWTPortalUtil.hasPortalAccess = function(record, admin_roles, user_id) {
		var kb = record.getValue("kb_knowledge_base") || record.getValue("u_kb_knowledge_base"),
			portal = record.getValue("sp_portal") || record.getValue("u_sp_portal"),
			calendar = record.getValue("calendar") || record.getValue("u_calendar"),
			sc = record.getValue("sc_catalog") || record.getValue("sc_catalog"),
			table = record.getTableName();
		
		//gs.log("Check Access[" + table + "]: " + kb + ", " + portal + ", " + calendar + ", " + sc);
		if(table === "u_portal_calendar_event") {
			calendar = record.getValue("u_calendar");
		} else if(table === "u_portal_calendar") {
			calendar = record.getValue("sys_id");
		} else if(table === "kb_knowledge_base") {
			kb = record.getValue("sys_id");
		} else if(table === "sc_catalog") {
			sc = record.getValue("sys_id");
		}
		
		if(portal) {
			return CWTPortalUtil.hasAccessTo(portal, admin_roles, user_id);
		} else if(calendar) {
			record = new GlideRecord("u_portal_calendar");
			record.get(calendar);
			return CWTPortalUtil.hasPortalAccess(record, admin_roles, user_id);
		} else if(kb) {
			record = new GlideRecord("sp_portal");
			record.addQuery("kb_knowledge_base", kb);
			record.query();
			if(record.next()) {
				return CWTPortalUtil.hasAccessTo(record, admin_roles, user_id);
			}
		} else if(sc) {
			record = new GlideRecord("sp_portal");
			record.addQuery("sc_catalog", sc);
			record.query();
			if(record.next()) {
				return CWTPortalUtil.hasAccessTo(record, admin_roles, user_id);
			}
		}
	};
	
	/**
	 * Creates a "surface" level copy of the passed object.
	 * 
	 * Any child relationships from the source record are not copied, their references
	 * are merely repeated in the created copy.
	 * 
	 * @method copyRecord
	 * @param {GlideRecord} source
	 * @param {Array} [keysAppend] Optional array of property names to which " - Copy" should
	 * 		be added. The keys "Title" (records), "Name" (records), and "ID" (widgets) are always considered append keys. This applies
	 * 		to "u_title", "u_name", and "u_id" as well.
	 * @param {Array} [keysIgnore] Optional array of property names to ignore when copying.
	 * 		sys_id is always automatically ignored for this process.
	 * @return {GlideRecord} New GlideRecord pointing to the newly created copy.
	 */
	CWTPortalUtil.copyRecord = function(source, keysAppend, keysIgnore) {
		var copy = new GlideRecord(source.getTableName()),
			properties = Object.keys(source),
			x;
		
		for(x=0; x<properties.length; x++) {
			if(properties[x] === "title" || properties[x] === "u_title" || properties[x] === "name" || properties[x] === "u_name" || properties[x] === "id" || properties[x] === "u_id" || (keysAppend && keysAppend.indexOf(properties[x]) !== -1)) {
				copy.setValue(properties[x], source.getValue(properties[x]) + " - Copy");
			} else if(properties[x] !== "sys_id" && (!keysIgnore || keysIgnore.indexOf(properties[x]) !== -1)) {
				copy.setValue(properties[x], source.getValue(properties[x]));
			}
		}
		
		copy.insert();
		return copy;
	};
	
	/**
	 * Copy a portal.
	 * 
	 * Additionally copies the Theme and Homepage as they tend to need to be unique for
	 * the new Portal.
	 * @method copy
	 * @param {GlideRecord} source
	 * @param {Object} [values] Optional object mapping properties to new values to use
	 * 		on the copy.
	 * @return {GlideRecord} New GlideRecord pointing to the newly created copy.
	 */
	CWTPortalUtil.copy = function(source, values) {
		var styleSheets = new GlideRecord("m2m_sp_theme_css_include"),
			styleSheet,
			newSheet,
			sheet,
			
			portalScripts = new GlideRecord("m2m_sp_theme_js_include"),
			portalScript,
			newScript,
			script,
			
			homepage = new GlideRecord("sp_page"),
			theme = new GlideRecord("sp_theme"),
			properties,
			copy,
			x;
		
		// Create base copy
		copy = CWTPortalUtil.copyRecord(current, "url_suffix");
		
		// Write Targeted Adjustments Changes
		if(values) {
			properties = Object.keys(values);
			for(x=0; x<properties.length; x++) {
				// Ensure Field is Valid
				if(copy.isValidField(properties[x])) {
					copy.setValue(properties[x], values[properties[x]]);
				}
			}
		}

		// Copy Theme and set on copy _IF_ Theme Exists
		if(theme.get(source.theme)) {
			theme = CWTPortalUtil.copyRecord(theme);
			copy.setValue("theme", theme.sys_id);
			copy.update();
			
			// Copy the Theme's StyleSheets
			styleSheets.addQuery("sp_theme", source.getValue("theme"));
			styleSheets.query();
			while(styleSheets.next()) {
				styleSheet = new GlideRecord("sp_css_include");
				sheet = new GlideRecord("sp_css");
				// Copy StyleSheet Include
				if(styleSheet.get(styleSheets.sp_css_include)) {
					if(styleSheet.getValue("source") == "local" && sheet.get(styleSheet.sp_css)) {
						// If there is a child StyleSheet that is locally hosted (Instead of URL), Copy that
						styleSheet = CWTPortalUtil.copyRecord(styleSheet);
						sheet = CWTPortalUtil.copyRecord(sheet);
						styleSheet.setValue("sp_css", sheet.sys_id);
						styleSheet.update();
					} else {
						// URL Source, no CSS Sheet needs copying
						styleSheet = CWTPortalUtil.copyRecord(styleSheet);
					}
					
					// Create the new relationship
					newSheet = new GlideRecord("m2m_sp_theme_css_include");
					newSheet.setValue("sp_css_include", styleSheet.sys_id);
					newSheet.setValue("sp_theme", theme.sys_id);
					newSheet.insert();
				}
			}
			
			// Copy the Theme's Script Includes
			portalScripts.addQuery("sp_theme", source.getValue("theme"));
			portalScripts.query();
			while(portalScripts.next()) {
				portalScript = new GlideRecord("sp_js_include");
				script = new GlideRecord("sys_ui_script");
				// Copy Script Include
				if(portalScript.get(portalScripts.sp_js_include)) {
					if(portalScript.getValue("source") == "local" && script.get(portalScript.sys_ui_script)) {
						// If there is a child Script that is locally hosted (Instead of URL), Copy that
						portalScript = CWTPortalUtil.copyRecord(portalScript);
						script = CWTPortalUtil.copyRecord(script);
						portalScript.setValue("sys_ui_script", script.sys_id);
						portalScript.update();
					} else {
						// URL Source, no Script needs copying
						portalScript = CWTPortalUtil.copyRecord(portalScript);
					}
					
					// Create the new relationship
					newScript = new GlideRecord("m2m_sp_theme_js_include");
					newScript.setValue("sp_js_include", portalScript.sys_id);
					newScript.setValue("sp_theme", theme.sys_id);
					newScript.insert();
				}
			}
		}

		// Copy Homepage and set on copy _IF_ Page Exists
		if(homepage.get(source.homepage)) {
			homepage = new SPClonePage().run(homepage);
			// SPClonePage fails by returning null
			if(homepage != null) {
				copy.setValue("homepage", homepage.sys_id);
				copy.update();
			} else {
				gs.addErrorMessage("Failed to copy homepage for " + source.title);
			}
		}
		
		// Copy Complete
		// No new changes to the copy to save
		return copy;
	};
})();