Name
global.UserSubscriptionHelper
Description
Helper class to retrieve subscription members
Script
var UserSubscriptionHelper = Class.create();
UserSubscriptionHelper.prototype = {
initialize: function() {
this.LICENSE_STATUS_ASSIGNED = 'assigned';
this.LICENSE_STATUS_APPROVAL_REQUIRED = 'approval_required';
this.LICENSE_SOURCE_USERSET = 'userset';
// table names
this.LICENSE_EXCLUSION_TABLE = 'sys_user_license_exclude';
this.USER_HAS_LICENSE_TABLE = 'sys_user_has_license';
this.USER_PENDING_LICENSE_TABLE = 'sys_user_pending_license';
this.LICENSE_SOURCE_TABLE = 'sys_user_license_source';
this.auditHelper = new UserSubscriptionAuditHelper();
},
doesUserHaveLicense: function(userSysID, licenseSysID) {
// This function checks if the user has license (is user a licensed user)
var userLicenseGR = new GlideRecord(this.USER_HAS_LICENSE_TABLE);
userLicenseGR.addQuery('user', userSysID);
userLicenseGR.addQuery('license', licenseSysID);
userLicenseGR.query();
return userLicenseGR.hasNext();
},
isUserAddedToLicense: function(userSysID, licenseSysID) {
// This function only checks if the user, license pair exists in the
// sys_user_has_license table
var userLicenseGR = this._getUserAddedToLicense(userSysID, licenseSysID);
return userLicenseGR.hasNext();
},
_getUserAddedToLicense: function(userSysID, licenseSysID) {
var userLicenseGR = new GlideRecord(this.USER_HAS_LICENSE_TABLE);
userLicenseGR.addQuery('user', userSysID);
userLicenseGR.addQuery('license', licenseSysID);
userLicenseGR.query();
return userLicenseGR;
},
isUserAddedToPendingLicense: function(userSysID, licenseSysID) {
// This function only checks if the user, license pair exists in the
// sys_user_pending_license table
var userLicenseGR = new GlideRecord(this.USER_PENDING_LICENSE_TABLE);
userLicenseGR.addQuery('user', userSysID);
userLicenseGR.addQuery('license', licenseSysID);
userLicenseGR.query();
return userLicenseGR.hasNext();
},
addUserToLicense: function (userSysID, licenseSysID, userSetSysID) {
if (this.isUserAddedToLicense(userSysID, licenseSysID)) {
this.addToLicenseSource(userSysID, licenseSysID, userSetSysID, false);
return;
}
var userLicenseStatus = this.canUserBeAssignedToLicense(licenseSysID, userSysID);
if (userLicenseStatus.canBeAdded) {
this.addUserToLicenseWithStatus(userSysID, licenseSysID, userSetSysID, userLicenseStatus.assignStatus);
}
},
addUserToLicenseWithStatus: function(userSysID, licenseSysID, userSetSysID, status) {
var isUserSubscribed = false;
var isUserAdded = false;
if (this.isUserAddedToLicense(userSysID, licenseSysID)) {
this.addToLicenseSource(userSysID, licenseSysID, userSetSysID, false);
return isUserAdded;
}
if (this._isUserExcludedFromLicense(userSysID, licenseSysID))
return isUserAdded;
isUserSubscribed = this._allocateUserToLicense(userSysID, licenseSysID, userSetSysID);
isUserAdded = isUserSubscribed;
if (isUserAdded)
this.addToLicenseSource(userSysID, licenseSysID, userSetSysID, false);
if (isUserSubscribed)
this._logChange(userSysID, licenseSysID, isUserSubscribed, false, false);
return isUserAdded;
},
_allocateUserToLicense: function(userSysID, licenseSysID, userSetSysID) {
var userLicenseGR = new GlideRecord(this.USER_HAS_LICENSE_TABLE);
userLicenseGR.initialize();
userLicenseGR.setValue('user', userSysID);
userLicenseGR.setValue('license', licenseSysID);
if (JSUtil.notNil(userSetSysID))
userLicenseGR.setValue('source', this.LICENSE_SOURCE_USERSET);
return (JSUtil.notNil(userLicenseGR.insert()))? true : false;
},
canUserBeAssignedToLicense: function (licenseSysID, userSysID) {
var returnObj = {}; // will contain 2 keys canBeAdded and assignStatus
if (JSUtil.nil(licenseSysID)) {
returnObj.canBeAdded = false;
return returnObj;
}
var licenseGR = this._fetchLicenseBySysID(licenseSysID);
// If not a valid license or if the user is excluded from the license
if (!licenseGR.isValidRecord() || this._isUserExcludedFromLicense(userSysID, licenseSysID)) {
returnObj.canBeAdded = false;
return returnObj;
}
// can be assigned to the license
returnObj.canBeAdded = true;
returnObj.assignStatus = this.LICENSE_STATUS_ASSIGNED;
return returnObj;
},
canUserBeSubscribedToLicense: function(licenseSysID, userSysID) {
var result = this.canUserBeAssignedToLicense(licenseSysID, userSysID);
return ((result.canBeAdded == true) && (result.assignStatus == this.LICENSE_STATUS_ASSIGNED));
},
doesUserFailEnforcementLimit: function (pendingSysIdList) {
if (JSUtil.nil(pendingSysIdList))
return false;
var pendingGR = new GlideRecord('sys_user_pending_license');
pendingGR.addQuery('sys_id', pendingSysIdList[0]);
pendingGR.query();
if (pendingGR.next()) {
var licGR = new GlideRecord('license_details');
licGR.addQuery('sys_id', pendingGR.getValue('license'));
licGR.query();
if (licGR.next()) {
var allocated = parseInt(licGR.getValue("allocated"));
var purchased = parseInt(licGR.getValue("count"));
var toBeAllocated = pendingSysIdList.length;
var slotsAvailable = purchased - allocated;
var isCapped = licGR.getValue('is_capped') == '1';
var isLicenseOverflown = allocated >= purchased;
var willLicenseOverflow = toBeAllocated > slotsAvailable;
// If user has enforcement limit turned ON
// AND allocation count is equal to or more than purchased,
// OR no. of users to be subscripbed is more than available slots,
// he is not complying with the enforcement limit of the subscription.
return (isCapped && (isLicenseOverflown || willLicenseOverflow));
}
}
return false;
},
doesAddingAListOfUsersExceedPurchasedLimit: function(/* array */userList, licenseSysID) {
var licGR = new GlideRecord('license_details');
licGR.addQuery('sys_id', licenseSysID);
licGR.query();
if (licGR.next()) {
var allocated = parseInt(licGR.getValue("allocated"));
var purchased = parseInt(licGR.getValue("count"));
var toBeAllocated = userList.length;
var slotsAvailable = purchased - allocated;
return (toBeAllocated > slotsAvailable);
}
return false;
},
_fetchLicenseBySysID: function(licSysID) {
var licGR = new GlideRecord('license_details');
licGR.get(licSysID);
return licGR;
},
addToLicenseSource: function(userSysID, licenseSysID, userSetSysID, isDirect) {
if (this._doesLicenseSourceExist(userSysID, licenseSysID, userSetSysID, isDirect)) {
return;
}
var userLicenseSourceGR = new GlideRecord(this.LICENSE_SOURCE_TABLE);
userLicenseSourceGR.initialize();
userLicenseSourceGR.setValue('user', userSysID);
userLicenseSourceGR.setValue('license', licenseSysID);
if (isDirect) {
userLicenseSourceGR.setValue('is_direct', 1);
} else {
userLicenseSourceGR.setValue('user_set_source', userSetSysID);
}
userLicenseSourceGR.insert();
},
_doesLicenseSourceExist: function(userSysID, licenseSysID, userSetSysID, isDirect) {
var userLicenseSourceGR = new GlideRecord(this.LICENSE_SOURCE_TABLE);
userLicenseSourceGR.initialize();
userLicenseSourceGR.addQuery('user', userSysID);
userLicenseSourceGR.addQuery('license', licenseSysID);
if (isDirect) {
userLicenseSourceGR.addQuery('is_direct', 1);
} else {
userLicenseSourceGR.addQuery('user_set_source', userSetSysID);
}
userLicenseSourceGR.query();
return userLicenseSourceGR.hasNext();
},
movePendingUserHasLicenseRecToSubscribed: function(pendingLicSysId) {
var skipSourceDelete = true;
var userSysId = "";
var licSysId = "";
var source = "";
var pendingLicGR = new GlideRecord(this.USER_PENDING_LICENSE_TABLE);
pendingLicGR.addQuery('sys_id', pendingLicSysId);
pendingLicGR.query();
if(pendingLicGR.next()) {
userSysId = pendingLicGR.getValue('user');
licSysId = pendingLicGR.getValue('license');
source = pendingLicGR.getValue('source');
if (JSUtil.notNil(userSysId) && JSUtil.notNil(licSysId)) {
var userLicenseGR = new GlideRecord(this.USER_HAS_LICENSE_TABLE);
userLicenseGR.initialize();
userLicenseGR.setValue('user', userSysId);
userLicenseGR.setValue('license', licSysId);
userLicenseGR.setValue('source', source);
userLicenseGR.setWorkflow(false);
userLicenseGR.insert();
this._logChange(userSysId, licSysId, true, false, false);
}
this._deleteUserFromPendingLicenseBySysId(pendingLicSysId, skipSourceDelete);
}
},
unSubscribeEligibleUser: function (userSysID, licenseSysID) {
// Un-Subscribe users with reference count == 1. DO NOT delete the reference otherwise
var isUserRemoved = false;
if ( this._getNumLicenseSourcesForAUserAndLicense(userSysID, licenseSysID) === 1) {
var isUserSubscribed = this.isUserAddedToLicense(userSysID, licenseSysID);
if (isUserSubscribed) {
this._logChange(userSysID, licenseSysID, false, true, false);
this.removeAllSourcesForUserLicense(userSysID, licenseSysID);
this._deleteUserFromLicense(userSysID, licenseSysID);
isUserRemoved = true;
}
}
return isUserRemoved;
},
dismissEligibleUserFromPending: function (userSysID, licenseSysID) {
// Dismiss pending users with reference count == 1. DO NOT delete the reference otherwise
var isUserRemoved = false;
if ( this._getNumLicenseSourcesForAUserAndLicense(userSysID, licenseSysID) === 1) {
var isUserInPending = this._isUserPendingLicense(userSysID, licenseSysID);
if (isUserInPending) {
this.removeAllSourcesForUserLicense(userSysID, licenseSysID);
this._deleteUserFromPendingLicense(userSysID, licenseSysID);
isUserRemoved = true;
}
}
return isUserRemoved;
},
removeUserFromLicense: function(userSysID, licenseSysID, removedUserSetSysID) {
// User set disassociated from the license, attempt to remove all the users
// who came to the license from this user set
return this._removeAUserFromLicense(userSysID, licenseSysID, false, false, removedUserSetSysID);
},
removeUserDirectlyFromLicense: function(userSysID, licenseSysID) {
// Called when user is removed directly removed from the UI
return this._removeAUserFromLicense(userSysID, licenseSysID, true, false, '');
},
removeAndExcludeUserFromLicense: function(userSysID, licenseSysID) {
// Removes a user from license and also excludes him from the license
return this._removeAUserFromLicense(userSysID, licenseSysID, true, true, '');
},
removeAndExcludeUserFromPendingLicense: function(userSysID, licenseSysID) {
// Removes a user from license and also excludes him from the pending license
return this._removeAUserFromPendingLicense(userSysID, licenseSysID, true, true);
},
removeUserFromPendingLicense: function(userSysID, licenseSysID) {
// Removes user from pending licene without eligibility check
return this._removeAUserFromPendingLicense(userSysID, licenseSysID, true, false);
},
_removeAUserFromPendingLicense: function(userSysID, licenseSysID, wasRemovedFromUI, excludeUser) {
// There is 1 way in which a user could be removed from a pending license
// Directly selecting the record from the sys_user_pending_license table and deleting it
var isUserRemoved = false;
if (wasRemovedFromUI) {
// Removed directly from UI - log the action, remove all the license sources, add to the exclusion table
// Finally delete the user license association
this._logChange(userSysID, licenseSysID, false, false, excludeUser);
this.removeAllSourcesForUserLicense(userSysID, licenseSysID);
this._deleteUserFromPendingLicense(userSysID, licenseSysID);
isUserRemoved = true;
if (excludeUser)
this._addUserToLicenseExclusionList(userSysID, licenseSysID);
}
return isUserRemoved;
},
_removeAUserFromLicense: function(userSysID, licenseSysID, wasRemovedFromUI, excludeUser, removedUserSetSysID) {
// There are only 2 ways in which a user could be removed from a license
// Either directly selecting the record from the sys_user_has_license table and deleting it, or by removing
// a user set associated to a license
var isUserRemoved = false;
if (wasRemovedFromUI) {
// Removed directly from UI - log the action, remove all the license sources, add to the exclusion table
// Finally delete the user license association
this._logChange(userSysID, licenseSysID, false, true, excludeUser);
this.removeAllSourcesForUserLicense(userSysID, licenseSysID);
this._deleteUserFromLicense(userSysID, licenseSysID);
isUserRemoved = true;
if (excludeUser)
this._addUserToLicenseExclusionList(userSysID, licenseSysID);
return isUserRemoved;
}
// User set dis-associated from the license
// retrieve all the sources for this user and license,
// if the only source is this userset, remove this license user association
if (this._getNumLicenseSourcesForAUserAndLicense(userSysID, licenseSysID) === 1) {
var isUserInPending = this._isUserPendingLicense(userSysID, licenseSysID);
this._logChange(userSysID, licenseSysID, false, !isUserInPending, excludeUser);
this.removeAllSourcesForUserLicense(userSysID, licenseSysID);
if (isUserInPending) {
this._deleteUserFromPendingLicense(userSysID, licenseSysID);
isUserRemoved = true;
}
else {
this._deleteUserFromLicense(userSysID, licenseSysID);
isUserRemoved = true;
}
} else {
// He has this license from multiple sources, only disassociate this source
this.removeUserSetSourceForUserLicense(userSysID, licenseSysID, removedUserSetSysID);
}
return isUserRemoved;
},
_isUserPendingLicense: function(userSysID, licenseSysID) {
var pendingLicGR = new GlideRecord(this.USER_PENDING_LICENSE_TABLE);
pendingLicGR.addQuery('user', userSysID);
pendingLicGR.addQuery('license', licenseSysID);
pendingLicGR.query();
return pendingLicGR.hasNext();
},
_deleteUserFromPendingLicense: function(userSysID, licenseSysID) {
if (!this._isUserPendingLicense(userSysID, licenseSysID))
return;
// Deletes a user from a pending license.
var usrPendingLicGR = new GlideRecord(this.USER_PENDING_LICENSE_TABLE);
usrPendingLicGR.addQuery('user', userSysID);
usrPendingLicGR.addQuery('license', licenseSysID);
usrPendingLicGR.query();
if (usrPendingLicGR.next())
usrPendingLicGR.deleteRecord();
},
_deleteUserFromPendingLicenseBySysId: function(pendingLicSysId, skipSourceDelete) {
// Deletes a user from a pending license.
var usrPendingLicGR = new GlideRecord(this.USER_PENDING_LICENSE_TABLE);
usrPendingLicGR.addQuery('sys_id', pendingLicSysId);
usrPendingLicGR.query();
if (skipSourceDelete)
usrPendingLicGR.setWorkflow(false);
if (usrPendingLicGR.next())
usrPendingLicGR.deleteRecord();
},
_getNumLicenseSourcesForAUserAndLicense: function(userSysID, licenseSysID) {
var userLicenseSourceGR = new GlideRecord(this.LICENSE_SOURCE_TABLE);
userLicenseSourceGR.addQuery('user', userSysID);
userLicenseSourceGR.addQuery('license', licenseSysID);
userLicenseSourceGR.query();
return userLicenseSourceGR.getRowCount();
},
removeUserSetSourceForUserLicense: function(userSysID, licenseSysID, sourceUserSetSysID) {
var userLicenseSourceGR = new GlideRecord(this.LICENSE_SOURCE_TABLE);
userLicenseSourceGR.addQuery('user', userSysID);
userLicenseSourceGR.addQuery('license', licenseSysID);
userLicenseSourceGR.addQuery('user_set_source', sourceUserSetSysID);
userLicenseSourceGR.query();
if (userLicenseSourceGR.next())
userLicenseSourceGR.deleteRecord();
},
removeDirectSourceForUserLicense: function(userSysID, licenseSysID, licenseSource) {
var userLicenseSourceGR = new GlideRecord(this.LICENSE_SOURCE_TABLE);
userLicenseSourceGR.addQuery('user', userSysID);
userLicenseSourceGR.addQuery('license', licenseSysID);
userLicenseSourceGR.addQuery('is_direct', '1');
userLicenseSourceGR.query();
if (userLicenseSourceGR.next())
userLicenseSourceGR.deleteRecord();
},
removeAllSourcesForUserLicense: function(userSysID, licenseSysID) {
// Removes all the licenses sources for this user and license
var userLicenseSourceGR = new GlideRecord(this.LICENSE_SOURCE_TABLE);
userLicenseSourceGR.addQuery('user', userSysID);
userLicenseSourceGR.addQuery('license', licenseSysID);
userLicenseSourceGR.query();
while (userLicenseSourceGR.next()) {
userLicenseSourceGR.deleteRecord();
}
},
_addUserToLicenseExclusionList: function(userSysID, licenseSysID) {
var userExcludeGR = new GlideRecord(this.LICENSE_EXCLUSION_TABLE);
userExcludeGR.initialize();
userExcludeGR.setValue('user', userSysID);
userExcludeGR.setValue('license', licenseSysID);
userExcludeGR.setWorkflow(false);
userExcludeGR.insert();
},
removeUserFromLicenseExclusionList: function(userSysID, licenseSysID) {
if (!this._isUserExcludedFromLicense(userSysID, licenseSysID))
return;
var userExcludeGR = new GlideRecord(this.LICENSE_EXCLUSION_TABLE);
userExcludeGR.addQuery('user', userSysID);
userExcludeGR.addQuery('license', licenseSysID);
userExcludeGR.query();
if (userExcludeGR.next())
userExcludeGR.deleteRecord();
},
_isUserExcludedFromLicense: function(userSysID, licenseSysID) {
var userExcludeGR = new GlideRecord(this.LICENSE_EXCLUSION_TABLE);
userExcludeGR.addQuery('user', userSysID);
userExcludeGR.addQuery('license', licenseSysID);
userExcludeGR.query();
return userExcludeGR.hasNext();
},
getExcludedUsersForLicense: function(licenseSysID) {
var excludedUserSysIds = [];
var userExcludeGR = new GlideRecord(this.LICENSE_EXCLUSION_TABLE);
userExcludeGR.addQuery('license', licenseSysID);
userExcludeGR.query();
while (userExcludeGR.next()) {
excludedUserSysIds.push(userExcludeGR.getValue('user'));
}
return excludedUserSysIds;
},
getUsersAllocatedForLicense: function(licenseSysID) {
var subscribedUserSysIds = [];
var subscribedUserGR = new GlideRecord(this.USER_HAS_LICENSE_TABLE);
subscribedUserGR.addQuery('license', licenseSysID);
subscribedUserGR.query();
while (subscribedUserGR.next())
subscribedUserSysIds.push(subscribedUserGR.getValue('user'));
return subscribedUserSysIds;
},
_deleteUserFromLicense: function(userSysID, licenseSysID) {
// Deletes a user from a license, does not matter what state he is in
var userLicenseGR = new GlideRecord(this.USER_HAS_LICENSE_TABLE);
userLicenseGR.addQuery('user', userSysID);
userLicenseGR.addQuery('license', licenseSysID);
userLicenseGR.addQuery('source', '!=', 'sys_entl');
userLicenseGR.query();
if (userLicenseGR.next())
userLicenseGR.deleteRecord();
},
canUserBeRemovedFromSubscription: function(userSysID, licenseSysID) {
var userLicenseGR = this._getUserAddedToLicense(userSysID, licenseSysID);
// Allowed to add a user to the excluded list if we don't have any records already...
if(!userLicenseGR.hasNext())
return true;
// users added to license with System Entitlement source should never be deleted
// if multiple source found, non System Entitlement users can be removed
var isSystemEntitlement = false;
var hasMultipleSource = false;
while (userLicenseGR.next()) {
if(userLicenseGR.getValue('source') == 'sys_entl')
isSystemEntitlement = true;
else
hasMultipleSource = true;
}
if (isSystemEntitlement && !hasMultipleSource)
return false;
return true;
},
_logChange: function(userSysId, licSysId, isAdd, isRemove, isExclude){
if (isAdd)
this.auditHelper.recordSubscribed(userSysId, licSysId);
else if (isRemove && !isExclude)
this.auditHelper.recordUnSubscribed(userSysId, licSysId);
else if (!isRemove && isExclude)
this.auditHelper.recordExcluded(userSysId, licSysId);
else if (isRemove && isExclude){
this.auditHelper.recordUnSubscribed(userSysId, licSysId);
this.auditHelper.recordExcluded(userSysId, licSysId);
}
},
type: 'UserSubscriptionHelper'
};
Sys ID
89eebd739f2302001526317f842e70fd