Name
sn_grc.ImportProfilesBase
Description
Library to import profiles into GRC
Script
var ImportProfilesBase = Class.create();
ImportProfilesBase.prototype = {
initialize: function() {},
getHierarchy: function(currentId, direction, tableName, category) {
return this._getHierarchy(null, currentId, direction, tableName, category);
},
hasParent: function(processId) {
return this._hasParent(processId);
},
hasUpstreamStagedProfiles: function(stagedProfileId) {
return this._hasUpstreamStagedProfiles(stagedProfileId);
},
createProfilesAndRelationships: function(rootId) {
return this._createProfilesAndRelationships(rootId);
},
clearStagedProfilesAndRelationships: function(rootId) {
return this._clearStagedProfilesAndRelationships(rootId);
},
getProfileClass: function(tableName, recordId) {
return this._getProfileClass(tableName, recordId);
},
isValidHierarchy: function(current) {
return this._isValidHierarchy(current);
},
isProfileRelationshipAvailable: function(profileId, profileRelationship) {
return this._isProfileRelationshipAvailable(profileId, profileRelationship);
},
getCategories: function(profile, direction) {
return this._getCategories(profile, direction);
},
getInvalidProfiles: function(profile, direction) {
return this._getInvalidProfiles(profile, direction);
},
generateProfiles: function() {
if (this._isEntityScopingEnabledForCMDBQuery()) {
gs.eventQueue('sn_grc.generate_profiles_from_job', null);
} else {
this._generateProfiles();
}
},
createProfile: function(params) {
return this._createProfile(params);
},
getProfileById: function(source) {
return this._getProfileById(source);
},
isEntityScopingEnabledForCMDBQuery: function() {
return this._isEntityScopingEnabledForCMDBQuery();
},
_isEntityScopingEnabledForCMDBQuery: function() {
var isPropertyEnabled = gs.getProperty('sn_grc.enable_entity_scoping_for_cmdb_query', '');
if (isPropertyEnabled == 'true') {
var sysId = 'b957ed9b0720301054685d3f0ad3006d';
var grScriptInclude = new GlideRecord('sys_script_include');
return grScriptInclude.get(sysId);
}
return false;
},
generateProfilesFromEvent: function() {
this._generateProfiles();
},
_generateProfiles: function() {
var deleteRecordsList = [];
var profileTypeSysIds = [];
var profileType = new GlideRecord('sn_grc_profile_type');
profileType.addActiveQuery();
profileType.addQuery("processing_profiles", false);
profileType.query();
while (profileType.next()) {
profileType.setValue("processing_profiles", true);
profileType.update();
var unwantedRecordsList = [];
var profileTypeId = profileType.getUniqueValue();
unwantedRecordsList = new GRCUtils().generateProfilesJob(profileType, false);
if (unwantedRecordsList.length != 0) {
profileTypeSysIds.push(profileTypeId);
deleteRecordsList = deleteRecordsList.concat(unwantedRecordsList);
}
}
if (deleteRecordsList.length > 0) {
//Remove unwanted m2m records
var util = new ItemGenerationV2Conditions();
var grUnwanted = new GlideRecord('sn_grc_m2m_profile_profile_type');
grUnwanted.addQuery("sys_id", "IN", deleteRecordsList);
grUnwanted.query();
while (grUnwanted.next()) {
var entityTypeId = grUnwanted.getValue('profile_type');
var entityId = grUnwanted.getValue('profile');
grUnwanted.skipInsertActionToQueue = true;
grUnwanted.deleteRecord();
if (util.entityTypeHasActiveContentAssociation(entityTypeId) || util.entityTypeHasItemAssociation(entityTypeId, false) ) {
var actionParms = {
action: 'remove_entity_from_entity_type',
entity_type_id: entityTypeId,
entity_id: entityId,
};
new sn_grc.IGEntityToEntityTypeActionHandler(actionParms).execute();
}
}
}
//sets processing_profiles to false for profile types
var profileTypes = new GlideRecord("sn_grc_profile_type");
profileTypes.addQuery("sys_id", "IN", profileTypeSysIds);
profileTypes.setValue("processing_profiles", false);
profileTypes.updateMultiple();
var psToRs = new GlideRecord("sn_risk_m2m_risk_definition_policy_statement");
if (psToRs.isValid()) {
psToRs.addQuery("last_associated_timestamp", "!=", "");
psToRs.query();
while (psToRs.next()) {
var psToRsActionParms = {
action: 'add_content_to_content',
table: 'sn_risk_m2m_risk_definition_policy_statement',
source: psToRs.getUniqueValue(),
content_id: psToRs.getValue('sn_risk_definition')
};
var strategy = new ItemGenerationV2Utils().getStrategy('sn_risk');
new IGContentActionHandler(psToRsActionParms, strategy).execute();
}
}
},
_getInvalidProfiles: function(profile, direction) {
// This function is looking for the profile already associated in the opposite direction
// and which are also presents in the direction we are looking for in order to avoid loops
var invalidProfileIds = [];
invalidProfileIds.push(profile.sys_id + '');
var oppositeDirection = direction == 'upstream' ? 'downstream' : 'upstream';
var associatedProfileIds = this._getAssociatedProfiles(profile.sys_id + '', oppositeDirection);
var categoryIds = this._getCategories(profile, direction);
var possibleInvalidRelations = new GlideRecord('sn_grc_profile');
possibleInvalidRelations.addQuery("profile_class.category", "IN", categoryIds).addOrCondition("profile_class.category", "");
possibleInvalidRelations.addQuery('sys_id', 'IN', associatedProfileIds);
possibleInvalidRelations.query();
while (possibleInvalidRelations.next())
invalidProfileIds.push(possibleInvalidRelations.sys_id + '');
return invalidProfileIds;
},
_isProfileRelationshipAvailable: function(profileId, profileRelationship) {
var profile = new GlideRecord("sn_grc_profile");
if (profile.get(profileId)) {
var direction = "downstream";
if (profileRelationship.getEncodedQuery().indexOf("downstream_profile=" + profileId) != -1)
direction = "upstream";
var categoryIds = new sn_grc.ImportProfiles().getCategories(profile, direction);
var invalidIds = new sn_grc.ImportProfiles().getInvalidProfiles(profile, direction);
var eligibleProfiles = new GlideRecord("sn_grc_profile");
eligibleProfiles.addEncodedQuery("active=true^profile_class.categoryIN" + categoryIds + "^ORprofile_class.category=^sys_idNOT IN" + invalidIds);
eligibleProfiles.query();
var eligibleProfileList = [];
while (eligibleProfiles.next())
eligibleProfileList.push(eligibleProfiles.sys_id + '');
var oppositeDirection = (direction == "upstream") ? "downstream" : "upstream";
for (var i = 0; i < eligibleProfileList.length; i++) {
var m2m = new GlideRecord("sn_grc_m2m_profile_profile");
m2m.addQuery(oppositeDirection + "_profile", profileId + '');
m2m.addQuery(direction + "_profile", eligibleProfileList[i] + '');
m2m.setLimit(1);
m2m.query();
if (!m2m.hasNext())
return true;
}
}
return false;
},
_getCategories: function(profile, direction) {
var category = new GlideRecord("sn_grc_profile_tier");
var profileCategory = new GlideRecord("sn_grc_profile_tier");
if (profileCategory.get(profile.profile_class.category)) {
if (direction == "upstream") {
category.addQuery("tier_level", "<=", profileCategory.tier_level);
category.orderByDesc("tier_level");
} else if (direction == "downstream") {
category.addQuery("tier_level", ">=", profileCategory.tier_level);
category.orderBy("tier_level");
}
category.setLimit(2);
}
category.query();
var categoryIds = [];
while (category.next())
categoryIds.push(category.getUniqueValue() + '');
return categoryIds;
},
getAssociatedProfiles: function(profileId, direction) {
return this._getAssociatedProfiles(profileId, direction);
},
_getAssociatedProfiles: function(profileId, direction) {
var profileM2M = new GlideRecord("sn_grc_m2m_profile_profile");
if (direction == 'upstream')
profileM2M.addQuery('downstream_profile', profileId);
else if (direction == 'downstream')
profileM2M.addQuery('upstream_profile', profileId);
profileM2M.query();
var profileIds = [];
while (profileM2M.next())
profileIds.push(profileM2M[direction + '_profile'] + '');
return profileIds;
},
_isValidHierarchy: function(current) {
var profiles = new sn_grc.GRCUtils().getMessage("profiles");
var profile = new sn_grc.GRCUtils().getMessage("profile");
var map = this._getCategoryMap();
var isValidHierarchy = {
errorMessage: '',
value: true
};
if (current.upstream_profile + '' == current.downstream_profile + '') {
isValidHierarchy.errorMessage = gs.getMessage("Invalid Relationship: Upstream {0} cannot be same as downstream {0}", profile);
isValidHierarchy.value = false;
return isValidHierarchy;
}
var upstreamCategory = current.upstream_profile.profile_class.category + '';
var downstreamCategory = current.downstream_profile.profile_class.category + '';
if (upstreamCategory != '' && downstreamCategory != '' && map[upstreamCategory].value > map[downstreamCategory].value) {
isValidHierarchy.errorMessage = gs.getMessage('Invalid Relationship: {2} from {0} category cannot roll up to {1} category', [map[downstreamCategory].name, map[upstreamCategory].name, profiles]);
isValidHierarchy.value = false;
return isValidHierarchy;
}
var upstreamProfiles = new sn_grc.GRCProfileLists().getUpstreamProfiles(current.upstream_profile + '');
if (upstreamProfiles.indexOf(current.downstream_profile + '') != -1) {
isValidHierarchy.errorMessage = gs.getMessage("Invalid Relationship: {0} is already an upstream {2} to {1} and therefore cannot be selected as downstream {2}", [current.downstream_profile.name, current.upstream_profile.name, profile]);
isValidHierarchy.value = false;
}
return isValidHierarchy;
},
_getCategoryMap: function() {
var map = {};
var category = new GlideRecord("sn_grc_profile_tier");
category.query();
while (category.next())
map[category.getUniqueValue() + ''] = {
name: category.label + '',
value: parseInt(category.tier_level)
};
return map;
},
_hasParent: function(processId) {
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('child', processId);
rel.query();
if (rel.hasNext())
return true;
return false;
},
_hasUpstreamStagedProfiles: function(stagedProfileId) {
var m2m = new GlideRecord('sn_grc_m2m_profile_staging');
m2m.addQuery('downstream', stagedProfileId);
m2m.query();
if (m2m.hasNext())
return true;
return false;
},
_getHierarchy: function(parentId, currentId, direction, tableName, category) {
var visitedItems = {};
this.rootId = currentId;
this.rootTable = tableName;
if (category)
this._getTablesFromCategory(category);
this._getRelationship(visitedItems, parentId, currentId, direction, tableName);
},
_getTablesFromCategory: function(category) {
var categoryId = "";
var categoryRec = new GlideRecord("sn_grc_profile_tier");
categoryRec.get("name", category);
categoryId = categoryRec.getUniqueValue();
if (!categoryId)
return;
var rule = new GlideRecord('sn_grc_profile_class_rules');
rule.addQuery('profile_class.category', categoryId);
rule.query();
var tableNames = [];
while (rule.next())
tableNames.push(rule.table + '');
this.tableNames = tableNames;
},
_getRelationship: function(visitedItems, parentId, currentId, direction, tableName) {
if (!visitedItems[currentId])
this._createStagedProfile(currentId, tableName);
// create m2m staging
this._createM2mStagedProfile(parentId, currentId, direction);
if (visitedItems[currentId])
return;
// create staged profile
visitedItems[currentId] = true;
parentId = currentId;
var rel = new GlideRecord('cmdb_rel_ci');
if (direction == 'upstream')
rel.addQuery('child', currentId);
else
rel.addQuery('parent', currentId);
if (this.tableNames)
rel.addQuery('child.sys_class_name', 'IN', this.tableNames);
rel.query();
while (rel.next()) {
if (direction == 'upstream') {
currentId = rel.parent + '';
tableName = rel.parent.sys_class_name + '';
} else {
currentId = rel.child + '';
tableName = rel.child.sys_class_name + '';
}
this._getRelationship(visitedItems, parentId, currentId, direction, tableName);
}
},
_createStagedProfile: function(sourceId, tableName) {
var source = new GlideRecord(tableName);
if (!source.get(sourceId))
return;
// Check if the source already exists in the staging table
var target = new GlideRecord('sn_grc_profile_staging');
if (target.get('applies_to', sourceId))
return;
target.name = source.getDisplayValue();
target.owned_by = source.assigned_to;
target.table = tableName + '';
target.applies_to = sourceId;
target.root_id = this.rootId;
target.root_table = this.rootTable;
if (!target.insert())
return;
},
_getStagedProfileById: function(sourceId) {
if (sourceId == null)
return null;
var stagingProfile = new GlideRecord('sn_grc_profile_staging');
if (!stagingProfile.get('applies_to', sourceId))
return null;
return stagingProfile.sys_id + '';
},
_createM2mStagedProfile: function(targetId, nextTargetId, direction) {
var sourceStagingProfileId = this._getStagedProfileById(targetId);
var targetStagingProfileId = this._getStagedProfileById(nextTargetId);
if ((sourceStagingProfileId == null) || (targetStagingProfileId == null))
return;
var m2m = new GlideRecord('sn_grc_m2m_profile_staging');
if (direction == 'upstream') {
m2m.addQuery('upstream', targetStagingProfileId);
m2m.addQuery('downstream', sourceStagingProfileId);
} else {
m2m.addQuery('downstream', targetStagingProfileId);
m2m.addQuery('upstream', sourceStagingProfileId);
}
m2m.query();
if (!m2m.next()) {
m2m = new GlideRecord('sn_grc_m2m_profile_staging');
if (direction == 'upstream') {
m2m.upstream = targetStagingProfileId;
m2m.downstream = sourceStagingProfileId;
} else {
m2m.downstream = targetStagingProfileId;
m2m.upstream = sourceStagingProfileId;
}
m2m.insert();
}
},
_cleanupProfiles: function(rootId) {
var stagedProfile = new GlideRecord('sn_grc_profile_staging');
stagedProfile.addQuery('root_id', rootId);
stagedProfile.query();
while (stagedProfile.next()) {
var profile = new GlideRecord('sn_grc_profile');
if (profile.get('applies_to', stagedProfile.applies_to + ''))
profile.deleteRecord();
}
},
_cleanupProfileRelationships: function(rootId) {
var stagedM2m = new GlideRecord('sn_grc_m2m_profile_staging');
stagedM2m.addQuery('downstream.root_id', rootId);
stagedM2m.query();
while (stagedM2m.next()) {
var m2m = new GlideRecord('sn_grc_m2m_profile_profile');
m2m.addQuery('upstream_profile.applies_to', stagedM2m.upstream.applies_to + '');
m2m.addQuery('downstream_profile.applies_to', stagedM2m.downstream.applies_to + '');
m2m.query();
m2m.deleteMultiple();
}
},
_createProfilesAndRelationships: function(rootId) {
// Create profiles
var stagedProfile = new GlideRecord('sn_grc_profile_staging');
stagedProfile.addQuery('root_id', rootId);
stagedProfile.query();
while (stagedProfile.next()) {
if (!this._createProfile(stagedProfile)) {
// Clean up all the remaining profiles
this._cleanupProfiles(rootId);
gs.addErrorMessage(new sn_grc.GRCUtils().getMessage("profile_type_to_error_generation"));
return false;
}
}
// Create m2m relationship between profiles
var m2m = new GlideRecord('sn_grc_m2m_profile_staging');
m2m.addQuery('downstream.root_id', rootId);
m2m.query();
while (m2m.next()) {
if (!this._createProfileRelationship(m2m)) {
this._cleanupProfileRelationships(rootId);
this._cleanupProfiles(rootId);
gs.addErrorMessage(new sn_grc.GRCUtils().getMessage("profile_type_to_error_generation"));
return false;
}
}
gs.addInfoMessage(gs.getMessage('Import profile complete.'));
return true;
},
_clearStagedProfilesAndRelationships: function(rootId) {
var stagedProfile = new GlideRecord('sn_grc_profile_staging');
stagedProfile.addQuery('root_id', rootId);
stagedProfile.query();
stagedProfile.deleteMultiple();
var m2m = new GlideRecord('sn_grc_m2m_profile_staging');
m2m.addQuery('downstream.root_id', rootId);
m2m.query();
m2m.deleteMultiple();
},
_getProfileById: function(sourceId) {
if (sourceId == null)
return null;
var profile = new GlideRecord('sn_grc_profile');
if (!profile.get('applies_to', sourceId))
return null;
return profile.sys_id + '';
},
_createProfileRelationship: function(m2m) {
var upstream = this._getProfileById(m2m.upstream.applies_to + '');
var downstream = this._getProfileById(m2m.downstream.applies_to + '');
if (upstream == null || downstream == null)
return false;
var profileRel = new GlideRecord('sn_grc_m2m_profile_profile');
profileRel.addQuery('upstream_profile', upstream);
profileRel.addQuery('downstream_profile', downstream);
profileRel.query();
if (profileRel.next())
return true;
profileRel.initialize();
profileRel.upstream_profile = upstream;
profileRel.downstream_profile = downstream;
if (!profileRel.insert()) {
var pr = new sn_grc.GRCUtils().getMessage("profile_type_lower");
gs.info(gs.getMessage("The {2} relationship creation failed for {0} and {1}", [m2m.upstream.getDisplayValue(), m2m.downstream.getDisplayValue(), pr]));
return false;
}
return true;
},
_getProfileClass: function(tableName, recordId) {
var profileClass = '';
var rule = new GlideRecord('sn_grc_profile_class_rules');
rule.addQuery('table', tableName);
rule.setLimit(1);
rule.query();
if (rule.next()) {
profileClass = rule.getValue("profile_class");
var subClass = this.getSubClassUsingClassRuleFilters(rule.getUniqueValue(), recordId, tableName);
if(subClass != "") {
return subClass;
}
}
return profileClass;
},
getSubClassUsingClassRuleFilters: function(profileClassRuleId, recordId, tableName) {
var filter = new GlideRecord('sn_grc_profile_class_rule_filter');
filter.addQuery('profile_class_rules', profileClassRuleId);
filter.query();
var subClass = "";
var priorityNo;
while(filter.next()) {
var isValid = this.checkIfRecordPartOfCurrentFilter(filter, tableName, recordId);
if(!isValid) {
continue;
}
var tempClass = filter.getValue('sub_class');
var currentFilterPriority = parseInt(filter.getValue('filter_priority'));
if(subClass=="" || priorityNo>currentFilterPriority) {
subClass = tempClass;
priorityNo = currentFilterPriority;
}
}
return subClass;
},
checkIfRecordPartOfCurrentFilter: function(filter, tableName, recordId) {
var condition = filter.getValue('condition');
if (condition == undefined) {
return true;
}
var gr = this.getTableRecords(tableName, condition);
while(gr.next()) {
if(gr.getUniqueValue() == recordId) {
return true;
}
}
return false;
},
getTableRecords: function(table, condition) {
var gr = new GlideRecord(table);
gr.initialize();
if (!gs.nil(condition)) {
gr.addEncodedQuery(condition);
}
gr.query();
return gr;
},
_createProfile: function(source) {
// Check if the source already exists in the staging table
var target = new GlideRecord('sn_grc_profile');
if (target.get('applies_to', source.applies_to + ''))
return true;
target.name = source.name;
target.owned_by = source.owned_by;
target.table = source.table;
target.applies_to = source.applies_to;
// Get class by table
target.profile_class = this._getProfileClass(source.table + '', source.applies_to + '');
if (!target.insert()) {
var pr = new sn_grc.GRCUtils().getMessage("profile_type_lower");
gs.info(gs.getMessage("The {1} creation failed for {0}", [source.name, pr]));
return false;
}
return true;
},
type: 'ImportProfilesBase'
};
Sys ID
7d9f9769e7223200dd926217c2f6a9d3