deleting password
This commit is contained in:
parent
36d8cc9a4d
commit
2519fc77d2
15 changed files with 237 additions and 47 deletions
|
@ -11,7 +11,7 @@ namespace Femto.Modules.Auth.Application;
|
|||
|
||||
internal class AuthService(
|
||||
AuthContext context,
|
||||
SessionStorage storage,
|
||||
SessionStorage sessionStorage,
|
||||
IDbConnectionFactory connectionFactory
|
||||
) : IAuthService
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ internal class AuthService(
|
|||
|
||||
var session = new Session(user.Id, true);
|
||||
|
||||
await storage.AddSession(session);
|
||||
await sessionStorage.AddSession(session);
|
||||
|
||||
return new(
|
||||
new UserInfo(user.Id, user.Username, user.Roles.Select(r => r.Role).ToList()),
|
||||
|
@ -53,7 +53,7 @@ internal class AuthService(
|
|||
{
|
||||
var session = new Session(userId, true);
|
||||
|
||||
await storage.AddSession(session);
|
||||
await sessionStorage.AddSession(session);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
@ -62,19 +62,19 @@ internal class AuthService(
|
|||
{
|
||||
var session = new Session(userId, false);
|
||||
|
||||
await storage.AddSession(session);
|
||||
await sessionStorage.AddSession(session);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
public Task<Session?> GetSession(string sessionId)
|
||||
{
|
||||
return storage.GetSession(sessionId);
|
||||
return sessionStorage.GetSession(sessionId);
|
||||
}
|
||||
|
||||
public async Task DeleteSession(string sessionId)
|
||||
{
|
||||
await storage.DeleteSession(sessionId);
|
||||
await sessionStorage.DeleteSession(sessionId);
|
||||
}
|
||||
|
||||
public async Task<UserAndSession> CreateUserWithCredentials(
|
||||
|
@ -113,7 +113,7 @@ internal class AuthService(
|
|||
|
||||
var session = new Session(user.Id, true);
|
||||
|
||||
await storage.AddSession(session);
|
||||
await sessionStorage.AddSession(session);
|
||||
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
|
@ -189,7 +189,7 @@ internal class AuthService(
|
|||
if (token is null)
|
||||
return (null, null);
|
||||
|
||||
if (!token.Validate(rememberMeToken.Verifier))
|
||||
if (!token.CheckVerifier(rememberMeToken.Verifier))
|
||||
return (null, null);
|
||||
|
||||
var user = await context.Users.SingleOrDefaultAsync(u => u.Id == token.UserId);
|
||||
|
@ -218,13 +218,34 @@ internal class AuthService(
|
|||
if (session is null)
|
||||
return;
|
||||
|
||||
if (!session.Validate(rememberMeToken.Verifier))
|
||||
if (!session.CheckVerifier(rememberMeToken.Verifier))
|
||||
return;
|
||||
|
||||
context.Remove(session);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task ChangePassword(Guid userId, string password, CancellationToken cancellationToken)
|
||||
{
|
||||
// change the password
|
||||
// invalidate long term sessions
|
||||
// invalidate sessions
|
||||
|
||||
var user = await context.Users.SingleOrDefaultAsync(u => u.Id == userId,cancellationToken);
|
||||
|
||||
if (user is null)
|
||||
throw new DomainError("invalid user");
|
||||
|
||||
user.SetPassword(password);
|
||||
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task InvalidateUserSessions(Guid userId, CancellationToken cancellationToken)
|
||||
{
|
||||
await sessionStorage.InvalidateUserSessions(userId);
|
||||
}
|
||||
|
||||
private class GetSignupCodesQueryResultRow
|
||||
{
|
||||
public string Code { get; set; }
|
||||
|
|
|
@ -20,13 +20,14 @@ public static class AuthStartup
|
|||
this IServiceCollection rootContainer,
|
||||
string connectionString,
|
||||
IEventBus eventBus,
|
||||
ILoggerFactory loggerFactory
|
||||
ILoggerFactory loggerFactory,
|
||||
TimeProvider timeProvider
|
||||
)
|
||||
{
|
||||
var hostBuilder = Host.CreateDefaultBuilder();
|
||||
|
||||
hostBuilder.ConfigureServices(services =>
|
||||
ConfigureServices(services, connectionString, eventBus, loggerFactory)
|
||||
ConfigureServices(services, connectionString, eventBus, loggerFactory, timeProvider)
|
||||
);
|
||||
|
||||
var host = hostBuilder.Build();
|
||||
|
@ -52,9 +53,12 @@ public static class AuthStartup
|
|||
IServiceCollection services,
|
||||
string connectionString,
|
||||
IEventPublisher publisher,
|
||||
ILoggerFactory loggerFactory
|
||||
ILoggerFactory loggerFactory,
|
||||
TimeProvider timeProvider
|
||||
)
|
||||
{
|
||||
services.AddSingleton(timeProvider);
|
||||
|
||||
services.AddTransient<IDbConnectionFactory>(_ => new DbConnectionFactory(connectionString));
|
||||
|
||||
services.AddDbContext<AuthContext>(builder =>
|
||||
|
@ -83,11 +87,8 @@ public static class AuthStartup
|
|||
|
||||
services.AddSingleton(publisher);
|
||||
services.AddSingleton<SessionStorage>();
|
||||
|
||||
services.AddScoped(
|
||||
typeof(IPipelineBehavior<,>),
|
||||
typeof(SaveChangesPipelineBehaviour<,>)
|
||||
);
|
||||
|
||||
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(SaveChangesPipelineBehaviour<,>));
|
||||
|
||||
services.AddScoped<IAuthService, AuthService>();
|
||||
}
|
||||
|
|
|
@ -3,12 +3,6 @@ using Femto.Modules.Auth.Models;
|
|||
|
||||
namespace Femto.Modules.Auth.Application;
|
||||
|
||||
/// <summary>
|
||||
/// I broke off IAuthService from IAuthModule because the CQRS distinction is cumbersome when doing auth handling,
|
||||
/// particularly in regards to session management. I may or may not bother to move the commands and queries here also,
|
||||
/// but for controller actions I do quite like having the abstraction, and there is less drive within me to bother.
|
||||
/// It just seems redundant to expose them both, and it's a bit confusin'
|
||||
/// </summary>
|
||||
public interface IAuthService
|
||||
{
|
||||
public Task<UserAndSession?> AuthenticateUserCredentials(
|
||||
|
@ -43,6 +37,9 @@ public interface IAuthService
|
|||
Task<NewRememberMeToken> CreateRememberMeToken(Guid userId);
|
||||
Task<(UserInfo?, NewRememberMeToken?)> GetUserWithRememberMeToken(RememberMeToken rememberMeToken);
|
||||
Task DeleteRememberMeToken(RememberMeToken rememberMeToken);
|
||||
|
||||
Task ChangePassword(Guid userId, string password, CancellationToken cancellationToken = default);
|
||||
Task InvalidateUserSessions(Guid userId, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
public record UserAndSession(UserInfo User, Session Session);
|
Loading…
Add table
Add a link
Reference in a new issue