using AutoMapper; using AutoMapper.QueryableExtensions; using LANCommander.Server.Data; using LANCommander.Server.Data.Enums; using LANCommander.Server.Data.Models; using LANCommander.Server.Services.Factories; using LANCommander.Server.Services.Models; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using System; using System.Data; using System.Linq; using System.Linq.Expressions; using LANCommander.Server.Services.Exceptions; namespace LANCommander.Server.Services { public class UserService : BaseService, IBaseDatabaseService { private readonly IdentityContext IdentityContext; private readonly CollectionService CollectionService; private readonly IMapper Mapper; public RepositoryFactory repositoryFactory { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public UserService( ILogger logger, IMapper mapper, RepositoryFactory repositoryFactory, RoleService roleService, CollectionService collectionService, IdentityContextFactory identityContextFactory) : base(logger) { IdentityContext = identityContextFactory.Create(); CollectionService = collectionService; Mapper = mapper; } public async Task GetAsync(string userName) { try { return await IdentityContext.UserManager.FindByNameAsync(userName); } finally { } } public async Task GetAsync(string userName) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); return Mapper.Map(user); } finally { } } public async Task> GetRolesAsync(string userName) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); var roleNames = await IdentityContext.UserManager.GetRolesAsync(user); return await IdentityContext.RoleManager.Roles.Where(r => roleNames.Contains(r.Name)).ToListAsync(); } finally { } } public async Task IsInRoleAsync(string userName, string roleName) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); return await IdentityContext.UserManager.IsInRoleAsync(user, roleName); } finally { } } public async Task> GetCollectionsAsync(Guid userId) { try { var user = await GetAsync(userId); var roles = await GetRolesAsync(user.UserName); var roleIds = roles.Select(r => r.Id).ToList(); if (roles.Any(r => r.Name == RoleService.AdministratorRoleName)) return await CollectionService.GetAsync(); else return await CollectionService .Include(c => c.Roles) .GetAsync(c => c.Roles.Any(r => roleIds.Contains(r.Id))); } catch (Exception ex) { Logger.LogError(ex, "Could not get user collections"); return new List(); } } public async Task AddAsync(User user) { try { var result = await IdentityContext.UserManager.CreateAsync(user); if (result.Succeeded) return await IdentityContext.UserManager.FindByNameAsync(user.UserName); else throw new UserRegistrationException(result, "Could not create user"); } finally { } } public async Task AddToRoleAsync(string userName, string roleName) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); await IdentityContext.UserManager.AddToRoleAsync(user, roleName); } finally { } } public async Task AddToRolesAsync(string userName, IEnumerable roleNames) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); var result = await IdentityContext.UserManager.AddToRolesAsync(user, roleNames); if (!result.Succeeded) throw new AddRoleException(result, "Could not add roles"); } finally { } } public async Task RemoveFromRole(string userName, string roleName) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); await IdentityContext.UserManager.RemoveFromRoleAsync(user, roleName); } finally { } } public async Task CheckPassword(string userName, string password) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); return await IdentityContext.UserManager.CheckPasswordAsync(user, password); } finally { } } public async Task ChangePassword(string userName, string currentPassword, string newPassword) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); var result = await IdentityContext.UserManager.ChangePasswordAsync(user, currentPassword, newPassword); return result; } finally { } } public async Task ChangePassword(string userName, string newPassword) { try { var user = await IdentityContext.UserManager.FindByNameAsync(userName); var token = await IdentityContext.UserManager.GeneratePasswordResetTokenAsync(user); return await IdentityContext.UserManager.ResetPasswordAsync(user, token, newPassword); } catch (Exception ex) { throw; } finally { } } public async Task SignOut() { } public async Task> GetAsync() { try { return await IdentityContext.UserManager.Users.ToListAsync(); } finally { } } public async Task> GetAsync() { try { return await IdentityContext.UserManager.Users.ProjectTo(Mapper.ConfigurationProvider).ToListAsync(); } finally { } } public async Task GetAsync(Guid id) { try { return await IdentityContext.UserManager.FindByIdAsync(id.ToString()); } finally { } } public async Task GetAsync(Guid id) { try { var user = await IdentityContext.UserManager.FindByIdAsync(id.ToString()); return Mapper.Map(user); } finally { } } public async Task> GetAsync(Expression> predicate) { try { return await IdentityContext.UserManager.Users.Where(predicate).ToListAsync(); } finally { } } public async Task> GetAsync(Expression> predicate) { try { return await IdentityContext.UserManager.Users.Where(predicate).ProjectTo(Mapper.ConfigurationProvider).ToListAsync(); } finally { } } public async Task FirstOrDefaultAsync(Expression> predicate) { try { return await IdentityContext.UserManager.Users.FirstOrDefaultAsync(predicate); } finally { } } public async Task FirstOrDefaultAsync(Expression> predicate) { try { return await IdentityContext.UserManager.Users.Where(predicate).ProjectTo(Mapper.ConfigurationProvider).FirstOrDefaultAsync(); } finally { } } public async Task FirstOrDefaultAsync(Expression> predicate, Expression> orderKeySelector) { try { return await IdentityContext.UserManager.Users.Where(predicate).OrderBy(orderKeySelector).FirstOrDefaultAsync(); } finally { } } public async Task FirstOrDefaultAsync(Expression> predicate, Expression> orderKeySelector) { try { return await IdentityContext.UserManager.Users.Where(predicate).ProjectTo(Mapper.ConfigurationProvider).OrderBy(orderKeySelector).FirstOrDefaultAsync(); } finally { } } public async Task ExistsAsync(Guid id) { try { var user = await IdentityContext.UserManager.FindByIdAsync(id.ToString()); return user != null; } finally { } } public async Task> AddMissingAsync(Expression> predicate, User entity) { try { var result = new ExistingEntityResult(); var user = await IdentityContext.UserManager.Users.FirstOrDefaultAsync(predicate); if (user == null) { await IdentityContext.UserManager.CreateAsync(entity); result.Existing = false; result.Value = await IdentityContext.UserManager.FindByNameAsync(user.UserName); } else { result.Existing = true; result.Value = user; } return result; } finally { } } public async Task UpdateAsync(User entity) { try { var user = await IdentityContext.UserManager.FindByIdAsync(entity.Id.ToString()); user.UserName = entity.UserName; user.PhoneNumber = entity.PhoneNumber; user.Email = entity.Email; user.TwoFactorEnabled = entity.TwoFactorEnabled; user.Alias = entity.Alias; user.Approved = entity.Approved; user.ApprovedOn = entity.ApprovedOn; await IdentityContext.UserManager.UpdateAsync(user); return user; } finally { } } public async Task DeleteAsync(User entity) { try { var user = await IdentityContext.UserManager.FindByIdAsync(entity.Id.ToString()); await IdentityContext.UserManager.DeleteAsync(user); } finally { } } public IBaseDatabaseService Include(Expression> includeExpression) { throw new NotImplementedException(); } public IBaseDatabaseService Query(Func, IQueryable> modifier) { throw new NotImplementedException(); } public IBaseDatabaseService Include(params Expression>[] expressions) { throw new NotImplementedException(); } public IBaseDatabaseService SortBy(Expression> expression, SortDirection direction) { throw new NotImplementedException(); } public IBaseDatabaseService DisableTracking() { throw new NotImplementedException(); } public Task> PaginateAsync(Expression> expression, int pageNumber, int pageSize) { throw new NotImplementedException(); } public void Dispose() { } } }