Name
sn_smd.SMSecurityManager
Description
No description available
Script
var SMSecurityManager = Class.create();
SMSecurityManager.CREATE = 'create';
SMSecurityManager.READ = 'read';
SMSecurityManager.WRITE = 'write';
SMSecurityManager.DELETE = 'delete';
SMSecurityManager.EXECUTE = 'execute';
SMSecurityManager.ADMINISTER_SECURITY = 'administer_security';
SMSecurityManager.PROFILE_MANAGER = 'profile';
SMSecurityManager.MEMBERSHIP_MANAGER = 'manage_membership';
SMSecurityManager.PERMISSION_CHECKER = 'check_permission';
SMSecurityManager.OWNER = 'Owner';
SMSecurityManager.ADMIN = 'Security Administrator';
SMSecurityManager.EDITOR = 'Editor';
SMSecurityManager.VIEWER = 'Viewer';
SMSecurityManager.USER = 'USER';
SMSecurityManager.GROUP = 'GROUP';
SMSecurityManager.SERVICE_MODEL_CTX = 'service_model';
SMSecurityManager.SERVICE_LAYER_CTX = 'service_layer';
SMSecurityManager.SERVICE_ENVIRONMENT_CTX = 'service_environment';
SMSecurityManager.ENVIRONMENT_TEMPLATE_CTX = 'environment_template';
SMSecurityManager.ENVIRONMENT_CTX = 'environment';
SMSecurityManager.DEPLOYMENT_CTX = 'deployment';
SMSecurityManager.PACKAGE_TEMPLATE_CTX = 'package_template';
SMSecurityManager.PACKAGE_CTX = 'package';
SMSecurityManager.allOperations = [SMSecurityManager.CREATE,
SMSecurityManager.READ,
SMSecurityManager.WRITE,
SMSecurityManager.DELETE,
SMSecurityManager.EXECUTE,
SMSecurityManager.ADMINISTER_SECURITY
];
SMSecurityManager.isValidOperation = function(operation) {
return SMSecurityManager.allOperations.indexOf(operation) > -1;
};
SMSecurityManager.prototype = {
securityContext: null, //object from service model api
contextDefinition: null, //object from service model api
context: null,
defaultUser: null,
initialize: function(context, objectId) {
this.defaultUser = gs.getUserName();
if(this.defaultUser == 'system') {
this.defaultUser = 'admin';
}
if(gs.nil(objectId)) {
//most of the operations require explicit setSecurityContextForOperation call
return;
}
this.setSecurityContextForOperation(context, objectId);
},
getSecurityContextForOperation: function(context, objectId) {
if(gs.nil(this.securityContext)) {
this.setSecurityContextForOperation(context, objectId);
}
return this.securityContext;
},
setSecurityContextForOperation: function(context, objectId) {
this.context = context;
this.contextDefinition = this.getContextDefinition();
if(context === SMSecurityManager.SERVICE_MODEL_CTX) {
/* eslint-disable no-undef */
this.securityContext = sn_svcmod.ServiceContainerFactory.load(objectId);
/* eslint-enable no-undef */
} else if(this._isLayerContext(context)){
this.securityContext = SMUtils.loadLayer(objectId);
} else if(context === SMSecurityManaget.SERVICE_ENVIRONMENT_CTX) {
/* eslint-disable no-undef */
this.securityContext = sn_svcmod.ServiceContainerFactory.loadEnvironment(objectId);
/* eslint-enable no-undef */
} else {
throw 'Undefined security context defintion '+ context;
}
},
_isLayerContext: function(context) {
return (context === SMSecurityManager.ENVIRONMENT_TEMPLATE_CTX
|| context === SMSecurityManager.ENVIRONMENT_CTX
|| context === SMSecurityManager.DEPLOYMENT_CTX
|| context === SMSecurityManager.PACKAGE_TEMPLATE_CTX
|| context === SMSecurityManager.PACKAGE_CTX
|| context === SMSecurityManager.SERVICE_LAYER_CTX);
},
getLayerContextId: function(layer) {
switch(layer.getKind()) {
case SMConstants.SVC_LAYER_KIND_SERVICE_DEF:
if(layer.getKindIdentifier() == SMConstants.SVC_KIND_IDENTIFIER_ENV_TMPL)
return SMSecurityManager.ENVIRONMENT_TEMPLATE_CTX;
else if(layer.getKindIdentifier() == SMConstants.SVC_KIND_IDENTIFIER_ENV_INST)
return SMSecurityManager.ENVIRONMENT_CTX;
else
return SMSecurityManager.SERVICE_LAYER_CTX;
case SMConstants.SVC_LAYER_KIND_SERVICE_STATE:
return SMSecurityManager.DEPLOYMENT_CTX;
case SMConstants.SVC_LAYER_KIND_PACKAGE_DEF:
return SMSecurityManager.PACKAGE_TEMPLATE_CTX;
case SMConstants.SVC_LAYER_KIND_PACKAGE_STATE:
return SMSecurityManager.PACKAGE_CTX;
}
},
/**
* returns an object with all the permissions on object for a user specified by a userName;
* if userName is null, the current user will be used to check the permissions.
*/
getAllPermissions: function(context, objectId, userName) {
var allowedOperations = {};
if (gs.nil(context) || gs.nil(objectId)) {
gs.info('Security Permission check error : invalid parameters');
return allowedOperations;
}
this.setSecurityContextForOperation(context, objectId);
try {
var ops = SMSecurityManager.allOperations;
for(var i = 0; i <ops.length; i++) {
//params.user is optional
if(this.checkPermission(context, objectId, ops[i], userName)) {
allowedOperations[ops[i]] = true;
}
}
} catch(error) {
return {};
}
return allowedOperations;
},
hasAnyPermission: function(context, objectId, userName) {
for(var i = 0; i < SMSecurityManager.allOperations.length; i++) {
if(this.checkPermission(context, objectId, SMSecurityManager.allOperations[i], userName)) {
return true;
}
}
return false;
},
hasCreatePermission: function(context, objectId, userName) {
return this.checkPermission(context, objectId, "create", userName);
},
hasReadPermission: function(context, objectId, userName) {
return this.checkPermission(context, objectId, "read", userName);
},
hasWritePermission: function(context, objectId, userName) {
return this.checkPermission(context, objectId, "write", userName);
},
hasDeletePermission: function(context, objectId, userName) {
return this.checkPermission(context, objectId, "delete", userName);
},
hasAdministerSecurityPermission: function(context, objectId, userName) {
return this.checkPermission(context, objectId, "administer_security", userName);
},
checkPermission: function(context, objectId, operation, userName) {
if(gs.nil(context) || gs.nil(objectId) || gs.nil(operation)) {
throw 'Context, object id, and operation is required for operation _checkPermission';
}
if(!SMSecurityManager.isValidOperation(operation)) {
throw 'Unsupported operation '+operation;
}
this.setSecurityContextForOperation(context, objectId);
var permission = this.securityContext.checkPermission(this.contextDefinition, operation, userName || '');
return this._booleanizePermission(permission);
},
_booleanizePermission: function(permission) {
if(permission == 'GRANT' || permission == 'INHERIT_GRANT') {
return true;
}
return false;
},
/**
* @Deprecated - use addProfileMembership method instead
* This method is intended to associate an user with a profile.
*/
setProfileMembership: function(ctxObject, profileName, userName, type) {
var user = userName || this.defaultUser;
var memberType = this._getMemberType(type);
if(memberType == SMSecurityManager.USER && gs.nil(this._getUser('sys_id', user)) && gs.nil(this._getUser('user_name', user))) {
if(gs.hasRole("maint")) {
return;
}
throw 'Invalid user to set profile membership for';
}
var profile = ctxObject.getPersona(profileName);
var membership = ctxObject.getMembership(profile);
var memberAction = membership.getAction(memberType, user);
if(gs.nil(memberAction)) {
membership.createAction(memberType, user);
} else {
memberAction.changeAction('GRANT');
}
var sraUserRole = '7d6071c0cb312200ee62d796634c9ca3';
new global.ServiceModelRoleAdder().addOrRemoveRole(user, memberType, sraUserRole, 'add');
},
denyProfileMembership: function(ctxObject, profileName, userName, type) {
var profile = ctxObject.getPersona(profileName);
var membership = ctxObject.getMembership(profile);
var memberAction = membership.getAction(this._getMemberType(type), userName);
memberAction.changeAction('DENY');
},
_getMemberType: function(type) {
var memberType = SMSecurityManager.USER;
if(!gs.nil(type)) {
memberType = type.toUpperCase();
}
return memberType;
},
allProfiles: function() {
this._checkContext();
var availableProfiles = [];
var profiles = this.securityContext.availablePersonas();
for(var i = 0; i < profiles.length; i++) {
var profile = profiles[i];
var profileToOpsRoot = profile.getRootMapping();
var parentCtxs = this._findParentContextDefinitionChain(this.context);
var profileToOps = profileToOpsRoot;
for(var j = 0; j < parentCtxs.length; j++) {
profileToOps = profileToOps.getChild(parentCtxs[j]);
}
profileToOps = profileToOps.getChild(this.context);
var obj = {};
obj.profile = profile;
obj.operations = {};
//you cannot create object of current context as you are already inside it so passing false
this._getOperationsForProfileAndItsChildren(profileToOps, obj.operations, false);
if (obj.operations[this.context] && obj.operations[this.context].length > 0)
availableProfiles.push(obj);
}
return this._profileDTOs(availableProfiles);
},
_getOperationsForProfileAndItsChildren: function(profileToOps, operations, hasParentCreateOp) {
if(gs.nil(profileToOps))
return;
var context = profileToOps.getContextDefinition().getObjectTypeId();
operations[context] = profileToOps.operations();
if(hasParentCreateOp) {
operations[context].push('create_exist_on_parent');
}
var children = profileToOps.children();
if (!children || children.length <=0)
return;
for(var i = 0; i < children.length; i++) {
var ops = profileToOps.operations();
hasParentCreateOp = ops.length > 0 && ops.indexOf(SMSecurityManager.CREATE) >= 0;
this._getOperationsForProfileAndItsChildren(children[i], operations, hasParentCreateOp);
}
},
//TODO: need to ask SecurityAPI writer for this method
_findParentContextDefinitionChain: function(context) {
var parents = [];
var gr = new GlideRecord("svc_security_object_def");
gr.addQuery('object_id', context);
gr.query();
if(gr.next()) {
var parent = gr.parent;
while(!gs.nil(parent) && parent.object_id != '<root>') {
parents.unshift(parent.object_id);
parent = parent.parent;
}
return parents;
}
throw 'Context definition '+context+' not found';
},
activeProfiles: function() {
this._checkContext();
return this._profileDTOs(this.securityContext.activePersonas());
},
profileMemberships: function() {
this._checkContext();
return this._profileMembershipDTOs(this.securityContext.memberships());
},
addProfileMembership: function(profileName, memberName, type) {
this._checkContext();
this.setProfileMembership(this.securityContext, profileName, memberName, type);
},
removeProfileMembership: function(profileName, memberName, type) {
this._checkContext();
this.denyProfileMembership(this.securityContext, profileName, memberName, type);
},
_profileDTOs : function(profiles) {
var dtos = [];
for(var i = 0; i < profiles.length; i++) {
var dto = {};
dto.id = profiles[i].profile ? profiles[i].profile.getSysId() : profiles[i].getSysId();
dto.name = profiles[i].profile ? profiles[i].profile.getName() : profiles[i].getName();
dto.operations = profiles[i].operations ? profiles[i].operations : [];
dtos.push(dto);
}
dtos.sort(function(a,b) {return a.name.toLowerCase() > b.name.toLowerCase();});
return dtos;
},
_profileMembershipDTOs: function(memberships) {
var dtos = {};
for(var i = 0; i < memberships.length; i++) {
var membership = memberships[i];
var profile = membership.getTargetPersona();
var forProfileDto = dtos[profile.getSysId()] || [];
this._getMembershipDTO(membership, SMSecurityManager.USER, forProfileDto);
this._getMembershipDTO(membership, SMSecurityManager.GROUP, forProfileDto);
forProfileDto.sort(function(a,b) {return a.member.name.toLowerCase() > b.member.name.toLowerCase();});
dtos[profile.getSysId()] = forProfileDto;
}
for(var profileId in dtos) {
if(dtos[profileId].length < 1) {
delete dtos[profileId];
}
}
return dtos;
},
_getMembershipDTO: function(membership, type, forProfileDto) {
//we only list the users that are granted permissions defined by the profile
var members = membership.getGranted(type);
for(var j = 0; j < members.length; j++) {
var dto = {};
switch(type) {
case SMSecurityManager.USER:
dto.member = this._getUser('user_name', members[j]);
dto.addedTo = this._getContext(membership, type, dto.member.sysId);
dto.type = 'User';
break;
case SMSecurityManager.GROUP:
dto.member = this._getGroup('name', members[j]);
dto.addedTo = this._getContext(membership, type, dto.member.sysId);
dto.type = 'Group';
break;
default:
}
forProfileDto.push(dto);
}
},
//We only handle grant case for now -- GRANT | INHERIT_GRANT
_getContext: function(membership, type, sysId) {
var membershipAction = membership.getAction(type, sysId);
var action = membershipAction.getAction();
if(action == 'GRANT') {
var addedToCtx = membership.getContext();
var addedTo = addedToCtx ? addedToCtx.getName() : '';
return addedTo;
}
return this._getContext(membershipAction.getContext(), type, sysId);
},
_getUser: function(field, value) {
var gr = new GlideRecord("sys_user");
gr.addQuery(field, value);
gr.query();
if(gr.next()) {
return {
sysId : gr.getValue('sys_id'),
id : gr.user_name+'',
name: gr.getDisplayValue()
};
}
return null;
},
_getGroup: function(field, value) {
var gr = new GlideRecord("sys_user_group");
gr.addQuery(field, value);
gr.query();
if(gr.next()) {
return {
sysId : gr.getValue('sys_id'),
id : gr.name+'',
name: gr.getDisplayValue()
};
}
return null;
},
_checkContext: function() {
if(gs.nil(this.securityContext))
throw 'No security context is defined for security manager';
},
getContextDefinition: function() {
/* eslint-disable no-undef */
var ctxDefinition = sn_svcmod.ServiceSecurityFactory.loadObjectTypeDefinitions();
/* eslint-enable no-undef */
var parentCtxs = this._findParentContextDefinitionChain(this.context);
for(var i = 0; i < parentCtxs.length; i++) {
ctxDefinition = ctxDefinition.getChild(parentCtxs[i]);
}
return ctxDefinition.getChild(this.context);
},
type: 'SMSecurityManager'
};
Sys ID
415735c9c3f12200e2ddb59af3d3ae92