43 lines
1.9 KiB
C#
43 lines
1.9 KiB
C#
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using SequenceAuth.Example.Domain;
|
|
using SequenceAuth.Example.Infrastructure;
|
|
using SequenceAuth.Lib;
|
|
|
|
namespace SequenceAuth.Example.Features.Auth;
|
|
|
|
public record LoginCommand(string Username) : IRequest<LoginResult>;
|
|
public record LoginResult(User User, string InitialSequence);
|
|
|
|
public class LoginCommandHandler(AppDbContext dbContext, ISequenceStore sequenceStore, Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor, Microsoft.Extensions.Options.IOptions<SequenceAuth.Lib.SequenceAuthOptions> options) : IRequestHandler<LoginCommand, LoginResult>
|
|
{
|
|
public async Task<LoginResult> Handle(LoginCommand request, CancellationToken cancellationToken)
|
|
{
|
|
var userOpt = await dbContext.Users.FirstOrDefaultAsync(u => u.Username == request.Username, cancellationToken);
|
|
|
|
var user = userOpt switch
|
|
{
|
|
null => await CreateUser(request.Username, cancellationToken),
|
|
_ => userOpt
|
|
};
|
|
|
|
var initialSequenceId = Guid.NewGuid().ToString("N");
|
|
var sequenceData = new SequenceData(UserId: user.Id.ToString(), RequestsRemaining: 1000, State: SequenceState.Initialized, NextSequenceId: initialSequenceId);
|
|
|
|
await sequenceStore.SaveSequenceAsync(initialSequenceId, sequenceData);
|
|
|
|
httpContextAccessor.HttpContext?.Response.Headers.Append(options.Value.NextHeaderName, initialSequenceId);
|
|
httpContextAccessor.HttpContext?.Response.Headers.Append(options.Value.RequestsRemainingHeaderName, "1000");
|
|
|
|
return new LoginResult(user, initialSequenceId);
|
|
}
|
|
|
|
private async Task<User> CreateUser(string username, CancellationToken cancellationToken)
|
|
{
|
|
var user = new User(Guid.NewGuid(), username);
|
|
dbContext.Users.Add(user);
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
return user;
|
|
}
|
|
}
|