Add UserRole handling
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Imprink.Domain.Repositories;
|
||||
using Imprink.Domain.Repositories.Products;
|
||||
using Imprink.Domain.Repositories.Users;
|
||||
|
||||
namespace Imprink.Application;
|
||||
|
||||
|
||||
7
src/Imprink.Application/Users/Dtos/RoleDto.cs
Normal file
7
src/Imprink.Application/Users/Dtos/RoleDto.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Imprink.Application.Users.Dtos;
|
||||
|
||||
public class RoleDto
|
||||
{
|
||||
public required Guid RoleId { get; set; }
|
||||
public required string RoleName { get; set; }
|
||||
}
|
||||
7
src/Imprink.Application/Users/Dtos/UserRoleDto.cs
Normal file
7
src/Imprink.Application/Users/Dtos/UserRoleDto.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Imprink.Application.Users.Dtos;
|
||||
|
||||
public class UserRoleDto
|
||||
{
|
||||
public required string UserId { get; set; }
|
||||
public required Guid RoleId { get; set; }
|
||||
}
|
||||
@@ -1,15 +1,22 @@
|
||||
using Imprink.Domain.Entities.Users;
|
||||
using Imprink.Application.Users.Dtos;
|
||||
using MediatR;
|
||||
|
||||
namespace Imprink.Application.Users;
|
||||
|
||||
public record GetUserRolesCommand(string Sub) : IRequest<IEnumerable<Role>>;
|
||||
public record GetUserRolesCommand(string Sub) : IRequest<IEnumerable<RoleDto>>;
|
||||
|
||||
public class GetUserRolesHandler(IUnitOfWork uw): IRequestHandler<GetUserRolesCommand, IEnumerable<Role>>
|
||||
public class GetUserRolesHandler(IUnitOfWork uw): IRequestHandler<GetUserRolesCommand, IEnumerable<RoleDto>>
|
||||
{
|
||||
public async Task<IEnumerable<Role>> Handle(GetUserRolesCommand request, CancellationToken cancellationToken)
|
||||
public async Task<IEnumerable<RoleDto>> Handle(GetUserRolesCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await uw.UserRepository.UserExistsAsync(request.Sub, cancellationToken)) return [];
|
||||
return await uw.UserRoleRepository.GetUserRolesAsync(request.Sub, cancellationToken);;
|
||||
if (!await uw.UserRepository.UserExistsAsync(request.Sub, cancellationToken)) return [];
|
||||
|
||||
var roles = await uw.UserRoleRepository.GetUserRolesAsync(request.Sub, cancellationToken);
|
||||
|
||||
return roles.Select(role => new RoleDto
|
||||
{
|
||||
RoleId = role.Id,
|
||||
RoleName = role.RoleName
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using Imprink.Domain.Entities.Users;
|
||||
using Imprink.Domain.Repositories;
|
||||
using MediatR;
|
||||
|
||||
namespace Imprink.Application.Users.Roles;
|
||||
|
||||
public record AddUserToRoleCommand(string UserId, Guid RoleId) : IRequest<bool>;
|
||||
|
||||
public class AddUserToRoleCommandHandler(
|
||||
IUserRoleRepository userRoleRepository,
|
||||
IRoleRepository roleRepository,
|
||||
IUserRepository userRepository)
|
||||
: IRequestHandler<AddUserToRoleCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(AddUserToRoleCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var userExists = await userRepository.UserExistsAsync(request.UserId, cancellationToken);
|
||||
if (!userExists)
|
||||
return false;
|
||||
|
||||
var roleExists = await roleRepository.RoleExistsAsync(request.RoleId, cancellationToken);
|
||||
if (!roleExists)
|
||||
return false;
|
||||
|
||||
var isAlreadyInRole = await userRoleRepository.IsUserInRoleAsync(request.UserId, request.RoleId, cancellationToken);
|
||||
if (isAlreadyInRole)
|
||||
return true;
|
||||
|
||||
var userRole = new UserRole
|
||||
{
|
||||
UserId = request.UserId,
|
||||
RoleId = request.RoleId
|
||||
};
|
||||
|
||||
await userRoleRepository.AddUserRoleAsync(userRole, cancellationToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using Imprink.Domain.Repositories;
|
||||
using MediatR;
|
||||
|
||||
namespace Imprink.Application.Users.Roles;
|
||||
|
||||
public record RemoveUserFromRoleCommand(string UserId, Guid RoleId) : IRequest<bool>;
|
||||
|
||||
public class RemoveUserFromRoleCommandHandler(
|
||||
IUserRoleRepository userRoleRepository,
|
||||
IRoleRepository roleRepository,
|
||||
IUserRepository userRepository)
|
||||
: IRequestHandler<RemoveUserFromRoleCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(RemoveUserFromRoleCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var userExists = await userRepository.UserExistsAsync(request.UserId, cancellationToken);
|
||||
if (!userExists)
|
||||
return false;
|
||||
|
||||
var roleExists = await roleRepository.RoleExistsAsync(request.RoleId, cancellationToken);
|
||||
if (!roleExists)
|
||||
return false;
|
||||
|
||||
var userRole = await userRoleRepository.GetUserRoleAsync(request.UserId, request.RoleId, cancellationToken);
|
||||
if (userRole == null)
|
||||
return true;
|
||||
|
||||
await userRoleRepository.RemoveUserRoleAsync(userRole, cancellationToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
29
src/Imprink.Application/Users/SetUserRoleHandler.cs
Normal file
29
src/Imprink.Application/Users/SetUserRoleHandler.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Imprink.Application.Users.Dtos;
|
||||
using Imprink.Domain.Entities.Users;
|
||||
using MediatR;
|
||||
|
||||
namespace Imprink.Application.Users;
|
||||
|
||||
public record SetUserRoleCommand(string Sub, Guid RoleId) : IRequest<UserRoleDto?>;
|
||||
|
||||
public class SetUserRoleHandler(IUnitOfWork uw) : IRequestHandler<SetUserRoleCommand, UserRoleDto?>
|
||||
{
|
||||
public async Task<UserRoleDto?> Handle(SetUserRoleCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!await uw.UserRepository.UserExistsAsync(request.Sub, cancellationToken)) return null;
|
||||
|
||||
var userRole = new UserRole
|
||||
{
|
||||
UserId = request.Sub,
|
||||
RoleId = request.RoleId
|
||||
};
|
||||
|
||||
var addedRole = await uw.UserRoleRepository.AddUserRoleAsync(userRole, cancellationToken);
|
||||
|
||||
return new UserRoleDto
|
||||
{
|
||||
UserId = addedRole.UserId,
|
||||
RoleId = addedRole.RoleId
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
using Imprink.Domain.Entities.Users;
|
||||
|
||||
namespace Imprink.Domain.Repositories;
|
||||
namespace Imprink.Domain.Repositories.Users;
|
||||
|
||||
public interface IUserRoleRepository
|
||||
{
|
||||
Task<IEnumerable<Role>> GetUserRolesAsync(string userId, CancellationToken cancellationToken = default);
|
||||
Task<IEnumerable<User>> GetUsersInRoleAsync(Guid roleId, CancellationToken cancellationToken = default);
|
||||
Task<bool> IsUserInRoleAsync(string userId, Guid roleId, CancellationToken cancellationToken = default);
|
||||
|
||||
Task<UserRole?> GetUserRoleAsync(string userId, Guid roleId, CancellationToken cancellationToken = default);
|
||||
Task AddUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default);
|
||||
Task RemoveUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default);
|
||||
Task<IEnumerable<UserRole>> GetUserRolesByUserIdAsync(string userId, CancellationToken cancellationToken = default);
|
||||
Task<UserRole> AddUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default);
|
||||
Task<UserRole> RemoveUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Imprink.Domain.Entities.Users;
|
||||
using Imprink.Domain.Repositories;
|
||||
using Imprink.Domain.Repositories.Users;
|
||||
using Imprink.Infrastructure.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
@@ -25,12 +26,6 @@ public class UserRoleRepository(ApplicationDbContext context) : IUserRoleReposit
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<bool> IsUserInRoleAsync(string userId, Guid roleId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await context.UserRole
|
||||
.AnyAsync(ur => ur.UserId == userId && ur.RoleId == roleId, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<UserRole?> GetUserRoleAsync(string userId, Guid roleId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await context.UserRole
|
||||
@@ -38,23 +33,17 @@ public class UserRoleRepository(ApplicationDbContext context) : IUserRoleReposit
|
||||
.FirstOrDefaultAsync(ur => ur.UserId == userId && ur.RoleId == roleId, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task AddUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default)
|
||||
public async Task<UserRole> AddUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default)
|
||||
{
|
||||
context.UserRole.Add(userRole);
|
||||
var ur = context.UserRole.Add(userRole);
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
return ur.Entity;
|
||||
}
|
||||
|
||||
public async Task RemoveUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default)
|
||||
public async Task<UserRole> RemoveUserRoleAsync(UserRole userRole, CancellationToken cancellationToken = default)
|
||||
{
|
||||
context.UserRole.Remove(userRole);
|
||||
var ur = context.UserRole.Remove(userRole);
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<UserRole>> GetUserRolesByUserIdAsync(string userId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await context.UserRole
|
||||
.AsNoTracking()
|
||||
.Where(ur => ur.UserId == userId)
|
||||
.ToListAsync(cancellationToken);
|
||||
return ur.Entity;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Imprink.Application;
|
||||
using Imprink.Domain.Repositories;
|
||||
using Imprink.Domain.Repositories.Products;
|
||||
using Imprink.Domain.Repositories.Users;
|
||||
using Imprink.Infrastructure.Database;
|
||||
|
||||
namespace Imprink.Infrastructure;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Security.Claims;
|
||||
using Imprink.Application.Users;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Imprink.WebApi.Controllers.Users;
|
||||
@@ -9,7 +10,7 @@ namespace Imprink.WebApi.Controllers.Users;
|
||||
[Route("/api/users/roles")]
|
||||
public class UserRoleController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
//[Authorize]
|
||||
[Authorize]
|
||||
[HttpGet("me")]
|
||||
public async Task<IActionResult> GetMyRoles()
|
||||
{
|
||||
@@ -20,4 +21,16 @@ public class UserRoleController(IMediator mediator) : ControllerBase
|
||||
|
||||
return Ok(myRoles);
|
||||
}
|
||||
|
||||
[Authorize(Roles = "Admin")]
|
||||
[HttpPost("set")]
|
||||
public async Task<IActionResult> SetUserRole(SetUserRoleCommand command)
|
||||
{
|
||||
var userRole = await mediator.Send(command);
|
||||
|
||||
if (userRole == null)
|
||||
return BadRequest();
|
||||
|
||||
return Ok(userRole);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using Imprink.Application.Products.Create;
|
||||
using Imprink.Application.Validation.Models;
|
||||
using Imprink.Domain.Repositories;
|
||||
using Imprink.Domain.Repositories.Products;
|
||||
using Imprink.Domain.Repositories.Users;
|
||||
using Imprink.Infrastructure;
|
||||
using Imprink.Infrastructure.Database;
|
||||
using Imprink.Infrastructure.Repositories.Products;
|
||||
@@ -74,6 +75,7 @@ public static class Startup
|
||||
|
||||
foreach (var role in roles) identity!.AddClaim(new Claim(ClaimTypes.Role, role));
|
||||
identity!.AddClaim(new Claim(ClaimTypes.Role, "User"));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
@@ -99,8 +101,9 @@ public static class Startup
|
||||
Description = "JWT Authorization header using the Bearer scheme.",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Scheme = "Bearer"
|
||||
Type = SecuritySchemeType.Http,
|
||||
Scheme = "Bearer",
|
||||
BearerFormat = "JWT"
|
||||
});
|
||||
|
||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
@@ -112,12 +115,9 @@ public static class Startup
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
},
|
||||
Scheme = "Bearer",
|
||||
Name = "Bearer",
|
||||
In = ParameterLocation.Header
|
||||
}
|
||||
},
|
||||
new List<string>()
|
||||
[]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user