Skip to content

Commit

Permalink
auth base
Browse files Browse the repository at this point in the history
  • Loading branch information
cyrmee committed Jun 8, 2023
1 parent bca4821 commit e328813
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 54 deletions.
13 changes: 13 additions & 0 deletions src/Application/DTOs/UserDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Application.DTOs;

public record UserLoginDto(
string UserName,
string Password
);

public record UserSignupDto(
string Email,
string UserName,
string PhoneNumber,
string Password
);
13 changes: 5 additions & 8 deletions src/Application/Services/AuthenticationService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Domain.Models;
using Domain.Repositories;
using Microsoft.AspNetCore.Identity;
Expand All @@ -17,6 +15,7 @@ public interface IAuthenticationService
Task<bool> IsTokenRevoked(string token);
Task<string?> RevokeToken(string token);
Task<string> GenerateJwtToken(User user);
DateTime GetTokenExpirationDays();
}

public class AuthenticationService : IAuthenticationService
Expand Down Expand Up @@ -100,11 +99,7 @@ private async Task<List<Claim>> GetClaims(User user)
claims.AddRange(roleClaims);
}
}

claims.Add(new Claim(ClaimTypes.UserData, JsonSerializer.Serialize(user, new JsonSerializerOptions()
{
ReferenceHandler = ReferenceHandler.Preserve
})));

return claims;
}

Expand All @@ -114,10 +109,12 @@ private JwtSecurityToken GenerateTokenOptions(SigningCredentials signingCredenti
audience: _configuration["JwtBearer:Audience"],
issuer: _configuration["JwtBearer:Issuer"],
claims: claims,
expires: DateTime.UtcNow.AddDays(Convert.ToDouble(_configuration["JwtBearer:TokenExpiration"])),
expires: GetTokenExpirationDays(),
signingCredentials: signingCredentials
);

return tokenOptions;
}

public DateTime GetTokenExpirationDays() => DateTime.UtcNow.AddDays(Convert.ToDouble(_configuration["JwtBearer:TokenExpiration"]));
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore;
using Domain.Models;
using System.Net;

namespace Infrastructure.Interceptors;

Expand Down
26 changes: 14 additions & 12 deletions src/Presentation/Configurations/ServiceCollections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public static void RegisterGeneralAppServices(IServiceCollection services)
{
services.AddControllers();
services.AddEndpointsApiExplorer();
services.AddAuthorization();
services.AddMemoryCache();
}

Expand Down Expand Up @@ -51,6 +50,7 @@ public static void RegisterAuthenticationServices(IServiceCollection services, A
ValidateIssuerSigningKey = true
};
});
services.AddAuthorization();
}


Expand Down Expand Up @@ -106,22 +106,24 @@ public static void RegisterSwaggerServices(IServiceCollection services) =>
});

public static void RegisterAutoMapper(IServiceCollection services) =>
services.AddSingleton(_ => new MapperConfiguration(cfg =>
services.AddSingleton(_ => new MapperConfiguration(m =>
{
cfg.CreateMap<Book, BookDto>().ReverseMap();
cfg.CreateMap<Book, BookWriteDto>().ReverseMap();
m.CreateMap<Book, BookDto>().ReverseMap();
m.CreateMap<Book, BookWriteDto>().ReverseMap();
m.CreateMap<BookCategory, BookCategoryDto>().ReverseMap();
m.CreateMap<BookCategory, BookCategoryWriteDto>().ReverseMap();
cfg.CreateMap<BookCategory, BookCategoryDto>().ReverseMap();
cfg.CreateMap<BookCategory, BookCategoryWriteDto>().ReverseMap();
m.CreateMap<Category, CategoryDto>().ReverseMap();
m.CreateMap<Category, CategoryWriteDto>().ReverseMap();
cfg.CreateMap<Category, CategoryDto>().ReverseMap();
cfg.CreateMap<Category, CategoryWriteDto>().ReverseMap();
m.CreateMap<OrderDetail, OrderDetailDto>().ReverseMap();
m.CreateMap<OrderDetail, OrderDetailWriteDto>().ReverseMap();
cfg.CreateMap<OrderDetail, OrderDetailDto>().ReverseMap();
cfg.CreateMap<OrderDetail, OrderDetailWriteDto>().ReverseMap();
m.CreateMap<Order, OrderDto>().ReverseMap();
m.CreateMap<Order, OrderWriteDto>().ReverseMap();
cfg.CreateMap<Order, OrderDto>().ReverseMap();
cfg.CreateMap<Order, OrderWriteDto>().ReverseMap();
m.CreateMap<User, UserSignupDto>().ReverseMap();
}).CreateMapper());

public static void RegisterSerilogServices(IServiceCollection services, ConfigureHostBuilder hostBuilder, string connectionString)
Expand Down
104 changes: 78 additions & 26 deletions src/Presentation/Controllers/UserController.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,89 @@
using System.Security.Claims;
using Application.DTOs;
using Application.Services;
using AutoMapper;
using Domain.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace Presentation.Controllers;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
//private readonly UserManager<User> _userManager;
//private readonly RoleManager<IdentityRole> _roleManager;
//private readonly IConfiguration _configuration;

//public UserController(UserManager<User> userManager, RoleManager<IdentityRole> roleManager, IConfiguration configuration)
//{
// _userManager = userManager;
// _roleManager = roleManager;
// _configuration = configuration;
//}

//[HttpGet("me")]
//public async Task<IActionResult> GetCurrentUser()
//{
// var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
// var user = await _userManager.FindByIdAsync(userId!);

// if (user == null)
// {
// return NotFound();
// }

// // Return user data
// return Ok(user);
//}
private readonly UserManager<User> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly IAuthenticationService _authenticationService;
private readonly IMapper _mapper;

public UserController(UserManager<User> userManager, RoleManager<IdentityRole> roleManager, IAuthenticationService authenticationService, IMapper mapper)
{
_userManager = userManager;
_roleManager = roleManager;
_authenticationService = authenticationService;
_mapper = mapper;
}

[HttpGet("me")]
public async Task<IActionResult> GetCurrentUser()
{
var username = User.Identity!.Name;
var user = await _userManager.FindByNameAsync(username!);

if (user == null)
{
return NotFound();
}

// Return user data
return Ok(user);
}

[HttpPost("login")]
[AllowAnonymous]
public async Task<ActionResult> Login([FromBody] UserLoginDto userLoginDto)
{
var user = await _userManager.FindByNameAsync(userLoginDto.UserName);
if (user != null && await _userManager.CheckPasswordAsync(user, userLoginDto.Password))
{
return Ok(new
{
token = await _authenticationService.GenerateJwtToken(user),
expiration = _authenticationService.GetTokenExpirationDays()
});
}
return Unauthorized();
}

[HttpPost("signup")]
[AllowAnonymous]
public async Task<ActionResult> SignUp([FromBody] UserSignupDto userSignupDto)
{
try
{
var userExists = await _userManager.FindByNameAsync(userSignupDto.UserName);
if (userExists != null)
return Conflict("User already exists!");

var user = _mapper.Map<User>(userSignupDto);

var result = await _userManager.CreateAsync(user, userSignupDto.Password);

// if (!await _roleManager.RoleExistsAsync(UserRole.Customer))
// await _roleManager.CreateAsync(new IdentityRole(UserRole.Customer));

// await _userManager.AddToRoleAsync(user, UserRole.Customer);

if (!result.Succeeded)
return UnprocessableEntity("User creation failed! Please check user details and try again.");

return Ok("User created successfully!");
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
}
8 changes: 4 additions & 4 deletions src/Presentation/Middlewares/LoggingMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Serilog;
using System.Diagnostics;
using System.Security.Claims;
using System.Text;

namespace Presentation.Middlewares;
Expand Down Expand Up @@ -35,15 +34,16 @@ public async Task Invoke(HttpContext context)
var request = context.Request;
var ipAddress = context.Connection.RemoteIpAddress?.ToString();
var userAgent = request.Headers["User-Agent"].ToString();
var user = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
// var user = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = context.User.Identity!.Name;

if (context.Request.Method is "PUT" or "PATCH" or "DELETE")
Log.Information("HTTP {RequestMethod} {RequestPath} received from {IpAddress} ({UserAgent}), " +
"Username {user}, Request Body: {requestBody}",
"Username: {user}, Request Body: {requestBody}",
request.Method, request.Path, ipAddress, userAgent, user, requestBody);
else
Log.Information("HTTP {RequestMethod} {RequestPath} received from {IpAddress} ({UserAgent}), " +
"Username {user}",
"Username: {user}",
request.Method, request.Path, ipAddress, userAgent, user);

stopwatch.Stop();
Expand Down
8 changes: 4 additions & 4 deletions src/Presentation/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
var config = builder.Configuration.Get<AppSettings>();

ServiceCollections.RegisterGeneralAppServices(builder.Services);
ServiceCollections.RegisterAutoMapper(builder.Services);
ServiceCollections.RegisterSwaggerServices(builder.Services);
ServiceCollections.RegisterRepositories(builder.Services);
ServiceCollections.RegisterApplicationServices(builder.Services);
ServiceCollections.RegisterAuthenticationServices(builder.Services, config);
ServiceCollections.RegisterDatabaseServices(builder, config!.ConnectionStrings.DefaultConnection);
ServiceCollections.RegisterRedisCache(builder.Services, config);
ServiceCollections.RegisterApplicationServices(builder.Services);
ServiceCollections.RegisterRepositories(builder.Services);
ServiceCollections.RegisterSwaggerServices(builder.Services);
ServiceCollections.RegisterAutoMapper(builder.Services);
ServiceCollections.RegisterSerilogServices(builder.Services, builder.Host, config.ConnectionStrings.DefaultConnection);

var app = builder.Build();
Expand Down
1 change: 1 addition & 0 deletions src/Presentation/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"JwtBearer:Key": "This is a sample secret key - please don't use in production environment.",
"JwtBearer:Issuer": "BookStore",
"JwtBearer:Audience": "https://localhost:5000",
"JwtBearer:TokenExpiration" : 5,
"ConnectionStrings:DefaultConnection": "Host=postgres;Port=5432;Database=book_store_db;Username=postgres;Password=password;",
"BaseUrl": "https://localhost:5000",
"AllowedHosts": "*",
Expand Down

0 comments on commit e328813

Please sign in to comment.