/// <summary> /// Update the provisioning status for a single unexpected user /// </summary> /// <param name="unexpectedUser"></param> /// <param name="siteSignIn"></param> private void Execute_UpdateUnexpectedUsersProvisioning_SingleUser( SiteUser unexpectedUser, TableauServerSignIn siteSignIn, WorkingListSiteUsers workingList_allKnownUsers) { _statusLogs.AddStatus("Process unexpected user: "******"811-1123: Unknown authentication type " + unexpectedUser.SiteAuthentication + ", for user " + unexpectedUser.Name); _statusLogs.AddError("811-1123: Unknown authentication type " + unexpectedUser.SiteAuthentication + ", for user " + unexpectedUser.Name); break; } }
/// <summary> /// Provision the groups /// </summary> /// <param name="siteSignIn"></param> private void Execute_ProvisionGroups(TableauServerSignIn siteSignIn, WorkingListSiteUsers workingList_allKnownUsers) { //If there are no provisioning instructions, then there is nothing we need to do here if (_provisionInstructions.GroupsToProvision == null) { _statusLogs.AddStatus("Skipping groups provisioning, because there are no instructions for this..."); return; } _statusLogs.AddStatusHeader("Provision the specified groups in site"); //================================================================================= //If we do not have it already, load the set of users for the site...we will need this to look up users //================================================================================= if (workingList_allKnownUsers == null) { var existingUsers = DownloadUsersList.CreateAndExecute(siteSignIn); existingUsers.ExecuteRequest(); workingList_allKnownUsers = new WorkingListSiteUsers(existingUsers.Users); } //================================================================================= //Download the groups //================================================================================= var downloadGroups = new DownloadGroupsList(siteSignIn); downloadGroups.ExecuteRequest(false); //Download the list of groups, but not the membership of the groups (we will only do that for the groups we care about) //Go through each of the groups... foreach (var thisProvisionGroup in _provisionInstructions.GroupsToProvision) { Execute_ProvisionGroups_SingleGroup(siteSignIn, thisProvisionGroup, downloadGroups, workingList_allKnownUsers); } }
/// <summary> /// Compare the list of users on the Server Site with the provision list of users and make the necessary updates /// </summary> /// <param name="existingSiteUsers"></param> private WorkingListSiteUsers Execute_ProvisionUsers(TableauServerSignIn siteSignIn) { //If there are no provisioning instructions, then there is nothing we need to do here if (_provisionInstructions.UsersToProvision == null) { _statusLogs.AddStatus("Skipping users/roles provisioning, because there are no instructions for this..."); return(null); } _statusLogs.AddStatusHeader("Provision users/roles in site"); //================================================================================= //Load the set of users for the site... //================================================================================= var existingUsers = DownloadUsersList.CreateAndExecute(siteSignIn); //Keep a list of the remaining users var workingListUnexaminedUsers = new WorkingListSiteUsers(existingUsers.Users); var workingList_allKnownUsers = new WorkingListSiteUsers(existingUsers.Users); //============================================================================== //Go through each user in our "to provision" list and see if we need to // 1. Add them as a new user // 2. Update an exisitng user //============================================================================== _statusLogs.AddStatusHeader("Process explicit users list"); foreach (var userToProvision in _provisionInstructions.UsersToProvision) { try { Execute_ProvisionUsers_SingleUser(userToProvision, siteSignIn, workingListUnexaminedUsers, workingList_allKnownUsers); } catch (Exception ex) { _statusLogs.AddError("Error provisioning user (913-1158)" + userToProvision.UserName + ", " + ex.Message); CSVRecord_ErrorUpdatingUser(userToProvision.UserName, userToProvision.UserRole, userToProvision.UserAuthentication, "Error provisioning user " + userToProvision.UserName + ", " + ex.Message); } //If the user was in the working list of users on the site, then remove them (since we have looked at them) workingListUnexaminedUsers.RemoveUser(userToProvision.UserName); } //============================================================================================ //Examine all the remaining users and decide if we need to unlicense or delete them //============================================================================================ _statusLogs.AddStatusHeader("Process unexpected users list"); foreach (var unexpectedUser in workingListUnexaminedUsers.GetUsers()) { try { Execute_UpdateUnexpectedUsersProvisioning_SingleUser(unexpectedUser, siteSignIn, workingList_allKnownUsers); } catch (Exception exUnxpectedUsers) { _statusLogs.AddError("Error processing unexpected user " + unexpectedUser.ToString() + ", " + exUnxpectedUsers.Message); CSVRecord_ErrorUpdatingUser(unexpectedUser.Name, unexpectedUser.SiteRole, unexpectedUser.SiteAuthentication, "Error processing unexpected user " + unexpectedUser.ToString() + ", " + exUnxpectedUsers.Message); } } return(workingList_allKnownUsers); }
/// <summary> /// Process the ownership-mapping request for a single user /// </summary> /// <param name="siteSignIn"></param> /// <param name="thisOwnershipChange"></param> /// <param name="workingList_allKnownUsers"></param> /// <param name="knownDataSources"></param> private void Execute_ProvisionOwnership_SingleUserChange_inner( TableauServerSignIn siteSignIn, ProvisioningChangeContentOwnership thisOwnershipChange, WorkingListSiteUsers workingList_allKnownUsers, ICollection <SiteDatasource> knownDataSources, ICollection <SiteFlow> knownFlows) { var userOldOwner = workingList_allKnownUsers.FindUserByName(thisOwnershipChange.OldOwnerName); if (userOldOwner == null) { throw new Exception("201202-415: Could not find user: "******"201202-416: Could not find user: " + userNewOwner.Name); } //------------------------------------------------------------------------------------ //Check the ownership of each of these types of content, and update from the //old owner to the designated new owner //------------------------------------------------------------------------------------ Execute_ProvisionOwnership_SingleUserChange_Workbooks(siteSignIn, userOldOwner, userNewOwner); Execute_ProvisionOwnership_SingleUserChange_Datasources(siteSignIn, knownDataSources, userOldOwner, userNewOwner); Execute_ProvisionOwnership_SingleUserChange_Flows(siteSignIn, userOldOwner, userNewOwner, knownFlows); }
/// <summary> /// Follows the instructions for any content ownership changes we want to make /// </summary> /// <param name="siteSignIn"></param> /// <param name="workingList_allKnownUsers"></param> private void Execute_ProvisionContentOwnershipChanges(TableauServerSignIn siteSignIn, WorkingListSiteUsers workingList_allKnownUsers) { //=============================================================================================== //If there are no content ownership changes to perform, then just exit this step //=============================================================================================== if ((_provisionInstructions.ContentOwnershipToProvision == null) || (_provisionInstructions.ContentOwnershipToProvision.Count == 0)) { _statusLogs.AddStatus("Skipping content ownership mapping, because there are no instructions for this..."); return; } _statusLogs.AddStatusHeader("Provision content ownership changes"); //================================================================================= //If we do not have it already, load the set of users for the site...we will need this to look up users //================================================================================= if (workingList_allKnownUsers == null) { var existingUsers = DownloadUsersList.CreateAndExecute(siteSignIn); existingUsers.ExecuteRequest(); workingList_allKnownUsers = new WorkingListSiteUsers(existingUsers.Users); } //================================================================================= //Unlike Workbooks, there is not a simple URL to download the list of Datasources //for a single user. (There is a filter parameter that can be added to the REST //API that queries data sources, but that takes a "user name" not a User ID). //Here we can query for ALL the data sources pass that to all teh remappign request //================================================================================= var downloadDataSources = new DownloadDatasourcesList(siteSignIn); downloadDataSources.ExecuteRequest(); var allSiteDataSources = downloadDataSources.Datasources; //================================================================================= //Get the list of flows in the iste //================================================================================= var downloadFlows = new DownloadFlowsList(siteSignIn); downloadFlows.ExecuteRequest(); var allSiteFlows = downloadFlows.Flows; //Go through each of the ownership change instructions... foreach (var thisOwnershipChange in _provisionInstructions.ContentOwnershipToProvision) { Execute_ProvisionOwnership_SingleUserChange( siteSignIn, thisOwnershipChange, workingList_allKnownUsers, allSiteDataSources, allSiteFlows); } }
/// <summary> /// Handle the provisioning for a single user /// </summary> /// <param name="userToProvision"></param> /// <param name="siteSignIn"></param> /// <param name="workingListUnexaminedUsers"></param> private void Execute_ProvisionUsers_SingleUser( ProvisioningUser userToProvision, TableauServerSignIn siteSignIn, WorkingListSiteUsers workingListUnexaminedUsers) { //See if a user with this name already exists var foundExistingUser = workingListUnexaminedUsers.FindUser(userToProvision.UserName); ProvisionUserInstructions.MissingUserAction missingUserAction; ProvisionUserInstructions.UnexpectedUserAction unexpectedUserAction; //Get the instructions based on the desired Auth model for the user we are provisioning switch (userToProvision.UserAuthenticationParsed) { case SiteUserAuth.Default: missingUserAction = _provisionInstructions.ActionForMissingDefaultAuthUsers; unexpectedUserAction = _provisionInstructions.ActionForUnexpectedDefaultAuthUsers; break; case SiteUserAuth.SAML: missingUserAction = _provisionInstructions.ActionForMissingSamlUsers; unexpectedUserAction = _provisionInstructions.ActionForUnexpectedSamlUsers; break; default: IwsDiagnostics.Assert(false, "814-1204: Unknown auth type"); throw new Exception("814-1204: Unknown auth type"); } //CASE 1: The user does NOT exist. So add them if (foundExistingUser == null) { Execute_ProvisionUsers_SingleUser_AddUser(siteSignIn, userToProvision, missingUserAction); return; } //CASE 2: The user EXISTS but is not the right role or auth; update them if ( (string.Compare(foundExistingUser.SiteRole, userToProvision.UserRole, true) != 0) || (string.Compare(foundExistingUser.SiteAuthentication, userToProvision.UserAuthentication, true) != 0) ) { Execute_ProvisionUsers_SingleUser_ModifyUser(siteSignIn, userToProvision, foundExistingUser); return; } //CASE 3: The user exists and does NOT need to be modified _statusLogs.AddStatus("No action: User exists and has expected role and authentication. User: " + userToProvision.UserName); }
/// <summary> /// Queries a site for all its users, and for recent content. /// Genterates and sends email to all the users /// </summary> /// <param name="showLogsHere"></param> /// <param name="statusLogs"></param> public void Execute() { WorkingListSiteUsers workingList_allKnownUsers = null; //================================================================================== //Get the data we need to run //================================================================================== //Generate the URLs we will need var siteUrlManager = TableauServerUrls.FromContentUrl(_config.SiteUrl, TaskMasterOptions.RestApiReponsePageSizeDefault); //================================================================================= //Sign in to the site //================================================================================= var siteSignIn = new TableauServerSignIn( siteUrlManager, _config.SiteClientId, _config.Secret, _statusLogs, _config.SiteSignInMode); var signInSuccess = siteSignIn.Execute(); ShowLogs(); //================================================================================= //Get the basic site info //================================================================================= var downloadSiteInfo = new DownloadSiteInfo(siteSignIn); downloadSiteInfo.ExecuteRequest(); var siteInfo = downloadSiteInfo.Site; ShowLogs(); //================================================================================= //Provision the users //================================================================================= workingList_allKnownUsers = Execute_ProvisionUsers(siteSignIn); ShowLogs(); //================================================================================= //Provision the groups //================================================================================= Execute_ProvisionGroups(siteSignIn, workingList_allKnownUsers); //================================================================================= //Content ownership changes //================================================================================= Execute_ProvisionContentOwnershipChanges(siteSignIn, workingList_allKnownUsers); }
/// <summary> /// Update the unexpected user based on the specified behavior /// </summary> /// <param name="unexpectedUser"></param> /// <param name="siteSignIn"></param> /// <param name="behavior"></param> private void Execute_UpdateUnexpectedUsersProvisioning_SingleUser_WithBehavior( SiteUser unexpectedUser, TableauServerSignIn siteSignIn, ProvisionUserInstructions.UnexpectedUserAction behavior, WorkingListSiteUsers workingList_allKnownUsers) { switch (behavior) { case ProvisionUserInstructions.UnexpectedUserAction.Report: _statusLogs.AddStatus("No action: Keep unexpected user unaltered. User: "******"SIMULATED existing/removed", unexpectedUser.SiteRole + "->" + "Unlicensed"); return; } return; case ProvisionUserInstructions.UnexpectedUserAction.Unlicense: Execute_UpdateUnexpectedUsersProvisioning_SingleUser_WithBehavior_Unlicense( unexpectedUser, siteSignIn, workingList_allKnownUsers); return; case ProvisionUserInstructions.UnexpectedUserAction.Delete: Execute_UpdateUnexpectedUsersProvisioning_SingleUser_WithBehavior_Delete( unexpectedUser, siteSignIn, workingList_allKnownUsers); return; default: IwsDiagnostics.Assert(false, "811-1130: Internal error. Unknown provisioning behavior for user " + unexpectedUser.ToString()); _statusLogs.AddError("811-1130: Internal error. Unknown provisioning behavior for user " + unexpectedUser.ToString()); return; } }
/// <summary> /// Add a specific user into the Server Site's group /// </summary> /// <param name="userEmail"></param> /// <param name="thisProvisionGroup"></param> /// <param name="siteUsersList"></param> private void Execute_ProvisionGroups_SingleGroup_AddUser( TableauServerSignIn siteSignIn, string userEmail, SiteGroup siteGroup, WorkingListSiteUsers siteUsersList) { var siteUserToAddToGroup = siteUsersList.FindUserByName(userEmail); //Sanity test. If the user is not a member of the site, they cannot be added to a group if (siteUserToAddToGroup == null) { CSVRecord_ErrorUpdatingUser(userEmail, "", "", "User not on site. Cannot be added to group"); _statusLogs.AddError("User not on site. Cannot be added to group, " + userEmail); return; //FAILED } switch (_provisionInstructions.ActionForMissingGroupMembers) { case ProvisionUserInstructions.MissingGroupMemberAction.Add: //Call the server and add the user var addUserToGroup = new SendAddUserToGroup(siteSignIn, siteUserToAddToGroup.Id, siteGroup.Id); bool userGroupAddSuccess = addUserToGroup.ExecuteRequest(); if (userGroupAddSuccess) { //SUCCESS CSVRecord_GroupModified_WithUser(siteGroup.Name, "added member", siteUserToAddToGroup.Name, ""); _statusLogs.AddStatus("Group membership: Added " + siteUserToAddToGroup.Name + " to group " + siteGroup.Name); } else { CSVRecord_ErrorUpdatingUser(userEmail, "", "", "User could not be added to group " + siteGroup.Name); _statusLogs.AddError("Group membership error: Failed to add " + siteUserToAddToGroup.Name + " to group " + siteGroup.Name); } return; case ProvisionUserInstructions.MissingGroupMemberAction.Report: //We are instructed to NOT REALLY add the user, jsut report CSVRecord_GroupModified_WithUser(siteGroup.Name, "SIMULATED added member", siteUserToAddToGroup.Name, ""); return; default: IwsDiagnostics.Assert(false, "814-433: Unknown action"); throw new Exception("814-433: Unknown action"); } }
/// <summary> /// Unlicense the user /// </summary> /// <param name="unexpectedUser"></param> /// <param name="siteSignIn"></param> /// <param name="workingList_allKnownUsers"></param> private void Execute_UpdateUnexpectedUsersProvisioning_SingleUser_WithBehavior_Unlicense( SiteUser unexpectedUser, TableauServerSignIn siteSignIn, WorkingListSiteUsers workingList_allKnownUsers) { //If the user is already unlicensed, then there is nothing that needs to be done if (unexpectedUser.SiteRoleParsed == SiteUserRole.Unlicensed) { return; } _statusLogs.AddStatus("Unlicense unexpected user: "******"existing/removed", unexpectedUser.SiteRole + "->" + userUpdated.SiteRole); workingList_allKnownUsers.ReplaceUser(userUpdated); return; } else { CSVRecord_ErrorUpdatingUser(unexpectedUser.Name, unexpectedUser.SiteRole, unexpectedUser.SiteAuthentication, "Error unlicensing user (913-215)"); return; } }
/// <summary> /// The ADD-User path for provisioning a user /// </summary> /// <param name="siteSignIn"></param> /// <param name="userToProvision"></param> /// <param name="missingUserAction"></param> private SiteUser Execute_ProvisionUsers_SingleUser_AddUser( TableauServerSignIn siteSignIn, ProvisioningUser userToProvision, ProvisionUserInstructions.MissingUserAction missingUserAction, WorkingListSiteUsers workingList_allKnownUsers) { switch (missingUserAction) { //Add the user case ProvisionUserInstructions.MissingUserAction.Add: //Setup to create a new user var createUser = new SendCreateUser( siteSignIn.ServerUrls, siteSignIn, userToProvision.UserName, userToProvision.UserRole, userToProvision.UserAuthenticationParsed); var userCreated = createUser.ExecuteRequest(); //------------------------------------------------------------------------------- //Record the action in an output file //------------------------------------------------------------------------------- CSVRecord_UserModified(userToProvision.UserName, userToProvision.UserRole, userToProvision.UserAuthentication, "added", ""); workingList_allKnownUsers.AddUser(userCreated); return(userCreated); //Don't add the user, just record the finding case ProvisionUserInstructions.MissingUserAction.Report: CSVRecord_UserModified(userToProvision.UserName, userToProvision.UserRole, userToProvision.UserAuthentication, "SIMULATED added", ""); return(null); default: IwsDiagnostics.Assert(false, "814-1210: Unknown missing user provisioning action"); throw new Exception("814-1210: Unknown missing user provisioning action"); } }
/// <summary> /// Change the ownership from 1 user, to another user /// </summary> /// <param name="siteSignIn"></param> /// <param name="thisOwnershipChange"></param> /// <param name="workingList_allKnownUsers"></param> private void Execute_ProvisionOwnership_SingleUserChange( TableauServerSignIn siteSignIn, ProvisioningChangeContentOwnership thisOwnershipChange, WorkingListSiteUsers workingList_allKnownUsers, ICollection <SiteDatasource> knownDataSources, ICollection <SiteFlow> knownFlows) { try { Execute_ProvisionOwnership_SingleUserChange_inner( siteSignIn, thisOwnershipChange, workingList_allKnownUsers, knownDataSources, knownFlows); } catch (Exception ex) { _statusLogs.AddError("Error attempting to change content ownership, from: " + thisOwnershipChange.OldOwnerName + ", to:" + thisOwnershipChange.NewOwnerName + ", error: " + ex.ToString()); } }
/// <summary> /// Provisioning for a single group /// </summary> /// <param name="siteSignIn"></param> /// <param name="thisProvisionGroup"></param> /// <param name="existingGroups"></param> private void Execute_ProvisionGroups_SingleGroup( TableauServerSignIn siteSignIn, ProvisioningGroup thisProvisionGroup, DownloadGroupsList existingGroups, DownloadUsersList siteUsersList) { _statusLogs.AddStatusHeader("Provision the group: " + thisProvisionGroup.GroupName); var thisExistingGroup = existingGroups.FindGroupWithName(thisProvisionGroup.GroupName); ICollection <SiteUser> existingUsersInGroup = new List <SiteUser>(); //If the Group does not exist on server then create it if (thisExistingGroup == null) { var createGroup = new SendCreateGroup(siteSignIn, thisProvisionGroup.GroupName); thisExistingGroup = createGroup.ExecuteRequest(); CSVRecord_GroupModified(thisExistingGroup.Name, "created group", ""); _statusLogs.AddStatus("Created group: " + thisExistingGroup.Name); } else { //Download the members of the group var downloadGroupMembers = new DownloadUsersListInGroup(siteSignIn, thisExistingGroup.Id); downloadGroupMembers.ExecuteRequest(); existingUsersInGroup = downloadGroupMembers.Users; } //==================================================================================== //Keep a list of the remaining users in the Server Site's group //==================================================================================== var workingListUnexaminedUsers = new WorkingListSiteUsers(existingUsersInGroup); //==================================================================================== //Go through each of the users we need to provision, and see if they are in the group //already //==================================================================================== foreach (var provisionThisUser in thisProvisionGroup.Members) { var userInGroup = workingListUnexaminedUsers.FindUser(provisionThisUser); if (userInGroup != null) { //The user is already in the group, no need to add them workingListUnexaminedUsers.RemoveUser(userInGroup); } else { //Add the user to the group try { Execute_ProvisionGroups_SingleGroup_AddUser(siteSignIn, provisionThisUser, thisExistingGroup, siteUsersList); } catch (Exception exAddUserToGroup) //Unexpected error case { IwsDiagnostics.Assert(false, "811-700: Internal error adding user to group: " + exAddUserToGroup.Message); _statusLogs.AddError("811-700: Internal error adding user to group: " + exAddUserToGroup.Message); } } } //============================================================================== //Remove any remaining users that are in the Server Site's Group but not in //our provisioning list //============================================================================== foreach (var unexpectedUser in workingListUnexaminedUsers.GetUsers()) { try { Execute_ProvisionGroups_RemoveSingleUser(siteSignIn, unexpectedUser, thisExistingGroup); } catch (Exception exUnxpectedUsers) { _statusLogs.AddError("Error removing unexpected user in GROUP " + unexpectedUser.ToString() + ", " + exUnxpectedUsers.Message); CSVRecord_Error(unexpectedUser.Name, unexpectedUser.SiteRole, unexpectedUser.SiteAuthentication, "Error removing unexpected user in GROUP" + unexpectedUser.ToString() + ", " + exUnxpectedUsers.Message); } } }
/// <summary> /// Delete and unexpected user /// </summary> /// <param name="unexpectedUser"></param> /// <param name="siteSignIn"></param> /// <param name="workingList_allKnownUsers"></param> private void Execute_UpdateUnexpectedUsersProvisioning_SingleUser_WithBehavior_Delete(SiteUser unexpectedUser, TableauServerSignIn siteSignIn, WorkingListSiteUsers workingList_allKnownUsers) { _statusLogs.AddStatus("Delete unexpected user: "******"existing/deleted", unexpectedUser.SiteRole + "->" + "DELETED"); workingList_allKnownUsers.RemoveUser(unexpectedUser.Name); return; //SUCCESS } //============================================================================================ //The delete user attempt was not a success (probably the user has owned content) //Log an error and attempt to unlicense the user //============================================================================================ CSVRecord_ErrorUpdatingUser( unexpectedUser.Name, unexpectedUser.SiteRole, unexpectedUser.SiteAuthentication, "Error deleting user (1020-227)"); //If the user is not unlicensed, then unlicense them... if (unexpectedUser.SiteRoleParsed != SiteUserRole.Unlicensed) { Execute_UpdateUnexpectedUsersProvisioning_SingleUser_WithBehavior_Unlicense( unexpectedUser, siteSignIn, workingList_allKnownUsers); } }
/// <summary> /// Handle the provisioning for a single user /// </summary> /// <param name="userToProvision"></param> /// <param name="siteSignIn"></param> /// <param name="workingListUnexaminedUsers"></param> private void Execute_ProvisionUsers_SingleUser( ProvisioningUser userToProvision, TableauServerSignIn siteSignIn, WorkingListSiteUsers workingListUnexaminedUsers, WorkingListSiteUsers workingList_allKnownUsers) { //See if a user with this name already exists var foundExistingUser = workingListUnexaminedUsers.FindUserByName(userToProvision.UserName); ProvisionUserInstructions.MissingUserAction missingUserAction; ProvisionUserInstructions.UnexpectedUserAction unexpectedUserAction; //Get the instructions based on the desired Auth model for the user we are provisioning switch (userToProvision.UserAuthenticationParsed) { case SiteUserAuth.Default: missingUserAction = _provisionInstructions.ActionForMissingDefaultAuthUsers; unexpectedUserAction = _provisionInstructions.ActionForUnexpectedDefaultAuthUsers; break; case SiteUserAuth.SAML: missingUserAction = _provisionInstructions.ActionForMissingSamlUsers; unexpectedUserAction = _provisionInstructions.ActionForUnexpectedSamlUsers; break; case SiteUserAuth.OpenID: missingUserAction = _provisionInstructions.ActionForMissingOpenIdUsers; unexpectedUserAction = _provisionInstructions.ActionForUnexpectedOpenIdUsers; break; default: var unknownAuthType = userToProvision.UserAuthentication; if (unknownAuthType == null) { unknownAuthType = ""; } IwsDiagnostics.Assert(false, "814-1204: Unknown auth type, " + unknownAuthType); throw new Exception("814-1204: Unknown auth type, " + unknownAuthType); } //=============================================================================================== //CASE 1: The user does NOT exist. So add them //=============================================================================================== if (foundExistingUser == null) { Execute_ProvisionUsers_SingleUser_AddUser(siteSignIn, userToProvision, missingUserAction, workingList_allKnownUsers); return; } //=============================================================================================== //CASE 2a: The user EXISTS but is not the right AUTH; update them //=============================================================================================== if (string.Compare(foundExistingUser.SiteAuthentication, userToProvision.UserAuthentication, true) != 0) { //Update the user Execute_ProvisionUsers_SingleUser_ModifyUser(siteSignIn, userToProvision, foundExistingUser); return; } //=============================================================================================== //CASE 2b: The user EXISTS but is not the right ROLE; update them //=============================================================================================== else if (string.Compare(foundExistingUser.SiteRole, userToProvision.UserRole, true) != 0) { //================================================================================================================================================================== //CASE 2b: Special case (to support Grant License on Sign In: If the user provisioning insturctions ALLOW //NOTE: If the authentication schemes do not match, then move foward with modifying the user -- this is a more fundamental change, and we should honor it explicitly //================================================================================================================================================================== if (userToProvision.AllowPromotedRole) { var existingUserRoleRank = ProvisioningUser.CalculateRoleRank(foundExistingUser.SiteRole); if (existingUserRoleRank > userToProvision.RoleRank) { _statusLogs.AddStatus("No action: Provisioning rule for this user allow keeping existing higher ranked role. User: "******", " + foundExistingUser.SiteRole); return; } } //CASE 2c: Update the user because the provisioning Role differs from the existing user's Role Execute_ProvisionUsers_SingleUser_ModifyUser(siteSignIn, userToProvision, foundExistingUser); return; } //=============================================================================================== //CASE 3: The user exists and does NOT need to be modified //=============================================================================================== _statusLogs.AddStatus("No action: User exists and has expected role and authentication. User: " + userToProvision.UserName); }