using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using AyCode.Models.Enums; using Microsoft.EntityFrameworkCore; using TIAM.Database.DbContexts; using TIAM.Entities.Permissions; using TIAM.Entities.Products; using TIAM.Entities.ServiceProviders; using TIAM.Entities.Products.DTOs; using TIAM.Entities.Users; namespace TIAM.Database.DataLayers.ServiceProviders { public class ServiceProviderDal : TiamDalBase { public ServiceProviderDal() : base() { } public ServiceProviderDal(ServiceProviderDbContext _object) { } #region ServiceProviders //16. (IServiceProviderDataService) get all service providers public Task> GetServiceProvidersAsync() { return Ctx.ServiceProviders.ToListAsync(); } //18. (IServiceProviderDataService) get serviceProvider by Id public virtual Task GetServiceProviderByIdAsync(Guid id) { Console.WriteLine($"Getting serviceProvider from db {id}"); return Ctx.ServiceProviders.SingleOrDefaultAsync(x=>x.Id == id); } //15. (IServiceProviderDataService) Create service provider public Task CreateServiceProviderAsync(TiamServiceProvider serviceProvider) { if(serviceProvider.Name == Ctx.ServiceProviders.FirstOrDefault(x=>x.Name == serviceProvider.Name)?.Name) { throw new Exception("ServiceProvider already exists"); } else { Ctx.ServiceProviders.Add(serviceProvider); Console.WriteLine($"Saving serviceProvider to db {serviceProvider.Id}, {serviceProvider.Name}, {serviceProvider.OwnerId}"); return Ctx.SaveChangesAsync().ContinueWith(x=>x.Result > 0); } } //14. (IserviceProviderDataService) Update service provider public Task UpdateServiceProviderAsync(TiamServiceProvider serviceProvider) { var dbServiceProvider = Ctx.ServiceProviders.FirstOrDefault(u => u.Id == serviceProvider.Id); if (dbServiceProvider != null) { dbServiceProvider = serviceProvider; Ctx.ServiceProviders.Update(dbServiceProvider); return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } else { throw new Exception("ServiceProvider not found"); } } //13. (IserviceProviderDataService) delete service provider public Task DeleteServiceProviderAsync(Guid id) { using (var transaction = Ctx.Database.BeginTransaction()) { var dbServiceProvider = Ctx.ServiceProviders.FirstOrDefault(u => u.Id == id); if (dbServiceProvider != null) { //get products for this provider var products = Ctx.Products.Where(x => x.OwnerId == id).ToList(); /*foreach (var productItem in products) { //delete products var permissionContextMappings = Ctx.PermissionContextMappings.Where(x => x.ContextId == productItem.Id).ToList(); //iterate through every row foreach (var item in permissionContextMappings) { if (item.SubjectType == (int)PermissionContextMappingSubjectType.Group) { //get users in the permissiongroup var permissionGroupUserMapping = Ctx.PermissionGroupUserMappings.Where(x => x.PermissionContextMappingId == item.Id).ToList(); //remove every row (users) from permissiongroup foreach (var user in permissionGroupUserMapping) { Ctx.PermissionGroupUserMappings.Remove(user); } } } //remove permissioncontextmappings Ctx.PermissionContextMappings.RemoveRange(permissionContextMappings); }*/ Ctx.Products.RemoveRange(products); Ctx.ServiceProviders.Remove(dbServiceProvider); return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } else { return Task.FromResult(false); } } } //17. (IServiceProviderDataService) get service provider by ownerId public Task> GetServiceProvidersByOwnerIdAsync() { throw new NotImplementedException(); } #endregion #region PermissionTypes //10. (IPermissionService) create permission type public Task CreatePermissionsTypeAsync(PermissionsType permissionsType) { bool result = false; using (var transaction = Ctx.Database.BeginTransaction()) { var existingPermission = Ctx.PermissionsTypes .FirstOrDefault(x => x.PermissionName == permissionsType.PermissionName)?.PermissionName; if (existingPermission == null) { //get all the permissiontypes for this context var permissionTypes = new List(); var nextBitValue = 0.0; permissionTypes = Ctx.PermissionsTypes .Where(x => x.ContextId == permissionsType.ContextId) .ToList(); //get the max value of the permissiontypes if (permissionTypes != null) { //next bit value is the power of two of the count of the permissiontypes nextBitValue = Math.Pow(2, permissionTypes.Count); } else { nextBitValue = Math.Pow(2,0); } permissionsType.PermissionBit = (int)nextBitValue; Ctx.PermissionsTypes.Add(permissionsType); Ctx.SaveChanges(); transaction.Commit(); result = true; } else { result = false; } } return Task.FromResult(result); } //11. (IPermissionService) get permission types for context public Task>? GetPermissionTypesByContextIdAsync(Guid contextId) { return Ctx.PermissionsTypes.Where(x => x.ContextId == contextId).ToListAsync(); } public Task GetPermissionFromPermissionType(PermissionsType pType) { if(Ctx.PermissionsTypes.FirstOrDefault(x=>x.Id == pType.Id) != null) { return Task.FromResult(pType.PermissionBit); } else { return Task.FromResult(0); } } #endregion #region PermissionMappings //2. get the contexts where the user has permission public async Task> GetPermissionContextByUserIdAsync(Guid UserId) { List _permissions = new List(); //get all assignedUsers List assignedUsers = await Ctx.AssignedUsers.Where(x => x.EmployeeUserId == UserId).ToListAsync(); //List _permissionContextMappings = new List(); List _permissionGroupUserMappings = new List(); //get contexts where the user has permission foreach (var item in assignedUsers) { //get the product where the permissioncontextmapping is var contextMapping = await Ctx.PermissionContextMappings.FirstOrDefaultAsync(x => x.SubjectId == item.Id); if (contextMapping != null) { _permissions.Add(new AssignedPermissionModel(item.ContextId, item.Id, (short)PermissionContextMappingSubjectType.User, item.Id.ToString(), contextMapping.Permissions)); } //get permissiongroupusermappings where the user is in the group _permissionGroupUserMappings = await Ctx.PermissionGroupUserMappings.Where(x => x.AssignedUserId == item.Id).ToListAsync(); foreach (var groupUserMapping in _permissionGroupUserMappings) { //get the permissioncontextmapping where the permissiongroup is var contextMapping2 = await Ctx.PermissionContextMappings.FirstOrDefaultAsync(x => x.Id == groupUserMapping.PermissionContextMappingId); if (contextMapping2 != null) { //get the group so we have the contextId var group = await Ctx.PermissionGroups.FirstOrDefaultAsync(x => x.Id == contextMapping2.SubjectId); _permissions.Add(new AssignedPermissionModel(group.ContextId, contextMapping2.SubjectId, (short)PermissionContextMappingSubjectType.Group, group.GroupName, contextMapping2.Permissions)); } } } return _permissions; } //3. (IPermissionService) get permissions of assigned users and groups public Task> GetPermissionsOfAssignedUsersAndGroupsAsyncByContextId(Guid contextId) { List result = new List(); var AssignedUsers = Ctx.AssignedUsers.Where(x => x.ContextId == contextId).ToListAsync(); if (AssignedUsers.Result != null) { foreach (var item in AssignedUsers.Result) { var mappingRow = Ctx.PermissionContextMappings.Where(x => x.SubjectId == item.Id).ToListAsync(); if (mappingRow.Result == null) { //user has no permission but is assigned... must be banned } else if (mappingRow.Result.Count > 1) { //user has been assigned more than onece to same context } else { foreach (var mapping in mappingRow.Result) { result.Add(new AssignedPermissionModel(item.ContextId, item.Id, mapping.SubjectType, item.EmployeeUserId.ToString(), mapping.Permissions)); } } } } var AssingedGroups = Ctx.PermissionGroups.Where(x => x.ContextId == contextId).ToListAsync(); if (AssingedGroups.Result != null) { foreach (var group in AssingedGroups.Result) { var mappingRow = Ctx.PermissionContextMappings.Where(x => x.SubjectId == group.Id).ToListAsync(); if (mappingRow.Result == null) { //group has no permission but is assigned... } else if (mappingRow.Result.Count > 1) { //group has been assigned more than onece to same context } else { foreach (var mapping in mappingRow.Result) { result.Add(new AssignedPermissionModel(group.ContextId, group.Id, mapping.SubjectType, group.GroupName, mapping.Permissions)); } } } } foreach (var row in result) { Console.WriteLine($"GetPermissionsOfAssignedUsersAndGroupsAsyncByContextId: {row.ContextId}, {row.SubjectId}, {row.SubjectType}, {row.Name}, {row.PermissionsValue}"); } return Task.FromResult(result); } //12. (IPermissionService) get permission groups for context public Task> GetPermissionsForContextByContextIdAsync(Guid contextId) { List permissionContextMappings = new List(); //get all Groups where the contextId is the same var groups = Ctx.PermissionGroups.Where(x => x.ContextId == contextId).ToListAsync(); foreach (var item in groups.Result) { //get permissioncontextmapping for the group if there is, so we know what permissions the group has var pCm = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == item.Id); permissionContextMappings.Add(pCm); } return Task.FromResult(permissionContextMappings); } //9. (IPermissionService) add user to permission group public Task AddUserToPermissionGroupAsync(Guid permissionGroupId, Guid userId) { bool result = false; using (var transaction = Ctx.Database.BeginTransaction()) { //do we need to check if PermissionContextMappingId exists? var permissionGroupUserMapping = new PermissionGroupUserMapping(userId, permissionGroupId); Ctx.PermissionGroupUserMappings.Add(permissionGroupUserMapping); Ctx.SaveChanges(); transaction.Commit(); result = true; } return Task.FromResult(result); } //8. (IPermissionService) create permission group public Task CreatePermissionGroupAsync(PermissionGroup permissionGroup, TiamServiceProvider serviceProvider) { bool result = false; using (var transaction = Ctx.Database.BeginTransaction()) { var existingPermissionGroup = Ctx.PermissionGroups.FirstOrDefault(x => x.GroupName == permissionGroup.GroupName)?.GroupName; if (existingPermissionGroup == null) { //create permission type 1 for the group var permissionType = new PermissionsType(serviceProvider.Id, "View"); Ctx.PermissionsTypes.Add(permissionType); //Create PermissionContextMapping for the group //create Id for the group Guid Id = Guid.NewGuid(); permissionGroup.Id = Id; var permissionContextMapping = new PermissionContextMapping(serviceProvider.Id, Id, (short)PermissionContextMappingSubjectType.Group, 1, true); Ctx.PermissionContextMappings.Add(permissionContextMapping); Ctx.PermissionGroups.Add(permissionGroup); Ctx.SaveChanges(); transaction.Commit(); result = true; } else { //group with same name already exists result = false; } } return Task.FromResult(result); } public Task> GetAssingedUsersInPermissionGroupByGroupId(Guid groupId) { List assignedUsers = new List(); //let's get the permissioncontextmapping for the group var pCm = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == groupId); Guid pCmId = pCm.Id; //let's get the permissiongroupusermappings for the permissioncontextmapping var pGum = Ctx.PermissionGroupUserMappings.Where(x => x.PermissionContextMappingId == pCmId).ToList(); if (pGum.Count > 0) { foreach (var group in pGum) { assignedUsers.Add(Ctx.AssignedUsers.FirstOrDefault(x => x.Id == group.AssignedUserId)); } } return Task.FromResult(assignedUsers); } #endregion #region Products //19. (IServiceProviderDataService) Create product public Task CreateProductAsync(TiamProduct product) { Ctx.Products.Add(product); Console.WriteLine($"Saving product to db {product.Id}, {product.Name}, {product.OwnerId}"); return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } //20. (IServiceProviderDataService) Update product public Task UpdateProductAsync(TiamProduct product) { var dbProduct = Ctx.Products.FirstOrDefault(u => u.Id == product.Id); if (dbProduct != null) { dbProduct = product; Ctx.Products.Update(dbProduct); return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } else { throw new Exception("Product not found"); } } //21. (IServiceProviderDataService) delete product public Task DeleteProductAsync(Guid id) { using (var transaction = Ctx.Database.BeginTransaction()) { var dbProduct = Ctx.Products.FirstOrDefault(u => u.Id == id); if (dbProduct != null) { //get assignedUsers for this product var assignedUsers = Ctx.AssignedUsers.Where(x => x.ContextId == id).ToList(); //remove assignedUsers foreach (var item in assignedUsers) { RemoveAssignedUserByUserId(item.Id); } return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } else { return Task.FromResult(false); } } } //4. (IPermissionService) AssignPermissionToUserForContextAsync public Task AssignPermissionToUserForContextAsync(AssignedUser assignedUser, PermissionsType permission) { var _assIgnedUser = Ctx.AssignedUsers.FirstOrDefault(x => x.Id == assignedUser.Id); if(_assIgnedUser != null) { //user exists var _permissionInt = GetPermissionFromPermissionType(permission); var permissionContextMapping = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == assignedUser.Id); var currentPermissions = permissionContextMapping.Permissions; var newPermissions = currentPermissions + _permissionInt.Result; permissionContextMapping.Permissions = newPermissions; return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } else { //user does not exist, let's create it return Task.FromResult(false); } } #endregion #region AssignedUsers //22. (IServiceProviderDataService) Create assignedUser public Task CreateAssignedUserAsync(AssignedUser assignedUser) { Ctx.AssignedUsers.Add(assignedUser); Console.WriteLine($"Saving assignedUser to db {assignedUser.Id}, {assignedUser.ContextId}, {assignedUser.EmployeeUserId}, {assignedUser.UserRoles}"); return Ctx.SaveChangesAsync().ContinueWith(x => assignedUser); } //23. (IServiceProviderDataService) Get Assigned Users By ProductId public Task> GetAssignedUsersByProductIdAsync(Guid productId) { return Ctx.AssignedUsers.Where(x => x.ContextId == productId).ToListAsync(); } //24 . (IServiceProviderDataService) Remove Assigned Users By Product Id public Task RemoveAssignedUsersByContextId(Guid contextId) { using (var transaction = Ctx.Database.BeginTransaction()) { var assignedUsers = Ctx.AssignedUsers.Where(x => x.ContextId == contextId).ToList(); //remove assignedUsers return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } } //25. (IServiceProviderDataService) Remove Assigned from product by AssignedUserId public Task RemoveAssignedUser(AssignedUser assignedUser, bool removeFromGroups) { using (var transaction = Ctx.Database.BeginTransaction()) { var assignedUserToRemove = Ctx.AssignedUsers.FirstOrDefault(x => x.Id == assignedUser.Id); //remove assignedUsers if (assignedUserToRemove != null) { if(removeFromGroups) { //remove permissiongroupusermappings RemoveAssingedUserFromAllProductPermissionGroups(assignedUserToRemove.Id); } Ctx.AssignedUsers.Remove(assignedUserToRemove); } return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } } public Task RemoveAssignedUserByUserId(Guid assignedUserId) { using (var transaction = Ctx.Database.BeginTransaction()) { var assignedUser = Ctx.AssignedUsers.FirstOrDefault(x => x.Id == assignedUserId); //remove assignedUsers if (assignedUser != null) { //CleanUp //remove permissioncontextmappings RemoveAssignedUserContextMappingByAssignedUserId(assignedUserId); //remove permissiongroupusermappings RemoveAssingedUserFromAllProductPermissionGroups(assignedUserId); } return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } } public Task RemoveAssignedUserContextMappingByAssignedUserId(Guid AssignedUserId) { using (var transaction = Ctx.Database.BeginTransaction()) { PermissionContextMapping? contextMapping = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == AssignedUserId); //remove assignedUsers if(contextMapping != null) { Ctx.PermissionContextMappings.Remove(contextMapping); } return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } } public Task RemoveAssingedUserFromAllProductPermissionGroups(Guid assignedUserId) { using (var transaction = Ctx.Database.BeginTransaction()) { var permissionGroupUserMapping = Ctx.PermissionGroupUserMappings.Where(x => x.AssignedUserId == assignedUserId); //remove assignedUsers if (permissionGroupUserMapping != null) { foreach (var item in permissionGroupUserMapping) { Ctx.PermissionGroupUserMappings.Remove(item); } } return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0); } } #endregion } }