From 8fa86c429d88249f8a065d79a3dc144d46d5945f Mon Sep 17 00:00:00 2001 From: Daniela2319 Date: Wed, 10 Dec 2025 10:29:56 -0300 Subject: [PATCH] feat: adicionado login e password --- .../Controllers/AuthController.cs | 42 ++++ .../Controllers/PersonController.cs | 74 +++++-- .../Controllers/UsuarioController.cs | 107 ++++++++++ .../Extensions/AuthenticationExtensions.cs | 45 +++++ .../DependencyInjectionExtensions.cs | 14 +- .../src/jwt-auth-api.Api/Program.cs | 14 +- .../Properties/launchSettings.json | 6 +- .../ViewModel/BaseViewModel.cs | 8 + .../ViewModel/Login/AuthLoginRequest.cs | 14 ++ .../ViewModel/Login/AuthLoginResponse.cs | 9 + .../ViewModel/Person/PersonViewModel.cs | 13 ++ .../ViewModel/Users/UserPasswordViewModel.cs | 10 + .../ViewModel/Users/UserRequestViewModel.cs | 14 ++ .../ViewModel/Users/UserResponseViewModel.cs | 10 + .../src/jwt-auth-api.Api/appsettings.json | 7 + .../jwt-auth-api.Api/jwt-auth-api.Api.csproj | 3 +- .../Auth/Config/TokenConfiguration.cs | 15 ++ .../Auth/Tools/TokenGenerator.cs | 46 +++++ .../Service/AuthService.cs | 48 +++++ .../{BaseService.cs => GeneriService.cs} | 43 ++-- .../Service/PersonService.cs | 24 +++ .../Service/ServicePerson.cs | 13 -- .../Service/ServiceUsuario.cs | 15 -- .../Service/UsuarioService.cs | 34 ++++ .../jwt-auth-api.Application.csproj | 4 + .../src/jwt-auth-api.Core/BaseModel.cs | 2 +- .../src/jwt-auth-api.Core/Permissao.cs | 12 -- .../src/jwt-auth-api.Core/Role.cs | 12 -- .../src/jwt-auth-api.Core/RolePermissao.cs | 12 -- .../src/jwt-auth-api.Core/Token.cs | 14 -- .../jwt-auth-api.Core/{ => Users}/Person.cs | 2 +- .../jwt-auth-api.Core/{ => Users}/Usuario.cs | 4 +- .../src/jwt-auth-api.Core/UsuarioRole.cs | 12 -- .../Context/ApplicationDbContext.cs | 7 +- .../20251203120433_Initial.Designer.cs | 188 ------------------ .../Migrations/20251203120433_Initial.cs | 141 ------------- .../20251209140241_Initial.Designer.cs | 84 ++++++++ .../Migrations/20251209140241_Initial.cs | 58 ++++++ .../ApplicationDbContextModelSnapshot.cs | 124 +----------- .../Repositories/AuthRepository.cs | 24 +++ ...{BaseRepository.cs => GeneriRepository.cs} | 49 +++-- .../Repositories/Interfaces/IRepositoriy.cs | 11 +- .../Repositories/RepositoryInDbPostgres.cs | 4 +- 43 files changed, 765 insertions(+), 627 deletions(-) create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/AuthController.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/UsuarioController.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/AuthenticationExtensions.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/BaseViewModel.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginRequest.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginResponse.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Person/PersonViewModel.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserPasswordViewModel.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserRequestViewModel.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserResponseViewModel.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Config/TokenConfiguration.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Tools/TokenGenerator.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Application/Service/AuthService.cs rename jwt-auth-api.Api/src/jwt-auth-api.Application/Service/{BaseService.cs => GeneriService.cs} (79%) create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Application/Service/PersonService.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServicePerson.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServiceUsuario.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Application/Service/UsuarioService.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Core/Permissao.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Core/Role.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Core/RolePermissao.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Core/Token.cs rename jwt-auth-api.Api/src/jwt-auth-api.Core/{ => Users}/Person.cs (89%) rename jwt-auth-api.Api/src/jwt-auth-api.Core/{ => Users}/Usuario.cs (79%) delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Core/UsuarioRole.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.Designer.cs delete mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.Designer.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.cs create mode 100644 jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/AuthRepository.cs rename jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/{BaseRepository.cs => GeneriRepository.cs} (79%) diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/AuthController.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/AuthController.cs new file mode 100644 index 0000000..1222456 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/AuthController.cs @@ -0,0 +1,42 @@ +using jwt_auth_api.Api.ViewModel.Login; +using jwt_auth_api.Application.Service; +using Microsoft.AspNetCore.Identity.Data; +using Microsoft.AspNetCore.Mvc; + +namespace jwt_auth_api.Api.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class AuthController : ControllerBase + { + private readonly AuthService _authService; + public AuthController(AuthService authService) + { + _authService = authService; + } + + [HttpPost("login")] + public IActionResult Login([FromBody] AuthLoginRequest request) + { + try + { + string retorno = _authService.Login(request.Email, request.Password); + AuthLoginResponse response = new AuthLoginResponse(); + response.Token = retorno; + response.Message = "Login realizado com sucesso"; + return Ok(response); + } + catch (Exception ex) + { + return Unauthorized(new { Message = ex.Message }); + } + } + + [HttpPost("Logout")] + public IActionResult Logout() + { + string result = _authService.Logout(); + return Ok(result); + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/PersonController.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/PersonController.cs index e2683f8..eb1ae09 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/PersonController.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/PersonController.cs @@ -1,54 +1,92 @@ -using jwt_auth_api.Application.Service; -using jwt_auth_api.Core; +using jwt_auth_api.Api.ViewModel; +using jwt_auth_api.Api.ViewModel.PersonViewModel; +using jwt_auth_api.Application.Service; +using jwt_auth_api.Core.Users; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 - namespace jwt_auth_api.Api.Controllers { [Route("api/[controller]")] [ApiController] + [Authorize] public class PersonController : ControllerBase { - private readonly ServicePerson _servicePerson; - public PersonController(ServicePerson servicePerson) + private readonly PersonService _servicePerson; + public PersonController(PersonService servicePerson) { _servicePerson = servicePerson; } [HttpGet] - public List Get() + public IActionResult Get() { - return _servicePerson.Read(); + List person = _servicePerson.Read(); + List listViewModel = new List(); + foreach (var p in person) + { + listViewModel.Add(new PersonViewModel + { + Id = p.Id, + FirstName = p.FirstName, + LastName = p.LastName + }); + } + return Ok(listViewModel); } - [HttpGet("{id}")] - public Person Get(Guid id) + public ActionResult Get(int id) { - return _servicePerson.ReadById(id); + Person person = _servicePerson.ReadById(id); + if (person == null) + return NotFound(); + + var personViewModel = new PersonViewModel + { + Id = person.Id, + FirstName = person.FirstName, + LastName = person.LastName + }; + + return personViewModel; } + [HttpGet("exist/{id}")] - public bool Exist(Guid id) + public IActionResult Exist(int id) { - return _servicePerson.Exists(id); + var response = _servicePerson.Exists(id); + return Ok(response); } [HttpPost] - public void Post([FromBody] Person model) + public IActionResult Post([FromBody] PersonViewModel viewModel) { + Person model = new Person + { + FirstName = viewModel.FirstName, + LastName = viewModel.LastName + }; _servicePerson.Create(model); + return CreatedAtAction(nameof(Get), new { id = model.Id }, model); } - - + [HttpPut("{id}")] - public void Put(Guid id, [FromBody] Person model) + public IActionResult Put(int id, [FromBody] PersonViewModel viewModel) { + Person model = new Person + { + Id = id, + FirstName = viewModel.FirstName, + LastName = viewModel.LastName + }; + _servicePerson.Update(model); + return Ok(model); } [HttpDelete("{id}")] - public StatusCodeResult Delete(Guid id) + public StatusCodeResult Delete(int id) { try { diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/UsuarioController.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/UsuarioController.cs new file mode 100644 index 0000000..e5ecb03 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/Controllers/UsuarioController.cs @@ -0,0 +1,107 @@ +using jwt_auth_api.Api.ViewModel.UsersViewModel; +using jwt_auth_api.Application.Service; +using jwt_auth_api.Core.Users; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace jwt_auth_api.Api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + [Authorize] + public class UsuarioController : ControllerBase + { + private readonly UsuarioService _serviceUsuario; + private readonly PersonService _servicePerson; + + public UsuarioController(UsuarioService serviceUsuario, PersonService servicePerson) + { + _serviceUsuario = serviceUsuario; + _servicePerson = servicePerson; + } + + [HttpGet] + public List Get() + { + List usuarios = _serviceUsuario.Read(); + List listViewModel = new List(); + foreach (var usuario in usuarios) + { + listViewModel.Add(new UserResponseViewModel + { + Id = usuario.Id, + Email = usuario.Email, + CreatedAt = usuario.CreatedAt, + Person = _servicePerson.ReadById(usuario.PersonId) + }); //gerei o token no senha do usuario, depois é validar com jwt + } + return listViewModel; + } + + + [HttpGet("{id}")] + public UserResponseViewModel Get(int id) + { + Usuario user = _serviceUsuario.ReadById(id); + UserResponseViewModel userResponseViewModel = new UserResponseViewModel + { + Id = user.Id, + Email = user.Email, + CreatedAt = user.CreatedAt, + Person = _servicePerson.ReadById(user.PersonId) + }; + return userResponseViewModel; + } + + [HttpGet("exist/{id}")] + public bool Exist(int id) + { + return _serviceUsuario.Exists(id); + } + + [HttpPost] + public IActionResult Post([FromBody] UserRequestViewModel viewModel) + { + Usuario model = new Usuario + { + Email = viewModel.Email, + Password = viewModel.Password, + PersonId = viewModel.PersonId + }; + _serviceUsuario.Create(model); + return CreatedAtAction(nameof(Get), new { id = model.Id }, model); + } + + + [HttpPut("{id}")] + public void Put(int id, [FromBody] UserPasswordViewModel model) + { + if (id != model.Id) + { + throw new ArgumentException("O ID do objeto User não é igual ao ID da URL."); + } + + Usuario userToUpdate = new Usuario(); + userToUpdate.Id = model.Id; + userToUpdate.Password = model.Password; + _serviceUsuario.Update(userToUpdate); + } + + [HttpDelete("{id}")] + public StatusCodeResult Delete(int id) + { + try + { + this. _serviceUsuario.Delete(id); + StatusCodeResult result = new StatusCodeResult(204); + return result; + } + catch (Exception) + { + StatusCodeResult result = new StatusCodeResult(500); + return result; + } + + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/AuthenticationExtensions.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/AuthenticationExtensions.cs new file mode 100644 index 0000000..0b4e4f6 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/AuthenticationExtensions.cs @@ -0,0 +1,45 @@ +using jwt_auth_api.Application.Auth.Config; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Authorization; +using Microsoft.IdentityModel.Tokens; +using System.Security.Claims; +using System.Text; + +namespace jwt_auth_api.Api.Extensions +{ + public static class AuthenticationExtensions + { + public static IServiceCollection AddAuthenticationConfiguration(this IServiceCollection services, IConfiguration configuration) + { + // Configurações de Token + var tokenConfigurations = configuration.GetSection("TokenConfigurations"); + var issuer = tokenConfigurations["Issuer"]; + var audience = tokenConfigurations["Audience"]; + var secret = tokenConfigurations["Secret"] + ?? throw new InvalidOperationException("JWT Secret não configurado."); + services.Configure(tokenConfigurations); + + services.AddAuthentication(option => + { + option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + ValidIssuer = issuer, + ValidAudience = audience, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)), + RoleClaimType = ClaimTypes.Role + }; + }); + + return services; + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/DependencyInjectionExtensions.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/DependencyInjectionExtensions.cs index 3eb326e..aca5206 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/DependencyInjectionExtensions.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/Extensions/DependencyInjectionExtensions.cs @@ -1,6 +1,9 @@ -using jwt_auth_api.Application.Service; +using jwt_auth_api.Application.Auth.Tools; +using jwt_auth_api.Application.Service; +using jwt_auth_api.Core.Users; using jwt_auth_api.Infrastructure.Repositories; using jwt_auth_api.Infrastructure.Repositories.Interfaces; +using Microsoft.AspNetCore.Identity; namespace jwt_auth_api.Api.Extensions { @@ -8,10 +11,15 @@ public static class DependencyInjectionExtensions { public static IServiceCollection AddAppDependencies(this IServiceCollection services) { - services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped>(); // ===== Repositories ===== - services.AddScoped(typeof(IRepositoriy<>), typeof(BaseRepository<>)); + services.AddScoped(typeof(IRepositoriy<>), typeof(GeneriRepository<>)); + services.AddScoped(); return services; } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/Program.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/Program.cs index 8e69155..0c6dfcd 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Api/Program.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/Program.cs @@ -1,6 +1,9 @@ using jwt_auth_api.Api.Extensions; using jwt_auth_api.Infrastructure.Context; using Microsoft.EntityFrameworkCore; +using Microsoft.OpenApi; +using Scalar.AspNetCore; + var builder = WebApplication.CreateBuilder(args); @@ -11,8 +14,7 @@ builder.Services.AddControllers(); // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); + //===== Database ===== builder.Services.AddDbContext(options => @@ -23,19 +25,19 @@ //===== Extensions ===== builder.Services.AddAppDependencies(); +builder.Services.AddAuthenticationConfiguration(builder.Configuration); + var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { + app.MapScalarApiReference(); app.MapOpenApi(); - - app.UseSwagger(); - app.UseSwaggerUI(); } app.UseHttpsRedirection(); - +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/Properties/launchSettings.json b/jwt-auth-api.Api/src/jwt-auth-api.Api/Properties/launchSettings.json index 0da6cec..d7ea458 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Api/Properties/launchSettings.json +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/Properties/launchSettings.json @@ -4,7 +4,8 @@ "http": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": false, + "launchBrowser": true, + "launchUrl": "scalar", "applicationUrl": "http://localhost:5261", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" @@ -13,7 +14,8 @@ "https": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": false, + "launchBrowser": true, + "launchUrl": "scalar", "applicationUrl": "https://localhost:7185;http://localhost:5261", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/BaseViewModel.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/BaseViewModel.cs new file mode 100644 index 0000000..e9da6bd --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/BaseViewModel.cs @@ -0,0 +1,8 @@ +namespace jwt_auth_api.Api.ViewModel +{ + public class BaseViewModel + { + public int Id { get; set; } + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginRequest.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginRequest.cs new file mode 100644 index 0000000..4fd4ba1 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginRequest.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; + +namespace jwt_auth_api.Api.ViewModel.Login +{ + public class AuthLoginRequest + { + [Required(ErrorMessage = "O campo E-mail é obrigatório.")] + [EmailAddress(ErrorMessage = "O campo E-mail deve ser um endereço de e-mail válido.")] + public string Email { get; set; } = string.Empty; + [Required(ErrorMessage = "O campo Senha é obrigatório.")] + [MinLength(3, ErrorMessage = "O campo Senha deve ter no mínimo 3 caracteres.")] + public string Password { get; set; } = string.Empty; + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginResponse.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginResponse.cs new file mode 100644 index 0000000..3dc59b1 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Login/AuthLoginResponse.cs @@ -0,0 +1,9 @@ +namespace jwt_auth_api.Api.ViewModel.Login +{ + public class AuthLoginResponse + { + public string Token { get; set; } = string.Empty; + public string Message { get; set; } = string.Empty; + + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Person/PersonViewModel.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Person/PersonViewModel.cs new file mode 100644 index 0000000..ad6ea0c --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Person/PersonViewModel.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace jwt_auth_api.Api.ViewModel.PersonViewModel +{ + public class PersonViewModel : BaseViewModel + { + [Required(ErrorMessage = "O campo Primeiro Nome é obrigatório.")] + public string FirstName { get; set; } = string.Empty; + [Required(ErrorMessage = "O campo Sobrenome é obrigatório.")] + public string LastName { get; set; } = string.Empty; + + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserPasswordViewModel.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserPasswordViewModel.cs new file mode 100644 index 0000000..55aaa97 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserPasswordViewModel.cs @@ -0,0 +1,10 @@ +using System.ComponentModel.DataAnnotations; + +namespace jwt_auth_api.Api.ViewModel.UsersViewModel +{ + public class UserPasswordViewModel : BaseViewModel + { + [Required(ErrorMessage = "O campo Senha é obrigatório.")] + public string Password { get; set; } = string.Empty; + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserRequestViewModel.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserRequestViewModel.cs new file mode 100644 index 0000000..52c9558 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserRequestViewModel.cs @@ -0,0 +1,14 @@ +using jwt_auth_api.Core.Users; +using System.ComponentModel.DataAnnotations; + +namespace jwt_auth_api.Api.ViewModel.UsersViewModel +{ + public class UserRequestViewModel + { + [Required(ErrorMessage = "O campo Email é obrigatório.")] + public string Email { get; set; } = string.Empty; + [Required(ErrorMessage = "O campo Senha é obrigatório.")] + public string Password { get; set; } = string.Empty; + public int PersonId { get; set; } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserResponseViewModel.cs b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserResponseViewModel.cs new file mode 100644 index 0000000..a9ce0c7 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/ViewModel/Users/UserResponseViewModel.cs @@ -0,0 +1,10 @@ +using jwt_auth_api.Core.Users; + +namespace jwt_auth_api.Api.ViewModel.UsersViewModel +{ + public class UserResponseViewModel : BaseViewModel + { + public string Email { get; set; } = string.Empty; + public Person Person { get; set; } = new Person(); + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/appsettings.json b/jwt-auth-api.Api/src/jwt-auth-api.Api/appsettings.json index d062b4f..d641eff 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Api/appsettings.json +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/appsettings.json @@ -5,8 +5,15 @@ "Microsoft.AspNetCore": "Warning" } }, + // Scrings de conexão - Adicione os valores em User-Secrets "AllowedHosts": "*", "ConnectionStrings": { "Postgres": "" + }, + // Configurações do JWT - Adicione os valores em User-Secrets + "TokenConfigurations": { + "Audience": "", + "Issuer": "", + "Secret": "" } } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Api/jwt-auth-api.Api.csproj b/jwt-auth-api.Api/src/jwt-auth-api.Api/jwt-auth-api.Api.csproj index 02351fc..ad254f2 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Api/jwt-auth-api.Api.csproj +++ b/jwt-auth-api.Api/src/jwt-auth-api.Api/jwt-auth-api.Api.csproj @@ -9,12 +9,13 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Config/TokenConfiguration.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Config/TokenConfiguration.cs new file mode 100644 index 0000000..8d4d5a1 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Config/TokenConfiguration.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace jwt_auth_api.Application.Auth.Config +{ + public class TokenConfiguration + { + public string Audience { get; set; } = string.Empty; + public string Issuer { get; set; } = string.Empty; + public string Secret { get; set; } = string.Empty; + + + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Tools/TokenGenerator.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Tools/TokenGenerator.cs new file mode 100644 index 0000000..c694c6d --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Application/Auth/Tools/TokenGenerator.cs @@ -0,0 +1,46 @@ +using jwt_auth_api.Application.Auth.Config; +using jwt_auth_api.Core.Users; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; + +namespace jwt_auth_api.Application.Auth.Tools +{ + public class TokenGenerator + { + private readonly TokenConfiguration _tokenConfiguration; + public TokenGenerator(IOptions tokenConfiguration) + { + this._tokenConfiguration = tokenConfiguration.Value; + } + public string GenerateToken(Usuario model) + { + // ===== Claims do Token ===== + var claims = new List + { + new Claim(ClaimTypes.Email, model.Email), + new Claim("UsuarioId", model.Id.ToString()), + new Claim("PersonId", model.PersonId.ToString()), + new Claim(ClaimTypes.Role, "Admin") + }; + + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenConfiguration.Secret)); + var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + + var expiration = DateTime.UtcNow.AddHours(2); + + // ===== Gera o token ===== + var token = new JwtSecurityToken( + issuer: _tokenConfiguration.Issuer, + audience: _tokenConfiguration.Audience, + claims: claims, + expires: expiration, + signingCredentials: creds + ); + var tokenHandler = new JwtSecurityTokenHandler().WriteToken(token); + return tokenHandler; + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/AuthService.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/AuthService.cs new file mode 100644 index 0000000..8f36181 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/AuthService.cs @@ -0,0 +1,48 @@ +using jwt_auth_api.Application.Auth.Tools; +using jwt_auth_api.Core.Users; +using jwt_auth_api.Infrastructure.Repositories; +using Microsoft.AspNetCore.Identity; + + +namespace jwt_auth_api.Application.Service +{ + public class AuthService + { + // Injetar dependências necessárias, como repositórios e serviços de hashing de senha + private readonly AuthRepository _authRepository; + private readonly PasswordHasher _passwordHasher; + private readonly TokenGenerator _tokenGenerator; + + public AuthService(AuthRepository authRepository, PasswordHasher sha256PasswordHasher, TokenGenerator tokenGenerator) + { + _authRepository = authRepository; + _passwordHasher = sha256PasswordHasher; + _tokenGenerator = tokenGenerator; + } + public string Login(string email, string password) + { + if (string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(password)) + throw new ArgumentException("Email e senha são obrigatórios."); + + var model = _authRepository.GetUserByEmail(email); + if (model == null) + throw new UnauthorizedAccessException("Usuário não encontrado."); + + var result = _passwordHasher.VerifyHashedPassword(model, model.Password, password); + if (result != PasswordVerificationResult.Success) + throw new UnauthorizedAccessException("Senha inválida."); + + var token = _tokenGenerator.GenerateToken(model); + if (string.IsNullOrEmpty(token)) + throw new ApplicationException("Falha ao gerar token."); + + return token; + } + + public string Logout() + { + return "Logout bem-sucedido."; + } + + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/BaseService.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/GeneriService.cs similarity index 79% rename from jwt-auth-api.Api/src/jwt-auth-api.Application/Service/BaseService.cs rename to jwt-auth-api.Api/src/jwt-auth-api.Application/Service/GeneriService.cs index d5c09cc..e054f39 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/BaseService.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/GeneriService.cs @@ -3,56 +3,57 @@ namespace jwt_auth_api.Application.Service { - public class BaseService : IRepositoriy where T : BaseModel + public class GeneriService : IRepositoriy where T : BaseModel { private readonly IRepositoriy _repository; - public BaseService(IRepositoriy repository) + public GeneriService(IRepositoriy repository) { _repository = repository; } - public virtual Guid Create(T entity) + + public virtual List Read() { - return _repository.Create(entity); + return _repository.Read(); } - public virtual void Delete(Guid id) + public virtual T ReadById(int id) { var entity = _repository.ReadById(id); if (entity == null) - throw new Exception($"Registro {id} não encontrado."); + throw new Exception($"Registro ID {id} não encontrado."); - _repository.Delete(id); + return entity; } - public virtual bool Exists(Guid id) + public virtual int Create(T entity) { - return _repository.Exists(id); + return _repository.Create(entity); } - public virtual List Read() + public virtual void Update(T entity) { - return _repository.Read(); + var existing = _repository.ReadById(entity.Id); + + if (existing == null) + throw new Exception($"Registro {entity.Id} não encontrado."); + + _repository.Update(entity); } - public virtual T ReadById(Guid id) + public virtual void Delete(int id) { var entity = _repository.ReadById(id); if (entity == null) - throw new Exception($"Registro ID {id} não encontrado."); + throw new Exception($"Registro {id} não encontrado."); - return entity; + _repository.Delete(id); } - public virtual void Update(T entity) + public virtual bool Exists(int id) { - var existing = _repository.ReadById(entity.Id); - - if (existing == null) - throw new Exception($"Registro {entity.Id} não encontrado."); - - _repository.Update(entity); + return _repository.Exists(id); } } } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/PersonService.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/PersonService.cs new file mode 100644 index 0000000..79f9a02 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/PersonService.cs @@ -0,0 +1,24 @@ +using jwt_auth_api.Core.Users; +using jwt_auth_api.Infrastructure.Repositories.Interfaces; +using Microsoft.AspNetCore.Authorization; + + +namespace jwt_auth_api.Application.Service +{ + [Authorize(Roles = "Admin")] + public class PersonService : GeneriService + { + public PersonService(IRepositoriy repository) : base(repository) + { + } + + public override void Update(Person model) + { + var existingPerson = ReadById(model.Id); + existingPerson.FirstName = model.FirstName; + existingPerson.LastName = model.LastName; + + base.Update(existingPerson); + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServicePerson.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServicePerson.cs deleted file mode 100644 index 27fbd99..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServicePerson.cs +++ /dev/null @@ -1,13 +0,0 @@ -using jwt_auth_api.Core; -using jwt_auth_api.Infrastructure.Repositories.Interfaces; - - -namespace jwt_auth_api.Application.Service -{ - public class ServicePerson : BaseService - { - public ServicePerson(IRepositoriy repository) : base(repository) - { - } - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServiceUsuario.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServiceUsuario.cs deleted file mode 100644 index 1313fa8..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/ServiceUsuario.cs +++ /dev/null @@ -1,15 +0,0 @@ -using jwt_auth_api.Core; -using jwt_auth_api.Infrastructure.Repositories.Interfaces; -using System; -using System.Collections.Generic; -using System.Text; - -namespace jwt_auth_api.Application.Service -{ - public class ServiceUsuario : BaseService - { - public ServiceUsuario(IRepositoriy repository) : base(repository) - { - } - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/UsuarioService.cs b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/UsuarioService.cs new file mode 100644 index 0000000..5fc164a --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Application/Service/UsuarioService.cs @@ -0,0 +1,34 @@ +using jwt_auth_api.Core.Users; +using jwt_auth_api.Infrastructure.Repositories.Interfaces; +using Microsoft.AspNetCore.Identity; + +namespace jwt_auth_api.Application.Service +{ + public class UsuarioService : GeneriService + { + private readonly PasswordHasher _passwordHasher; + public UsuarioService(IRepositoriy repository, PasswordHasher sha256PasswordHasher) : base(repository) + { + _passwordHasher = sha256PasswordHasher; + } + + public override int Create(Usuario model) + { + model.Password = _passwordHasher.HashPassword(model, model.Password); + return base.Create(model); + } + + public override void Update(Usuario model) + { + Usuario existingUser = ReadById(model.Id); + if (existingUser != null) + { + model.Email = existingUser.Email; // Evita alterar o email + model.PersonId = existingUser.PersonId; // Evita alterar o PersonId + model.Password = _passwordHasher.HashPassword(model, model.Password); // Atualiza a senha com hash + } + base.Update(model); + } + + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Application/jwt-auth-api.Application.csproj b/jwt-auth-api.Api/src/jwt-auth-api.Application/jwt-auth-api.Application.csproj index f04eb83..aab976e 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Application/jwt-auth-api.Application.csproj +++ b/jwt-auth-api.Api/src/jwt-auth-api.Application/jwt-auth-api.Application.csproj @@ -7,6 +7,10 @@ enable + + + + diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/BaseModel.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/BaseModel.cs index 2e99515..95b5852 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/BaseModel.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Core/BaseModel.cs @@ -6,7 +6,7 @@ namespace jwt_auth_api.Core { public class BaseModel { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public override string ToString() diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/Permissao.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/Permissao.cs deleted file mode 100644 index 3e3ccd6..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/Permissao.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace jwt_auth_api.Core -{ - public class Permissao : BaseModel - { - public string Name { get; set; } = string.Empty; - public string Description { get; set; } = string.Empty; - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/Role.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/Role.cs deleted file mode 100644 index ef5a940..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/Role.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace jwt_auth_api.Core -{ - public class Role : BaseModel - { - public string Name { get; set; } = string.Empty; - public string Description { get; set; } = string.Empty; - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/RolePermissao.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/RolePermissao.cs deleted file mode 100644 index f6b9d62..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/RolePermissao.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace jwt_auth_api.Core -{ - public class RolePermissao : BaseModel - { - public Guid RoleId { get; set; } - public Guid PermissaoId { get; set; } - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/Token.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/Token.cs deleted file mode 100644 index 3cdd974..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/Token.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace jwt_auth_api.Core -{ - public class Token : BaseModel - { - public Guid UsuarioId { get; set; } - public string RefreshToken { get; set; } = string.Empty; - public DateTime ExpiresAt { get; set; } - - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/Person.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/Users/Person.cs similarity index 89% rename from jwt-auth-api.Api/src/jwt-auth-api.Core/Person.cs rename to jwt-auth-api.Api/src/jwt-auth-api.Core/Users/Person.cs index e283390..f8c44c0 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/Person.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Core/Users/Person.cs @@ -1,4 +1,4 @@ -namespace jwt_auth_api.Core +namespace jwt_auth_api.Core.Users { public class Person : BaseModel { diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/Usuario.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/Users/Usuario.cs similarity index 79% rename from jwt-auth-api.Api/src/jwt-auth-api.Core/Usuario.cs rename to jwt-auth-api.Api/src/jwt-auth-api.Core/Users/Usuario.cs index ab709ff..561ea48 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/Usuario.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Core/Users/Usuario.cs @@ -2,13 +2,13 @@ using System.Collections.Generic; using System.Text; -namespace jwt_auth_api.Core +namespace jwt_auth_api.Core.Users { public class Usuario : BaseModel { public string Email { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; public bool IsActive { get; set; } - public Guid PersonId { get; set; } + public int PersonId { get; set; } } } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Core/UsuarioRole.cs b/jwt-auth-api.Api/src/jwt-auth-api.Core/UsuarioRole.cs deleted file mode 100644 index dadf55f..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Core/UsuarioRole.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace jwt_auth_api.Core -{ - public class UsuarioRole : BaseModel - { - public Guid UsuarioId { get; set; } - public Guid RoleId { get; set; } - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Context/ApplicationDbContext.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Context/ApplicationDbContext.cs index 0d942b3..b2b4a78 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Context/ApplicationDbContext.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Context/ApplicationDbContext.cs @@ -1,4 +1,4 @@ -using jwt_auth_api.Core; +using jwt_auth_api.Core.Users; using Microsoft.EntityFrameworkCore; namespace jwt_auth_api.Infrastructure.Context @@ -8,11 +8,6 @@ public class ApplicationDbContext : DbContext public ApplicationDbContext(DbContextOptions options) : base(options) { } public DbSet Persons { get; set; } - public DbSet Tokens { get; set; } - public DbSet UsuarioRoles { get; set; } - public DbSet RolePermissaos { get; set; } - public DbSet Permissaos { get; set; } - public DbSet Roles { get; set; } public DbSet Usuarios { get; set; } } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.Designer.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.Designer.cs deleted file mode 100644 index d385198..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.Designer.cs +++ /dev/null @@ -1,188 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using jwt_auth_api.Infrastructure.Context; - -#nullable disable - -namespace jwt_auth_api.Infrastructure.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20251203120433_Initial")] - partial class Initial - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("jwt_auth_api.Core.Permissao", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Permissaos"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("FirstName") - .IsRequired() - .HasColumnType("text"); - - b.Property("LastName") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Persons"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.Role", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Roles"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.RolePermissao", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("PermissaoId") - .HasColumnType("uuid"); - - b.Property("RoleId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("RolePermissaos"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.Token", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone"); - - b.Property("RefreshToken") - .IsRequired() - .HasColumnType("text"); - - b.Property("UsuarioId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("Tokens"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.Usuario", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsActive") - .HasColumnType("boolean"); - - b.Property("Password") - .IsRequired() - .HasColumnType("text"); - - b.Property("PersonId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("Usuarios"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.UsuarioRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("RoleId") - .HasColumnType("uuid"); - - b.Property("UsuarioId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("UsuarioRoles"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.cs deleted file mode 100644 index 48a74d7..0000000 --- a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251203120433_Initial.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace jwt_auth_api.Infrastructure.Migrations -{ - /// - public partial class Initial : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Permissaos", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - Name = table.Column(type: "text", nullable: false), - Description = table.Column(type: "text", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Permissaos", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Persons", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - FirstName = table.Column(type: "text", nullable: false), - LastName = table.Column(type: "text", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Persons", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "RolePermissaos", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - RoleId = table.Column(type: "uuid", nullable: false), - PermissaoId = table.Column(type: "uuid", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_RolePermissaos", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Roles", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - Name = table.Column(type: "text", nullable: false), - Description = table.Column(type: "text", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Roles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Tokens", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - UsuarioId = table.Column(type: "uuid", nullable: false), - RefreshToken = table.Column(type: "text", nullable: false), - ExpiresAt = table.Column(type: "timestamp with time zone", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Tokens", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "UsuarioRoles", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - UsuarioId = table.Column(type: "uuid", nullable: false), - RoleId = table.Column(type: "uuid", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_UsuarioRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Usuarios", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - Email = table.Column(type: "text", nullable: false), - Password = table.Column(type: "text", nullable: false), - IsActive = table.Column(type: "boolean", nullable: false), - PersonId = table.Column(type: "uuid", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Usuarios", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Permissaos"); - - migrationBuilder.DropTable( - name: "Persons"); - - migrationBuilder.DropTable( - name: "RolePermissaos"); - - migrationBuilder.DropTable( - name: "Roles"); - - migrationBuilder.DropTable( - name: "Tokens"); - - migrationBuilder.DropTable( - name: "UsuarioRoles"); - - migrationBuilder.DropTable( - name: "Usuarios"); - } - } -} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.Designer.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.Designer.cs new file mode 100644 index 0000000..f631b12 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.Designer.cs @@ -0,0 +1,84 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using jwt_auth_api.Infrastructure.Context; + +#nullable disable + +namespace jwt_auth_api.Infrastructure.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251209140241_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("jwt_auth_api.Core.Users.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("jwt_auth_api.Core.Users.Usuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.Property("PersonId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Usuarios"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.cs new file mode 100644 index 0000000..e3443df --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/20251209140241_Initial.cs @@ -0,0 +1,58 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace jwt_auth_api.Infrastructure.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Persons", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + FirstName = table.Column(type: "text", nullable: false), + LastName = table.Column(type: "text", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Persons", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Usuarios", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Email = table.Column(type: "text", nullable: false), + Password = table.Column(type: "text", nullable: false), + IsActive = table.Column(type: "boolean", nullable: false), + PersonId = table.Column(type: "integer", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Usuarios", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Persons"); + + migrationBuilder.DropTable( + name: "Usuarios"); + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs index 471b7b8..3f41788 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs @@ -22,33 +22,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - modelBuilder.Entity("jwt_auth_api.Core.Permissao", b => + modelBuilder.Entity("jwt_auth_api.Core.Users.Person", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("uuid"); + .HasColumnType("integer"); - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Permissaos"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.Person", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("CreatedAt") .HasColumnType("timestamp with time zone"); @@ -66,77 +46,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Persons"); }); - modelBuilder.Entity("jwt_auth_api.Core.Role", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Roles"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.RolePermissao", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("PermissaoId") - .HasColumnType("uuid"); - - b.Property("RoleId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("RolePermissaos"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.Token", b => + modelBuilder.Entity("jwt_auth_api.Core.Users.Usuario", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("integer"); - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone"); - - b.Property("RefreshToken") - .IsRequired() - .HasColumnType("text"); - - b.Property("UsuarioId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("Tokens"); - }); - - modelBuilder.Entity("jwt_auth_api.Core.Usuario", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("CreatedAt") .HasColumnType("timestamp with time zone"); @@ -152,33 +68,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired() .HasColumnType("text"); - b.Property("PersonId") - .HasColumnType("uuid"); + b.Property("PersonId") + .HasColumnType("integer"); b.HasKey("Id"); b.ToTable("Usuarios"); }); - - modelBuilder.Entity("jwt_auth_api.Core.UsuarioRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("RoleId") - .HasColumnType("uuid"); - - b.Property("UsuarioId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("UsuarioRoles"); - }); #pragma warning restore 612, 618 } } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/AuthRepository.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/AuthRepository.cs new file mode 100644 index 0000000..17fde52 --- /dev/null +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/AuthRepository.cs @@ -0,0 +1,24 @@ +using jwt_auth_api.Core.Users; +using jwt_auth_api.Infrastructure.Context; +using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; +using System; +using System.Collections.Generic; +using System.Text; + +namespace jwt_auth_api.Infrastructure.Repositories +{ + public class AuthRepository + { + private readonly ApplicationDbContext _context; + + public AuthRepository(ApplicationDbContext context) + { + _context = context; + } + public Usuario? GetUserByEmail(string email) + { + var user = _context.Usuarios.FirstOrDefault(u => u.Email == email); + return user; + } + } +} diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/BaseRepository.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/GeneriRepository.cs similarity index 79% rename from jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/BaseRepository.cs rename to jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/GeneriRepository.cs index aa819c6..dbda8d1 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/BaseRepository.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/GeneriRepository.cs @@ -5,44 +5,22 @@ namespace jwt_auth_api.Infrastructure.Repositories { - public class BaseRepository : IRepositoriy where T : BaseModel + public class GeneriRepository : IRepositoriy where T : BaseModel { private readonly ApplicationDbContext _context; private readonly DbSet _dbSet; - public BaseRepository(ApplicationDbContext context) + public GeneriRepository(ApplicationDbContext context) { _context = context; _dbSet = context.Set(); } - public Guid Create(T entity) - { - _dbSet.Add(entity); - _context.SaveChanges(); - return entity.Id; - } - - public void Delete(Guid id) - { - var entity = ReadById(id); - - if (entity == null) - return; - - _dbSet.Remove(entity); - _context.SaveChanges(); - } - - public bool Exists(Guid id) - { - return _context.Set().Any(e => e.Id == id); - } public List Read() { return _dbSet.ToList(); } - public T ReadById(Guid id) + public T ReadById(int id) { var entity = _dbSet.Find(id); if (entity is null) @@ -50,6 +28,13 @@ public T ReadById(Guid id) return entity; } + public int Create(T entity) + { + _dbSet.Add(entity); + _context.SaveChanges(); + return entity.Id; + } + public void Update(T entity) { var modelOriginal = ReadById(entity.Id); @@ -58,5 +43,19 @@ public void Update(T entity) _context.Entry(modelOriginal).CurrentValues.SetValues(entity); _context.SaveChanges(); } + + public void Delete(int id) + { + var entity = ReadById(id); + if (entity == null) + return; + _dbSet.Remove(entity); + _context.SaveChanges(); + } + + public bool Exists(int id) + { + return _dbSet.Any(e => e.Id == id); + } } } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/Interfaces/IRepositoriy.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/Interfaces/IRepositoriy.cs index 45c8e28..9e6ff2b 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/Interfaces/IRepositoriy.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/Interfaces/IRepositoriy.cs @@ -1,13 +1,12 @@ - -namespace jwt_auth_api.Infrastructure.Repositories.Interfaces +namespace jwt_auth_api.Infrastructure.Repositories.Interfaces { public interface IRepositoriy { - Guid Create(T entity); List Read(); - T ReadById(Guid id); + T ReadById(int id); + int Create(T entity); void Update(T entity); - void Delete(Guid id); - bool Exists(Guid id); + void Delete(int id); + bool Exists(int id); } } diff --git a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/RepositoryInDbPostgres.cs b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/RepositoryInDbPostgres.cs index 634321a..a7ce2ad 100644 --- a/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/RepositoryInDbPostgres.cs +++ b/jwt-auth-api.Api/src/jwt-auth-api.Infrastructure/Repositories/RepositoryInDbPostgres.cs @@ -1,9 +1,9 @@ -using jwt_auth_api.Core; +using jwt_auth_api.Core.Users; using jwt_auth_api.Infrastructure.Context; namespace jwt_auth_api.Infrastructure.Repositories { - public class RepositoryInDbPostgres : BaseRepository + public class RepositoryInDbPostgres : GeneriRepository { public RepositoryInDbPostgres(ApplicationDbContext context) : base(context) {