AyCode.Core/AyCode.Database/DataLayers/Users/AcUserDalBase.cs

239 lines
8.7 KiB
C#

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.Database.DbSets.Users;
using AyCode.Interfaces.Addresses;
using AyCode.Interfaces.Profiles;
using AyCode.Interfaces.ServiceProviders;
namespace AyCode.Database.DataLayers.Users
{
public abstract class AcUserDalBase<TDbContext, TUser, TProfile, TUserToken, TServiceProvider, TUserToServiceProvider, TProfileAddress> : AcDalBase<TDbContext>
where TDbContext : AcDbContextBase, IAcUserDbContextBase<TUser, TProfile, TUserToken, TServiceProvider, TUserToServiceProvider, TProfileAddress>
where TUser : class, IAcUser<TProfile, TServiceProvider, TUserToServiceProvider, TProfileAddress>
where TProfile : class, IAcProfile<TProfileAddress>
where TUserToken : class, IAcUserTokenBase
where TServiceProvider : class, IAcServiceProviderBase
where TUserToServiceProvider : class, IAcUserToServiceProviderBase
where TProfileAddress : class, IAcAddress
{
public TUser? GetUserById(Guid userId) => Session(x => x.GetUserById(userId));
public Task<TUser?> GetUserByIdAsync(Guid userId) => SessionAsync(x => x.GetUserById(userId));
public TUser? GetUserByEmail(string? email) => Session(x => x.GetUserByEmail(email));
public Task<TUser?> GetUserByEmailAsync(string? email) => SessionAsync(x => x.GetUserByEmail(email));
public Task<bool> AddUserAsync(TUser user)
{
return TransactionAsync(ctx => ctx.AddUser(user));
}
public Task<bool> AddUserAsync(TUser user, string profileName, TProfileAddress 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, TProfileAddress 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, TProfileAddress address, string? firstName, string? lastName)
{
var profile = Activator.CreateInstance<TProfile>();
profile.Id = Guid.NewGuid();
profile.Name = profileName;
profile.FirstName = firstName;
profile.LastName = lastName;
profile.Address = address;
profile.AddressId = address.Id;
return profile;
}
public Task<bool> RemoveUserAsync(TUser? user) => TransactionAsync(ctx => RemoveUserTransactionBody(user, ctx));
public Task<bool> RemoveUserAsync(Guid userId) => TransactionAsync(ctx =>
{
var user = ctx.GetUserById(userId);
return RemoveUserTransactionBody(user, ctx);
});
protected bool RemoveUserTransactionBody(TUser? user, TDbContext ctx)
{
if (user == null) return false;
var profile = ctx.Profiles.FirstOrDefault(x => x.Id == user.ProfileId);
if (profile != null)
{
var address = ctx.Addresses.FirstOrDefault(x => x.Id == profile.AddressId);
if (address != null) ctx.Addresses.Remove(address);
ctx.Profiles.Remove(profile);
}
return ctx.RemoveUser(user);
}
public TUser? AuthenticateUser(string? email, string? password, string refreshToken, out AcErrorCode errorCode)
{
TUser? user = null;
var errorCodeInner = AcErrorCode.Unset;
var result = Transaction(ctx =>
{
user = ctx.GetUserByEmail(email);
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;
return false;
});
errorCode = errorCodeInner;
return result ? user : null;
}
public async Task<TUser?> 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<TUser?, AcErrorCode, AcErrorCode> 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);
}
}
}