/// <summary> /// Processes the groups from AD and updates the users as needed. /// </summary> /// <param name="employeeId">The id of the employee</param> /// <param name="groupNames">The names of the groups the user is a member of</param> public void ProcessGroupChanges(EntityId employeeId, List <string> groupNames) { // get the id of the user's profile EntityId profileId = null; if (EmployeeProfileCache.ContainsKey(employeeId.Token)) { profileId = new EntityId(EmployeeProfileCache.GetValue(employeeId.Token)); } if (profileId == null) { // did not find it in the cache...get the id from the api var employeeProfileId = ApiService.GetEmployeeProfileIdAsync(employeeId, AuthToken).GetAwaiter().GetResult(); profileId = new EntityId(employeeProfileId); } // get the existing group membership var onlineGroupsIds = ApiService.GetGroupMembershipAsync(profileId, AuthToken).GetAwaiter().GetResult(); // we only get Ids back from the API so we need to further process them // so that we xref the Ids to the group names returned by AD var onlineGroups = ProcessOnlineGroups(onlineGroupsIds); // if not then add them to the user var groupsToAdd = new List <EntityId>(); var adGroupIds = new List <string>(); groupNames.ForEach(grpName => { var groupId = EmployeeGroupCache.GetValue(grpName); if (groupId == null) { // try to get the group by its name using the api groupId = ApiService.GetGroupAsync(grpName, AuthToken).GetAwaiter().GetResult(); } if (groupId == null) { // group is not in the system and needs to be created. groupId = ApiService.CreateGroupAsync(grpName, AuthToken).GetAwaiter().GetResult(); EmployeeGroupCache.Add(groupId, grpName); } // add the group to the list of AD groups...we will use this list to // figure out which groups need to be removed from Compliance 360 adGroupIds.Add(groupId); // if the user is not a current member of the group then // put it in the list to add to the profile if (!onlineGroups.ContainsKey(groupId)) { groupsToAdd.Add(new EntityId(groupId)); } }); // check the list of online group Ids. If they are not in the list // of local AD groups them remove it var groupsToRemove = new List <EntityId>(); foreach (var onlineGroup in onlineGroupsIds) { // bit of a hack but we do not want to remove the user from the // division employees groups if (onlineGroups[onlineGroup].Contains("Employees")) { continue; } if (!adGroupIds.Contains(onlineGroup)) { groupsToRemove.Add(new EntityId(onlineGroup)); } } ApiService.UpdateEmployeeProfileAsync(profileId, groupsToAdd, groupsToRemove, AuthToken); }
/// <summary> /// Writes the user to the stream /// </summary> /// <param name="user">Reference to the user to write to the stream.</param> public void Write(ActiveDirectoryUser user) { var employee = new MetaObject(); // process each of the field values in the map string employeeNum = null; EntityId workflowTemplate = null; EntityId division = null; SortedList <string, string> groups = null; foreach (MapElement map in StreamConfig.Mapping) { object value = null; switch (map.To) { case SystemFields.JobTitleId: value = GetJobTitleValue(map.From, division, user); break; case SystemFields.EmployeeNum: employeeNum = GetFieldValue(map.From, user); value = employeeNum; break; case SystemFields.Department: value = GetDepartment(map.From, user, division); break; case SystemFields.PrimaryDivision: division = GetDivisionFieldValue(map.From, user); value = division; break; case SystemFields.Groups: groups = GetFieldValueAsObject(map.From, user) as SortedList <string, string>; break; case SystemFields.WorkflowTemplate: break; default: value = GetFieldValue(map.From, user); break; } // only map the property if a value is present if (value != null) { employee[map.To] = value; } } if (employeeNum == null) { var userJson = JsonConvert.SerializeObject(user); Logger.Error("Error writing Employee to stream. Missing EmployeeNum map \"to\" value. {0}", userJson); return; } if (division == null) { var userJson = JsonConvert.SerializeObject(user); Logger.Error("Error writing Employee to stream. Missing PrimaryDivision map \"to\" value. {0}", userJson); return; } if (workflowTemplate == null) { workflowTemplate = GetDefaultWorkflowTemplate(); employee[SystemFields.WorkflowTemplate] = workflowTemplate; } // get the id of the employee from the cache...if found this is an update // otherwise we are creating a new employee. EntityId employeeId = null; if (EmployeeCache.ContainsKey(employeeNum)) { employeeId = new EntityId(EmployeeCache.GetValue(employeeNum)); } else { // check to see if the username already exists in c360 var empId = ApiService.GetEmployeeIdAsync(employeeNum, AuthToken).GetAwaiter().GetResult(); if (empId != null) { employeeId = new EntityId(empId); EmployeeCache.Add(employeeNum, employeeId.Token); } } if (employeeId == null) { // create the new employee record employee[SystemFields.CanLogin] = true; employee[SystemFields.Password] = Guid.NewGuid().ToString(); employeeId = new EntityId(ApiService.CreateEmployeeAsync(employee, AuthToken).GetAwaiter().GetResult()); EmployeeCache.Add(employeeNum, employeeId.Token); } else { // update an existing employee record ApiService.UpdateEmployeeAsync(employeeId, employee, AuthToken).GetAwaiter().GetResult(); } if (groups != null) { ProcessGroupChanges(employeeId, groups.Values.ToList()); } }