first commit

This commit is contained in:
Vitalii Litvinchuk
2026-06-13 23:23:50 +03:00
commit 23958e8e2c
72 changed files with 6142 additions and 0 deletions
@@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Mvc;
namespace SequenceAuth.Example.Controllers;
[ApiController]
[Route("[controller]/[action]")]
public abstract class ApiControllerBase : ControllerBase
{
protected Guid UserId
{
get
{
var options = HttpContext.RequestServices.GetRequiredService<Microsoft.Extensions.Options.IOptions<SequenceAuth.Lib.SequenceAuthOptions>>().Value;
return Guid.Parse(HttpContext.Items[options.UserIdItemKey]?.ToString() ?? throw new UnauthorizedAccessException());
}
}
}
@@ -0,0 +1,24 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using SequenceAuth.Example.Features.Auth;
namespace SequenceAuth.Example.Controllers;
public class AuthController(IMediator mediator) : ApiControllerBase
{
public record LoginRequest(string Username);
[HttpPost]
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
var result = await mediator.Send(new LoginCommand(request.Username));
return Ok(result.User);
}
[HttpPost]
public async Task<IActionResult> Logout()
{
await mediator.Send(new LogoutCommand());
return Ok();
}
}
@@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
namespace SequenceAuth.Example.Controllers;
public class SecureController : ApiControllerBase
{
[HttpGet]
public IActionResult GetData()
{
return Ok(new { Message = "This is protected data. You must have a valid sequence to see this." });
}
}
@@ -0,0 +1,39 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using SequenceAuth.Example.Domain;
using SequenceAuth.Example.Features.Todos;
namespace SequenceAuth.Example.Controllers;
public class TodoController(IMediator mediator) : ApiControllerBase
{
public record CreateTodoRequest(string Title);
[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateTodoRequest request)
{
var result = await mediator.Send(new CreateTodoCommand(UserId, request.Title));
return Ok(result);
}
[HttpGet]
public async Task<IActionResult> List([FromQuery] TodoStatus? status)
{
var result = await mediator.Send(new GetTodosQuery(UserId, status));
return Ok(result);
}
[HttpPut("{id}")]
public async Task<IActionResult> ChangeStatus(Guid id, [FromQuery] TodoStatus status)
{
var result = await mediator.Send(new ChangeTodoStatusCommand(id, UserId, status));
return result.Outcome switch
{
ChangeTodoStatusOutcome.Success => Ok(result.Item),
ChangeTodoStatusOutcome.NotFound => NotFound(),
ChangeTodoStatusOutcome.Unauthorized => StatusCode(403), // No identity claims for Forbid() without auth scheme
_ => StatusCode(500)
};
}
}