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;
};
})();