/// <summary> /// Check if a given user has a given permission /// </summary> /// <param name="userIdentifier">the user's identifier</param> /// <param name="permissionIdentifier">the permission's identifier</param> /// <returns></returns> public async Task <AccessControlResponse> IsUserHasPermission(string userIdentifier, string permissionIdentifier) { if (string.IsNullOrEmpty(userIdentifier)) { return(new AccessControlResponse(AccessControlResponseErrorInfo.BadArgument, nameof(userIdentifier), userIdentifier)); } if (string.IsNullOrEmpty(permissionIdentifier)) { return(new AccessControlResponse(AccessControlResponseErrorInfo.BadArgument, nameof(permissionIdentifier), permissionIdentifier)); } var ip = GetIdentityProvider(); var groupIdentifiers = (await ip.GetUserGroups(userIdentifier)).Select(x => x.GroupIdentifier); if (groupIdentifiers.Count() <= 0) { return(new AccessControlResponse(AccessControlResponseErrorInfo.NoError)); } using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { bool isPermissionExists = (from p in context.Permissions where permissionIdentifier == p.PermissionName select p.PermissionName).FirstOrDefault() != null; if (!isPermissionExists) { return(new AccessControlResponse(AccessControlResponseErrorInfo.PermissionNotFound, nameof(permissionIdentifier), permissionIdentifier)); } int countFoundPermissions = (from gp in context.GroupPermissions where groupIdentifiers.Contains(gp.GroupIdentification) && gp.Permission.PermissionName == permissionIdentifier && gp.IsGranted select gp).Count(); return((countFoundPermissions > 0) ? (new AccessControlResponse()) : (new AccessControlResponse(AccessControlResponseErrorInfo.NoError))); } }
/// <summary> /// Get all permissions linked to a given group /// This will not enumerate all permissions linked to any hierarchical group, only the ones directly associated with this group /// </summary> /// <param name="groupIdentifier">the group's identifier</param> /// <returns></returns> public async Task <PermissionInfo[]> GetGroupPermissions(string groupIdentifier) { List <PermissionInfo> ret = new List <PermissionInfo>(); using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { (await context.GroupPermissions.Where(g => g.GroupIdentification == groupIdentifier).ToListAsync()).ForEach(groupPermission => LinkPermissionInfos(context, groupPermission, ref ret)); return(ret.ToArray()); } }
/// <summary> /// Get all permissions linked to a given user /// </summary> /// <param name="userIdentifier">the user's identifier</param> /// <returns></returns> public async Task <PermissionInfo[]> GetUserPermissions(string userIdentifier) { var ip = GetIdentityProvider(); var groupIdentifiers = (await ip.GetUserGroups(userIdentifier)).Select(x => x.GroupIdentifier); List <PermissionInfo> ret = new List <PermissionInfo>(); if (groupIdentifiers.Count() <= 0) { return(ret.ToArray()); } using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { (await context.GroupPermissions.Where(g => groupIdentifiers.Contains(g.GroupIdentification)).Distinct().ToListAsync()).ForEach(groupPermission => LinkPermissionInfos(context, groupPermission, ref ret)); return(ret.ToArray()); } }
public async Task <string> GetMenuDefinitionForUser(string userName) { var menuProvider = GetMenuProvider(); var groups = await GetIdentityProvider().GetUserGroups(userName); var permissions = new List <Permission>(); using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { var permissionSet = context.GroupPermissions.Include(gp => gp.Permission).Where(gp => groups.Select(g => g.GroupIdentifier).Contains(gp.GroupIdentification)).Where(gp => gp.IsGranted).Select(gp => gp.Permission).Distinct(); permissions.AddRange(permissionSet); } var menuValue = await menuProvider.CreateMenuDefinitionForPermissionSet(permissions.Select(p => p.PermissionId).ToArray()); var menuValueSerialized = BreanosConnectors.SerializationHelper.Serialize(menuValue); return(menuValueSerialized); }
/// <summary> /// Register a new permission with an optional parent permission (which must already exist in the access control service's data) /// </summary> /// <param name="permissionIdentifier">the permission's identifier</param> /// <param name="parentPermission">optional - parent-permission's identifier</param> /// <returns></returns> public async Task <AccessControlResponse> RegisterPermission(string permissionIdentifier, string parentPermissionIdentifier) { using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { var isPermissionExists = Task.Run(() => context.Permissions.Where(x => x.PermissionName == permissionIdentifier).Count() > 0); if (await isPermissionExists) { return(new AccessControlResponse(AccessControlResponseErrorInfo.DuplicateEntity, nameof(permissionIdentifier), permissionIdentifier)); } if (string.IsNullOrEmpty(parentPermissionIdentifier)) { await context.Permissions.AddAsync(new Permission() { PermissionName = permissionIdentifier }); await context.SaveChangesAsync(); return(new AccessControlResponse()); } else { var parentPermissionEntity = context.Permissions.Where(x => x.PermissionName == parentPermissionIdentifier).FirstOrDefault(); if (parentPermissionEntity != default(Permission)) { Permission p = new Permission() { PermissionName = permissionIdentifier, ParentPermission = parentPermissionEntity }; await context.Permissions.AddAsync(p); await context.SaveChangesAsync(); return(new AccessControlResponse()); } else { return(new AccessControlResponse(AccessControlResponseErrorInfo.EntityNotFound, nameof(parentPermissionIdentifier), parentPermissionIdentifier)); } } } }
/// <summary> /// Deregister a permission. The permission will be deleted and its childpermissions will be turned into base permissions without parent permission. /// All group-permission associations for the permission will be deleted as well if the permission would be created again afterwards (with the same identifier), /// the groups' associations to that permission would have to be recreated as well /// </summary> /// <param name="permissionIdentifier">the permission's identifier</param> /// <param name="parentPermission">optional - parent-permission's identifier</param> /// <returns></returns> public async Task <AccessControlResponse> DeregisterPermission(string permissionIdentifier) { using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { var permissionToBeDeleted = await context.Permissions.Where(x => x.PermissionName == permissionIdentifier).FirstOrDefaultAsync(); var isPermissionExists = permissionToBeDeleted != null; if (isPermissionExists) { var groupPermissionsToBeDeleted = context.GroupPermissions.Where(gp => gp.PermissionId == permissionToBeDeleted.PermissionId); if (groupPermissionsToBeDeleted.Any()) { foreach (var groupPermission in groupPermissionsToBeDeleted) { context.GroupPermissions.Remove(groupPermission); } await context.SaveChangesAsync(); } var danglingPermissions = context.Permissions.Where(x => x.ParentPermissionId == permissionToBeDeleted.PermissionId); if (danglingPermissions.Any()) { foreach (var danglingPermission in danglingPermissions) { danglingPermission.ParentPermissionId = null; } } await context.SaveChangesAsync(); var permissionToRemove = context.Permissions.Remove(permissionToBeDeleted); await context.SaveChangesAsync(); return(new AccessControlResponse()); } else { return(new AccessControlResponse(AccessControlResponseErrorInfo.EntityNotFound, nameof(permissionIdentifier), permissionIdentifier)); } } }
public async Task <AccessControlResponse> RegisterKpu(KpuRegistrationRequest krr) { logger.Trace($"KPU: {krr.KpuId}"); var kpuName = krr.KpuId; var menuDefinitionText = krr.MenuXmlString; //test menuDefinition for correctness MenuDefinition mdef = null; if (!string.IsNullOrEmpty(menuDefinitionText)) { if (!BreanosConnectors.SerializationHelper.TryDeserialize <MenuProvider.Interfaces.MenuDefinition>(krr.MenuXmlString, out mdef)) { logger.Error($"Could not properly deserialize the sent menu definition for RegistrationRequest for {krr.KpuId}"); return(new AccessControlResponse(AccessControlResponseErrorInfo.BadArgument, nameof(krr.MenuXmlString), krr.MenuXmlString)); } } //add permissions to db with fk to kpu logger.Trace($"Adding permissions from RegistrationRequest for {krr.KpuId}"); foreach (var permissionRequest in krr.PermissionRequests) { await ProcessKpuPermissionRequest(krr.KpuId, permissionRequest, null); } //gather required permissions var requiredPermissionsByName = new List <string>(); foreach (var mg in mdef.MenuGroups) { foreach (var mi in mg.MenuItems) { if (!requiredPermissionsByName.Contains(mi.PermissionIdentifier)) { requiredPermissionsByName.Add(mi.PermissionIdentifier); } } } logger.Trace($"Found {requiredPermissionsByName.Count} required permissions in menu definition"); using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { if (!requiredPermissionsByName.All(context.Permissions.Select(p => p.PermissionName).Contains)) // if any menu-required permission is not present in the DB by now { var notFoundPermissions = requiredPermissionsByName.Where(rp => !context.Permissions.Select(p => p.PermissionName).Contains(rp)); logger.Error($"Some required permissions were not present in the database: {string.Join(", ", notFoundPermissions)}"); return(new AccessControlResponse(AccessControlResponseErrorInfo.EntityNotFound, "Required Permission", string.Join(", ", notFoundPermissions.ToArray()))); } var actualRequiredPermissionIds = context.Permissions.Where(p => requiredPermissionsByName.Contains(p.PermissionName)).Select(p => p.PermissionId); KpuMetadata menuMetadata = new KpuMetadata() { Data = krr.MenuXmlString, MetadataType = KpuMetaDataType_MenuDefinition, Name = krr.KpuId + "_Menu", }; await context.AddAsync <KpuMetadata>(menuMetadata); logger.Trace($"Created KpuMetadata with Id {menuMetadata.Id}"); await context.SaveChangesAsync(); foreach (var pId in actualRequiredPermissionIds) { await context.AddAsync(new KpuMetadataPermission() { KpuMetadataId = menuMetadata.Id, PermissionId = pId }); } await context.SaveChangesAsync(); logger.Trace("Linked permissions to new metadata"); //add menu to db with fk to kpu? } return(new AccessControlResponse()); }
/// <summary> /// Modifiy the set of permissions linked to a given group by adding / removing a permission, issued e.g. by a certain user /// </summary> /// <param name="permissionIdentifier">the permission's identifier</param> /// <param name="groupIdentifier">the group's identifier</param> /// <param name="isPermitted">true if a group permission should be created, false if one should be deleted</param> /// <param name="issuer">the change-issuing entity, i.e. user</param> /// <returns></returns> public async Task <AccessControlResponse> SetPermission(string permissionIdentifier, string groupIdentifier, bool isPermitted, string issuer) { using (var context = new AccessControlServiceContextFactory(AppSettings).CreateDbContext(null)) { var p = context.Permissions.Where(x => x.PermissionName == permissionIdentifier).FirstOrDefault(); if (p == null) { return(new AccessControlResponse(AccessControlResponseErrorInfo.EntityNotFound, nameof(permissionIdentifier), permissionIdentifier)); } var existingGroupPermission = context.GroupPermissions.Where(x => x.GroupIdentification == groupIdentifier && x.Permission.PermissionName == permissionIdentifier).FirstOrDefault(); if (existingGroupPermission == null) { var newGP = new GroupPermission() { PermissionId = p.PermissionId, GroupIdentification = groupIdentifier, GrantedAt = DateTime.UtcNow, Grantee = issuer, IsGranted = isPermitted }; await context.GroupPermissions.AddAsync(newGP); if (p.ParentPermissionId != null) { Permission pp = p; while ((pp.ParentPermissionId) != null) { pp = GetParentPermission(context, pp); GroupPermission innerGroupPermission = (from gp in context.GroupPermissions where pp.PermissionId == gp.PermissionId && groupIdentifier == gp.GroupIdentification select gp).SingleOrDefault(); bool isNewEntity = (innerGroupPermission == null); if (!isNewEntity && innerGroupPermission.IsGranted == isPermitted) { continue; //if the gp stays the same essentially, do not touch it } else if (isNewEntity) { innerGroupPermission = new GroupPermission() { PermissionId = pp.PermissionId, GroupIdentification = groupIdentifier } } ; innerGroupPermission.GrantedAt = DateTime.UtcNow; innerGroupPermission.Grantee = issuer; innerGroupPermission.IsGranted = isPermitted; if (isNewEntity) { await context.GroupPermissions.AddAsync(innerGroupPermission); } } } } else { existingGroupPermission.IsGranted = isPermitted; existingGroupPermission.Grantee = issuer; existingGroupPermission.GrantedAt = DateTime.UtcNow; IEnumerable <Permission> childPermissions = new List <Permission>() { p }; if (!isPermitted) { while ((childPermissions = GetChildPermissionsRange(context, childPermissions.Select(cpms => cpms.PermissionId))) != null) { var correspondingGroupPermissions = GetGroupPermissionByGroupAndPIds(context, groupIdentifier, childPermissions.Select(cp => cp.PermissionId)); if (correspondingGroupPermissions.Count() <= 0) { break; } foreach (var cgp in correspondingGroupPermissions) { bool isChildGrantedChange = (cgp.IsGranted != isPermitted); cgp.IsGranted = isPermitted; if (isChildGrantedChange) { cgp.GrantedAt = DateTime.UtcNow; cgp.Grantee = issuer; } } } } else { Permission parentPermission = p; while ((parentPermission = GetParentPermission(context, parentPermission)) != null) { var correspondingGroupPermission = GetGroupPermissionByGroupAndPId(context, groupIdentifier, parentPermission.PermissionId); if (correspondingGroupPermission != null) { bool isParentGrantedChange = (correspondingGroupPermission.IsGranted != isPermitted); correspondingGroupPermission.IsGranted = isPermitted; if (isParentGrantedChange) { correspondingGroupPermission.GrantedAt = DateTime.UtcNow; correspondingGroupPermission.Grantee = issuer; } } } } } await context.SaveChangesAsync(); return(new AccessControlResponse()); } }