/// <summary> /// For all dnn role to b2c group mappings configured in DnnRoleMappings.config, and that exist in AzureB2C tenant, insure that roles exist on dnn. /// </summary> /// <param name="portalId">PortalID of the dnn portal where roles are created.</param> /// <param name="settings">Configuration settings for module</param> /// <returns>Logging message(s) of job execution.</returns> internal string SyncRoles(int portalId, AzureConfig settings) { try { if (CustomRoleMappings == null || CustomRoleMappings.RoleMapping == null || CustomRoleMappings.RoleMapping.Length == 0) { return("No role mappings configured. See DnnRoleMappings.config in module root folder."); } else { if (string.IsNullOrEmpty(settings.AADApplicationId) || string.IsNullOrEmpty(settings.AADApplicationKey)) { throw new Exception($"AAD application ID or key are not valid on portal {portalId}"); } var graphClient = new GraphClient(settings.AADApplicationId, settings.AADApplicationKey, settings.TenantId); // Add roles from AAD B2C var aadGroups = graphClient.GetAllGroups(""); if (aadGroups != null && aadGroups.Values != null) { foreach (var mapGroup in CustomRoleMappings.RoleMapping) { var dnnRole = Security.Roles.RoleController.Instance.GetRoleByName(portalId, mapGroup.DnnRoleName); var aadGroup = aadGroups.Values.FirstOrDefault(s => s.DisplayName == mapGroup.B2cRoleName); if (dnnRole == null && aadGroup != null) { // Create role var roleId = Security.Roles.RoleController.Instance.AddRole(new Security.Roles.RoleInfo { RoleName = mapGroup.B2cRoleName, Description = aadGroup.Description, PortalID = portalId, Status = Security.Roles.RoleStatus.Approved, RoleGroupID = -1, AutoAssignment = false, IsPublic = false }); } } } } return($"Successfully synchronized portal {portalId}"); } catch (Exception e) { return($"Error while synchronizing the roles from portal {portalId}: {e}"); } }
public HttpResponseMessage GetAllGroups() { try { var settings = new AzureConfig(AzureConfig.ServiceName, PortalSettings.PortalId); var graphClient = new GraphClient(settings.AADApplicationId, settings.AADApplicationKey, settings.TenantId); var query = ""; var users = graphClient.GetAllGroups(query); return(Request.CreateResponse(HttpStatusCode.OK, users.Values)); } catch (Exception ex) { return(Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message)); } }
private static void UpdateGroupMemberShip(GraphClient graphClient, User user, List <Group> userGroups) { var groups = graphClient.GetAllGroups(""); foreach (var group in groups.Values) { var groupMembers = graphClient.GetGroupMembers(group.ObjectId); if (groupMembers.Values.Any(u => u.ObjectId == user.ObjectId) && !userGroups.Any(x => x.ObjectId == group.ObjectId)) { graphClient.RemoveGroupMember(group.ObjectId, user.ObjectId); } if (!groupMembers.Values.Any(u => u.ObjectId == user.ObjectId) && userGroups.Any(x => x.ObjectId == group.ObjectId)) { graphClient.AddGroupMember(group.ObjectId, user.ObjectId); } } }
internal string SyncRoles(int portalId, AzureConfig settings) { try { var customRoleMappings = GetRoleMappingsForPortal(portalId, settings); if (string.IsNullOrEmpty(settings.AADApplicationId) || string.IsNullOrEmpty(settings.AADApplicationKey)) { throw new Exception($"AAD application ID or key are not valid on portal {portalId}"); } var graphClient = new GraphClient(settings.AADApplicationId, settings.AADApplicationKey, settings.TenantId); // Add roles from AAD B2C var aadGroups = graphClient.GetAllGroups(""); if (aadGroups != null && aadGroups.Values != null) { var groupPrefix = settings.GroupNamePrefixEnabled ? "AzureB2C-" : ""; var groups = aadGroups.Values; if (customRoleMappings != null && customRoleMappings.Count > 0) { groupPrefix = ""; var b2cRoles = customRoleMappings.Select(rm => rm.B2cRoleName); groups.RemoveAll(x => !b2cRoles.Contains(x.DisplayName)); } foreach (var aadGroup in groups) { var dnnRole = RoleController.Instance.GetRoleByName(portalId, $"{groupPrefix}{aadGroup.DisplayName}"); if (dnnRole == null) { // Create role var roleId = AddRole(portalId, $"{groupPrefix}{aadGroup.DisplayName}", aadGroup.Description, true); } } } // Let's remove DNN roles imported from B2C that no longer exists in B2C var dnnB2cRoles = GetDnnB2cRoles(portalId); // Let's exclude first the mapped roles (we won't remove mapped roles) foreach (var role in customRoleMappings) { var mappedRole = dnnB2cRoles.FirstOrDefault(ri => ri.RoleName == role.DnnRoleName); if (mappedRole != null) { dnnB2cRoles.Remove(mappedRole); } } // Remove roles no longer exists in AAD B2C (only the ones that are not mapped against a DNN role) foreach (var dnnRole in dnnB2cRoles) { if (aadGroups == null || aadGroups.Values == null || aadGroups.Values.FirstOrDefault(x => x.DisplayName == (dnnRole.RoleName.StartsWith("AzureB2C-") ? dnnRole.RoleName.Substring("AzureB2C-".Length) : dnnRole.RoleName)) == null) { RoleController.Instance.DeleteRole(dnnRole); // This is a workaround to a bug in DNN where RoleSettings is not deleted when a role is deleted DotNetNuke.Data.DataContext.Instance().Execute(System.Data.CommandType.Text, $"DELETE {DotNetNuke.Data.DataProvider.Instance().DatabaseOwner}{DotNetNuke.Data.DataProvider.Instance().ObjectQualifier}RoleSettings WHERE RoleID = @0", dnnRole.RoleID); } } return($"Successfully synchronized portal {portalId}"); } catch (Exception e) { return($"Error while synchronizing the roles from portal {portalId}: {e}"); } }
internal string SyncRoles(int portalId, AzureConfig settings) { try { var syncErrorsDesc = ""; var syncErrors = 0; var groupsCreated = 0; var groupsDeleted = 0; var customRoleMappings = GetRoleMappingsForPortal(portalId, settings); if (string.IsNullOrEmpty(settings.AADApplicationId) || string.IsNullOrEmpty(settings.AADApplicationKey)) { throw new Exception($"AAD application ID or key are not valid on portal {portalId}"); } var graphClient = new GraphClient(settings.AADApplicationId, settings.AADApplicationKey, settings.TenantId); var query = "$orderby=displayName"; var filter = ConfigurationManager.AppSettings["AzureAD.GetAllGroups.Filter"]; if (!string.IsNullOrEmpty(filter)) { query = $"$filter={filter}"; } // Add roles from AAD var aadGroups = graphClient.GetAllGroups(query); var allaadGroups = new List <Components.Graph.Models.Group>(); if (aadGroups != null && aadGroups.Values != null) { var groupPrefix = settings.GroupNamePrefixEnabled ? "Azure-" : ""; while (aadGroups.Values.Count > 0) { var groups = aadGroups.Values; allaadGroups.AddRange(groups); if (customRoleMappings != null && customRoleMappings.Count > 0) { groupPrefix = ""; var b2cRoles = customRoleMappings.Select(rm => rm.AadRoleName); groups.RemoveAll(x => !b2cRoles.Contains(x.DisplayName)); } foreach (var aadGroup in groups) { var dnnRole = RoleController.Instance.GetRoleByName(portalId, $"{groupPrefix}{aadGroup.DisplayName}"); if (dnnRole == null) { try { // Create role var roleId = AddRole(portalId, $"{groupPrefix}{aadGroup.DisplayName}", aadGroup.Description, true); groupsCreated++; } catch (Exception ex) { syncErrors++; syncErrorsDesc += $"\n{ex.Message}"; } } } if (string.IsNullOrEmpty(aadGroups.ODataNextLink)) { break; } aadGroups = graphClient.GetNextGroups(aadGroups.ODataNextLink); } } // Let's remove DNN roles imported from B2C that no longer exists in AAD var dnnAadRoles = GetDnnAadRoles(portalId); // Let's exclude first the mapped roles (we won't remove mapped roles) foreach (var role in customRoleMappings) { var mappedRole = dnnAadRoles.FirstOrDefault(ri => ri.RoleName == role.DnnRoleName); if (mappedRole != null) { dnnAadRoles.Remove(mappedRole); } } // Remove roles no longer exists in AAD (only the ones that are not mapped against a DNN role) foreach (var dnnRole in dnnAadRoles) { if (allaadGroups.Count == 0 || allaadGroups.FirstOrDefault(x => x.DisplayName == (dnnRole.RoleName.StartsWith("Azure-") ? dnnRole.RoleName.Substring("Azure-".Length) : dnnRole.RoleName)) == null) { try { RoleController.Instance.DeleteRole(dnnRole); // This is a workaround to a bug in DNN where RoleSettings is not deleted when a role is deleted DotNetNuke.Data.DataContext.Instance().Execute(System.Data.CommandType.Text, $"DELETE {DotNetNuke.Data.DataProvider.Instance().DatabaseOwner}{DotNetNuke.Data.DataProvider.Instance().ObjectQualifier}RoleSettings WHERE RoleID = @0", dnnRole.RoleID); groupsDeleted++; } catch (Exception ex) { syncErrors++; syncErrorsDesc += $"\n{ex.Message}"; } } } var syncResultDesc = ""; if (!string.IsNullOrEmpty(syncErrorsDesc)) { Logger.Error($"AAD Role Sync errors detected: {syncErrorsDesc}"); syncResultDesc = $"Portal {portalId} synced with errors, check logs for more information (sync errors: {syncErrors}; groups created: {groupsCreated}; groups deleted: {groupsDeleted}"; } else { syncResultDesc = $"Successfully synchronized portal {portalId} (sync errors: 0; groups created: {groupsCreated}; groups deleted: {groupsDeleted}"; } return(syncResultDesc); } catch (Exception e) { Logger.Error($"Error while synchronizing the roles from portal {portalId}: {e}"); return($"Error while synchronizing the roles from portal {portalId}: {e}"); } }