using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using AyCode.Database.DbContexts; using AyCode.Database.DbContexts.Users; using AyCode.Entities.Users; using AyCode.Interfaces.Users; using Microsoft.EntityFrameworkCore; using AyCode.Database.Extensions; using AyCode.Core.Consts; using AyCode.Core.Helpers; using AyCode.Core.Loggers; using AyCode.Core.Server.Loggers; using AyCode.Database.DbSets.Users; using AyCode.Interfaces.Addresses; using AyCode.Interfaces.Messages; using AyCode.Interfaces.Profiles; using AyCode.Interfaces.ServiceProviders; namespace AyCode.Database.DataLayers.Users { public abstract class AcUserDalBase : AcDalBase where TDbContext : AcDbContextBase, IAcUserDbContextBase where TUser : class, IAcUser where TProfile : class, IAcProfile where TUserToken : class, IAcUserTokenBase where TCompany : class, IAcCompanyBase where TUserToCompany : class, IAcUserToCompanyBase where TAddress : class, IAcAddress where TEmailMessage : class, IAcEmailMessageBase { public TUser? GetUserById(Guid userId, bool onlyConfirmed) => Session(x => x.GetUserById(userId, onlyConfirmed)); public Task GetUserByIdAsync(Guid userId, bool onlyConfirmed) => SessionAsync(x => x.GetUserById(userId, onlyConfirmed)); public TUser? GetUserByEmail(string? email, bool onlyConfirmed) => Session(x => x.GetUserByEmail(email, onlyConfirmed)); public Task GetUserByEmailAsync(string? email, bool onlyConfirmed) => SessionAsync(x => x.GetUserByEmail(email, onlyConfirmed)); public TUserModelDto? GetUserModelDtoById(Guid userId, bool onlyConfirmed) where TUserModelDto : class, IAcUserModelDtoMinBase => Session(ctx => ctx.GetUserModelDtoById(userId, onlyConfirmed)); public Task GetUserModelDtoByIdAsync(Guid userId, bool onlyConfirmed) where TUserModelDto : class, IAcUserModelDtoMinBase => SessionAsync(ctx => ctx.GetUserModelDtoById(userId, onlyConfirmed)); public TUserModelDto? GetUserModelDtoByEmail(string email, bool onlyConfirmed) where TUserModelDto : class, IAcUserModelDtoMinBase => Session(ctx => ctx.GetUserModelDtoByEmail(email, onlyConfirmed)); public Task GetUserModelDtoByEmailAsync(string email, bool onlyConfirmed) where TUserModelDto : class, IAcUserModelDtoMinBase => SessionAsync(ctx => ctx.GetUserModelDtoByEmail(email, onlyConfirmed)); public List GetAllUserModelDto() where TUserModelDto : class, IAcUserModelDtoMinBase => GetAllModelDto(); public Task> GetAllUserModelDtoAsync() where TUserModelDto : class, IAcUserModelDtoMinBase => GetAllModelDtoAsync(); public Task AddUserAsync(TUser user) { return TransactionAsync(ctx => ctx.AddUser(user)); } public Task AddUserAsync(TUser user, string profileName, TAddress address, string? firstName = null, string? lastName = null) { return TransactionAsync(ctx => { var profile = CreateProfile(profileName, address, firstName, lastName); user.Profile= profile; return ctx.AddUser(user); }); } public bool AddUser(TUser user, string profileName, TAddress address, string? firstName = null, string? lastName = null) { return Transaction(ctx => { var profile = CreateProfile(profileName, address, firstName, lastName); user.Profile = profile; return ctx.AddUser(user); }); } private static TProfile CreateProfile(string profileName, TAddress address, string? firstName, string? lastName) { var profile = Activator.CreateInstance(); profile.Id = Guid.NewGuid(); profile.Name = profileName; profile.FirstName = firstName; profile.LastName = lastName; profile.Address = address; profile.AddressId = address.Id; return profile; } public Task RemoveUserAsync(TUser user) => TransactionAsync(ctx => ctx.RemoveUser(user)); public Task RemoveUserAsync(Guid userId) => TransactionAsync(ctx => ctx.RemoveUser(userId)); public TUser? AuthenticateUser(string? email, string? password, string refreshToken, out AcErrorCode errorCode) { TUser? user = null; var errorCodeInner = AcErrorCode.Unset; var result = Transaction(ctx => { try { //var passwordHash = PasswordHasher.HashPassword(password, PasswordHasher.GenerateDynamicSalt(userId)); user = ctx.GetUserByEmail(email, true); if (user is { EmailConfirmed: true } && string.Equals(user.EmailAddress, email, StringComparison.CurrentCultureIgnoreCase) && PasswordHasher.VerifyPassword(password, user.Password, PasswordHasher.GenerateDynamicSalt(user.Id))) { if (ctx.UpdateJwtRefreshToken(user, refreshToken)) return true; errorCodeInner = AcErrorCode.RefreshTokenUpdateError; } else errorCodeInner = AcErrorCode.WrongLoginData; } catch (Exception ex) { GlobalLogger.Error(ex.Message, ex); errorCodeInner = AcErrorCode.UnknownError; } return false; }); errorCode = errorCodeInner; return result ? user : null; } public async Task UpdateJwtRefreshTokenAsync(string email, string refreshToken) { TUser? user = null; return await TransactionAsync(ctx => (user = ctx.UpdateJwtRefreshToken(email, refreshToken)) != null) ? user : null; } public TUser? UpdateJwtRefreshToken(string email, string refreshToken) { TUser? user = null; return Transaction(ctx => (user = ctx.UpdateJwtRefreshToken(email, refreshToken)) != null) ? user : null; } //public UserToken CreateUserToken(Guid userId, string verificationToken) //{ // UserToken userToken = null; // Transaction(ctx => // { // userToken = ctx.CreateUserToken(userId, verificationToken); // return userToken != null; // } // ); // return userToken; //} //public UserToken UpdateUserTokenSent(Guid userId, string verificationToken, DateTime tokenSentUtc) //{ // UserToken userToken = null; // Transaction(ctx => // { // userToken = ctx.UpdateUserTokenSent(userId, verificationToken, tokenSentUtc); // return userToken != null; // } // ); // return userToken; //} //public UserToken GetActiveUserToken(Guid userId) // => Session(ctx => ctx.GetActiveUserToken(userId)); //public UserToken GetUserToken(Guid userId, string verificationToken) // => Session(ctx => ctx.GetUserToken(userId, verificationToken)); //public bool IsValidToken(Guid userId, string verificationToken) // => Transaction(ctx => ctx.IsValidToken(userId, verificationToken)); //public bool IsValidToken(string email, string verificationToken) //{ // return Transaction(ctx => // { // var user = ctx.GetUserByEmail(email); // return user != null && ctx.IsValidToken(user.Id, verificationToken); // }); //} //public void DeactivateTokens(Guid userId) //{ // Transaction(ctx => // { // ctx.DeactivateTokens(userId); // return true; // }); //} //public string GetValidVerificationToken(UserDal userDal, Guid userId, out UserToken userToken) //{ // string verificationToken; // userToken = userDal.GetActiveUserToken(userId); // if (userToken == null) // { // verificationToken = AntGenerator.NewToken(); // userToken = userDal.CreateUserToken(userId, verificationToken); // } // else verificationToken = userToken.Token; // return verificationToken; //} public AcErrorCode GetUserForEmailValidation(string email, Func callback) { TUser? user = null; var errorCodes = AcErrorCode.Unset; Transaction(ctx => { var lowerEmail= email.ToLower(); user = ctx.Users.FirstOrDefault(x => x.EmailAddress == lowerEmail && x.EmailConfirmed); if (user == null) { errorCodes = AcErrorCode.UserNameNotFound; return false; } //user.Profile = ctx.Profiles.FirstOrDefault(x => x.OwnerId == user.Id); //if (!ctx.IsUserConsentsAccepted(user.Id)) errorCodes = AcErrorCode.ConsentNotAccepted; return true; }); //if (user != null) return callback(user, errorCodes); } } }