Moved Role Assignment from User to UserRoles
This commit is contained in:
parent
dc3fb100b1
commit
ebd07204b3
@ -32,14 +32,14 @@ namespace UserManagement.API.Controllers
|
||||
var user = await _userService.GetByUsernameAsync(login.Username, includeRoles: true);
|
||||
if (user is null)
|
||||
{
|
||||
return Unauthorized();
|
||||
return Unauthorized("Benutzername und Passwort stimmen nicht überein!");
|
||||
}
|
||||
|
||||
// Validate login credentials
|
||||
var isValid = await _authService.ValidateAsync(login.Username, login.Password);
|
||||
if (!isValid)
|
||||
{
|
||||
return Unauthorized();
|
||||
return Unauthorized("Benutzername und Passwort stimmen nicht überein!");
|
||||
}
|
||||
|
||||
// Create claims based on the user information
|
||||
|
||||
@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using UserManagement.Application.Dtos.Incomming;
|
||||
using UserManagement.Application.Interfaces;
|
||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
|
||||
|
||||
namespace UserManagement.API.Controllers
|
||||
{
|
||||
|
||||
@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using UserManagement.Application.Dtos.Incomming;
|
||||
using UserManagement.Application.Interfaces;
|
||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
|
||||
|
||||
namespace UserManagement.API.Controllers
|
||||
{
|
||||
@ -14,9 +13,11 @@ namespace UserManagement.API.Controllers
|
||||
{
|
||||
// CTOR
|
||||
private readonly IUserService _userService;
|
||||
public UserController(IUserService userService)
|
||||
private readonly ILogger<UserController> _logger;
|
||||
public UserController(IUserService userService, ILogger<UserController> logger)
|
||||
{
|
||||
_userService = userService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
// CREATE
|
||||
@ -28,7 +29,6 @@ namespace UserManagement.API.Controllers
|
||||
[Authorize(Roles = "Admin")]
|
||||
public async Task<IActionResult> CreateUser([FromBody] CreatingUserDto creatingUserDto)
|
||||
{
|
||||
// Validate incomming model
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
@ -36,21 +36,15 @@ namespace UserManagement.API.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
// Try to add user asynchronously
|
||||
var result = await _userService.AddUserAsync(creatingUserDto);
|
||||
var createdUser = await _userService.AddUserAsync(creatingUserDto);
|
||||
|
||||
// If user is successfully created, return a CreatedAtAction response with the created resource
|
||||
if (result is not null)
|
||||
if (createdUser is not null)
|
||||
{
|
||||
var id = result.Id;
|
||||
var createdResource = new { Id = id };
|
||||
var actionName = nameof(GetUserById);
|
||||
var routeValue = new { id = createdResource.Id };
|
||||
return CreatedAtAction(actionName, routeValue, createdResource);
|
||||
return CreatedAtAction(nameof(GetUserById), new { id = createdUser.Id }, createdUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest("Creation failed");
|
||||
return BadRequest("Erstellung des Benutzers fehlgeschlagen!");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -63,10 +57,18 @@ namespace UserManagement.API.Controllers
|
||||
[HttpGet]
|
||||
[SwaggerOperation(Summary = "Get all Users")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> GetAllUsers([FromQuery] bool includeRoles = true)
|
||||
{
|
||||
var users = await _userService.GetUsersAsync(includeRoles);
|
||||
return Ok(users);
|
||||
try
|
||||
{
|
||||
var users = await _userService.GetUsersAsync(includeRoles);
|
||||
return Ok(users);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// READ BY ID
|
||||
@ -77,16 +79,19 @@ namespace UserManagement.API.Controllers
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> GetUserById(int id, [FromQuery] bool includeRoles = true)
|
||||
{
|
||||
if (id <= 0)
|
||||
try
|
||||
{
|
||||
return BadRequest("Invalid Id");
|
||||
var user = await _userService.GetByIdAsync(id, includeRoles);
|
||||
return Ok(user);
|
||||
}
|
||||
var user = await _userService.GetByIdAsync(id, includeRoles);
|
||||
if (user == null)
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return NotFound();
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
return Ok(user);
|
||||
}
|
||||
|
||||
// READ BY USERNAME
|
||||
@ -97,16 +102,19 @@ namespace UserManagement.API.Controllers
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> GetUserByUsername(string username, [FromQuery] bool includeRoles = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(username))
|
||||
try
|
||||
{
|
||||
return BadRequest("Username connot be empty");
|
||||
var user = await _userService.GetByUsernameAsync(username, includeRoles);
|
||||
return Ok(user);
|
||||
}
|
||||
var user = await _userService.GetByUsernameAsync(username, includeRoles);
|
||||
if (user == null)
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return NotFound();
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
return Ok(user);
|
||||
}
|
||||
|
||||
// READ BY ROLE
|
||||
@ -117,12 +125,19 @@ namespace UserManagement.API.Controllers
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> GetUsersByRole(string role)
|
||||
{
|
||||
if (string.IsNullOrEmpty(role))
|
||||
try
|
||||
{
|
||||
return BadRequest("Role cannot be empty");
|
||||
var users = await _userService.GetByRoleAsync(role);
|
||||
return Ok(users);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
var users = await _userService.GetByRoleAsync(role);
|
||||
return Ok(users);
|
||||
}
|
||||
|
||||
// UPDATE
|
||||
@ -130,21 +145,27 @@ namespace UserManagement.API.Controllers
|
||||
[SwaggerOperation(Summary = "Update User")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<IActionResult> UpdateUser(int id, UpdatingUserDto updatingUserDto)
|
||||
{
|
||||
if (id <= 0)
|
||||
try
|
||||
{
|
||||
return BadRequest("Invalid Id");
|
||||
var updated = await _userService.UpdateUserAsync(updatingUserDto);
|
||||
return Ok(updated);
|
||||
}
|
||||
|
||||
var updated = await _userService.UpdateUserAsync(updatingUserDto);
|
||||
|
||||
if (!updated)
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return BadRequest("Update failed");
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
|
||||
return Ok(updated);
|
||||
}
|
||||
|
||||
// DELETE
|
||||
@ -155,19 +176,19 @@ namespace UserManagement.API.Controllers
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> DeleteUser([FromBody] int id)
|
||||
{
|
||||
if (id <= 0)
|
||||
try
|
||||
{
|
||||
return BadRequest("Invalid Id");
|
||||
var deleted = await _userService.DeleteUserAsync(id);
|
||||
return Ok(deleted);
|
||||
}
|
||||
|
||||
var deleted = await _userService.DeleteUserAsync(id);
|
||||
|
||||
if (!deleted)
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return BadRequest("Deletion failed");
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
82
UserManagement.API/Controllers/UserRolesController.cs
Normal file
82
UserManagement.API/Controllers/UserRolesController.cs
Normal file
@ -0,0 +1,82 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using UserManagement.Application.Dtos.Incomming;
|
||||
using UserManagement.Application.Dtos.Outgoing;
|
||||
using UserManagement.Application.Interfaces;
|
||||
|
||||
namespace UserManagement.API.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class UserRolesController : Controller
|
||||
{
|
||||
// CTOR
|
||||
private readonly IUserRolesService _userRolesService;
|
||||
public UserRolesController(IUserRolesService userRolesService)
|
||||
{
|
||||
_userRolesService = userRolesService;
|
||||
}
|
||||
|
||||
// CREATE ASSIGNMENT
|
||||
[HttpPost("AssignRoleToUser")]
|
||||
[SwaggerOperation(Summary = "Assign Role to User the better way")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> CreateAssignmentAsync(CreatingUserRolesDto creatingUserRolesDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _userRolesService.CreateAssignmentAsync(creatingUserRolesDto);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return Ok("Rolle erfolgreich zugewiesen!");
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest("Zuweisen der Rolle fehlgeschlagen!");
|
||||
}
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// REMOVE ROLE FROM USER
|
||||
[HttpDelete("RemoveRoleFromUser")]
|
||||
[SwaggerOperation(Summary = "Remove Role from User")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> RemoveRoleFromUser(CreatingUserRolesDto creatingUserRolesDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _userRolesService.RemoveRoleFromUserAsync(creatingUserRolesDto);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return Ok("Rolle erfolgreich entfernt!");
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest("Entfernung der Rolle fehlgeschlagen!");
|
||||
}
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
146
UserManagement.API/Migrations/20240926093702_AddIdColumnToUserRoles.Designer.cs
generated
Normal file
146
UserManagement.API/Migrations/20240926093702_AddIdColumnToUserRoles.Designer.cs
generated
Normal file
@ -0,0 +1,146 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using UserManagement.Infrastructure;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace UserManagement.API.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20240926093702_AddIdColumnToUserRoles")]
|
||||
partial class AddIdColumnToUserRoles
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.8")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.Role", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("CREATION_DATE");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)")
|
||||
.HasColumnName("ROLE");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Roles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("FIRST_NAME");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("LAST_NAME");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("PASSWORD_HASH");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)")
|
||||
.HasColumnName("USER_NAME");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserName")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.UserRoles", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("USER_ID");
|
||||
|
||||
b.Property<int>("RoleId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ROLE_ID");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("UserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.UserRoles", b =>
|
||||
{
|
||||
b.HasOne("UserManagement.Domain.Entities.Role", "Role")
|
||||
.WithMany("UserRoles")
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("UserManagement.Domain.Entities.User", "User")
|
||||
.WithMany("UserRoles")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Role");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.Role", b =>
|
||||
{
|
||||
b.Navigation("UserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.User", b =>
|
||||
{
|
||||
b.Navigation("UserRoles");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace UserManagement.API.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddIdColumnToUserRoles : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "ID",
|
||||
table: "UserRoles",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0)
|
||||
.Annotation("SqlServer:Identity", "1, 1");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ID",
|
||||
table: "UserRoles");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@ namespace UserManagement.API.Migrations
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.UserRole", b =>
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.UserRoles", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("int")
|
||||
@ -95,6 +95,13 @@ namespace UserManagement.API.Migrations
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ROLE_ID");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
@ -102,7 +109,7 @@ namespace UserManagement.API.Migrations
|
||||
b.ToTable("UserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.UserRole", b =>
|
||||
modelBuilder.Entity("UserManagement.Domain.Entities.UserRoles", b =>
|
||||
{
|
||||
b.HasOne("UserManagement.Domain.Entities.Role", "Role")
|
||||
.WithMany("UserRoles")
|
||||
|
||||
@ -18,11 +18,14 @@ builder.Services.AddSwaggerGen(s => s.EnableAnnotations());
|
||||
|
||||
builder.Services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
||||
|
||||
builder.Services.AddScoped<IRoleService, RoleService>();
|
||||
builder.Services.AddScoped<IRoleRepository, RoleRepository>();
|
||||
|
||||
builder.Services.AddScoped<IUserService, UserService>();
|
||||
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||
|
||||
builder.Services.AddScoped<IRoleService, RoleService>();
|
||||
builder.Services.AddScoped<IRoleRepository, RoleRepository>();
|
||||
builder.Services.AddScoped<IUserRolesService, UserRolesService>();
|
||||
builder.Services.AddScoped<IUserRolesRepository, UserRolesRepository>();
|
||||
|
||||
builder.Services.AddScoped<IAuthService, AuthService>();
|
||||
|
||||
|
||||
15
UserManagement.API/user-by-role.sql
Normal file
15
UserManagement.API/user-by-role.sql
Normal file
@ -0,0 +1,15 @@
|
||||
DECLARE @__role_0 nvarchar(450) = N'admin';
|
||||
|
||||
SELECT [u].[ID], [u].[FIRST_NAME], [u].[LAST_NAME], [u].[PASSWORD_HASH], [u].[USER_NAME], [t].[USER_ID], [t].[ROLE_ID], [t].[ID], [t].[CREATION_DATE], [t].[ROLE]
|
||||
FROM [Users] AS [u]
|
||||
LEFT JOIN (
|
||||
SELECT [u1].[USER_ID], [u1].[ROLE_ID], [r0].[ID], [r0].[CREATION_DATE], [r0].[ROLE]
|
||||
FROM [UserRoles] AS [u1]
|
||||
INNER JOIN [Roles] AS [r0] ON [u1].[ROLE_ID] = [r0].[ID]
|
||||
) AS [t] ON [u].[ID] = [t].[USER_ID]
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM [UserRoles] AS [u0]
|
||||
INNER JOIN [Roles] AS [r] ON [u0].[ROLE_ID] = [r].[ID]
|
||||
WHERE [u].[ID] = [u0].[USER_ID] AND [r].[ROLE] = @__role_0)
|
||||
ORDER BY [u].[ID], [t].[USER_ID], [t].[ROLE_ID]
|
||||
@ -1,6 +1,4 @@
|
||||
using UserManagement.Application.Dtos.Outgoing;
|
||||
|
||||
namespace UserManagement.Application.Dtos.Incomming
|
||||
namespace UserManagement.Application.Dtos.Incomming
|
||||
{
|
||||
public class CreatingUserDto
|
||||
{
|
||||
@ -11,7 +9,5 @@ namespace UserManagement.Application.Dtos.Incomming
|
||||
public string LastName { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
public ICollection<int> RoleIds { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
namespace UserManagement.Application.Dtos.Incomming
|
||||
{
|
||||
public class CreatingUserRolesDto
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
public int RoleId { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
namespace UserManagement.Application.Dtos.Incomming
|
||||
using UserManagement.Domain.Entities;
|
||||
|
||||
namespace UserManagement.Application.Dtos.Incomming
|
||||
{
|
||||
public class UpdatingUserDto
|
||||
{
|
||||
@ -11,7 +13,5 @@
|
||||
public string LastName { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
public ICollection<int> RoleIds { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
namespace UserManagement.Application.Dtos.Incomming
|
||||
{
|
||||
public class UpdatingUserRolesDto
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
public int RoleId { get; set; }
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,10 @@
|
||||
{
|
||||
public class ReadingUserRolesDto
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
|
||||
public string UserName { get; set; }
|
||||
|
||||
public int RoleId { get; set; }
|
||||
|
||||
public string RoleName { get; set; }
|
||||
|
||||
14
UserManagement.App/Interfaces/IUserRolesService.cs
Normal file
14
UserManagement.App/Interfaces/IUserRolesService.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using UserManagement.Application.Dtos.Incomming;
|
||||
using UserManagement.Application.Dtos.Outgoing;
|
||||
|
||||
namespace UserManagement.Application.Interfaces
|
||||
{
|
||||
public interface IUserRolesService
|
||||
{
|
||||
// CREATE ASSIGNMENT
|
||||
Task<bool> CreateAssignmentAsync(CreatingUserRolesDto creatingUserRolesDto);
|
||||
|
||||
// REMOVE ROLE FORM USER
|
||||
Task<bool> RemoveRoleFromUserAsync(CreatingUserRolesDto creatingUserRolesDto);
|
||||
}
|
||||
}
|
||||
@ -11,23 +11,18 @@ namespace UserManagement.Application.MappingProfiles
|
||||
{
|
||||
// ROLE
|
||||
CreateMap<Role, CreatingRoleDto>().ReverseMap();
|
||||
|
||||
CreateMap<Role, ReadingRoleDto>().ReverseMap();
|
||||
|
||||
CreateMap<Role, UpdatingRoleDto>().ReverseMap();
|
||||
|
||||
// USER ROLES
|
||||
CreateMap<UserRoles, CreatingUserRolesDto>().ReverseMap();
|
||||
CreateMap<UserRoles, ReadingUserRolesDto>().ReverseMap();
|
||||
|
||||
// USER
|
||||
CreateMap<User, CreatingUserDto>()
|
||||
.ForMember(dest => dest.RoleIds, opt => opt.Ignore())
|
||||
.ReverseMap()
|
||||
.AfterMap((src, dest) =>
|
||||
{
|
||||
dest.UserRoles = src.RoleIds?.Select(roleId => new UserRole
|
||||
{
|
||||
RoleId = roleId,
|
||||
User = dest
|
||||
}).ToList();
|
||||
|
||||
dest.PasswordHash = BCrypt.Net.BCrypt.HashPassword(src.Password);
|
||||
});
|
||||
|
||||
@ -40,16 +35,9 @@ namespace UserManagement.Application.MappingProfiles
|
||||
}).ToList()));
|
||||
|
||||
CreateMap<User, UpdatingUserDto>()
|
||||
.ForMember(dest => dest.RoleIds, opt => opt.Ignore())
|
||||
.ReverseMap()
|
||||
.AfterMap((src, dest) =>
|
||||
{
|
||||
dest.UserRoles = src.RoleIds?.Select(roleId => new UserRole
|
||||
{
|
||||
RoleId = roleId,
|
||||
UserId = dest.Id
|
||||
}).ToList();
|
||||
|
||||
dest.PasswordHash = BCrypt.Net.BCrypt.HashPassword(src.Password);
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ namespace UserManagement.Application.Services
|
||||
public class AuthService : IAuthService
|
||||
{
|
||||
// CTOR
|
||||
private IUserRepository _userRepository;
|
||||
private readonly IUserRepository _userRepository;
|
||||
public AuthService(IUserRepository userRepository)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
|
||||
119
UserManagement.App/Services/UserRolesService.cs
Normal file
119
UserManagement.App/Services/UserRolesService.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using AutoMapper;
|
||||
using UserManagement.Application.Dtos.Incomming;
|
||||
using UserManagement.Application.Dtos.Outgoing;
|
||||
using UserManagement.Application.Interfaces;
|
||||
using UserManagement.Domain.Entities;
|
||||
using UserManagement.Infrastructure.Interfaces;
|
||||
|
||||
namespace UserManagement.Application.Services
|
||||
{
|
||||
public class UserRolesService : IUserRolesService
|
||||
{
|
||||
// CTOR
|
||||
private readonly IUserRolesRepository _userRolesRepository;
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IRoleRepository _roleRepository;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public UserRolesService(IUserRolesRepository userRolesRepository, IUserRepository userRepository, IRoleRepository roleRepository, IMapper mapper)
|
||||
{
|
||||
_userRolesRepository = userRolesRepository;
|
||||
_userRepository = userRepository;
|
||||
_roleRepository = roleRepository;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
// CREATE ASSIGNMENT
|
||||
public async Task<bool> CreateAssignmentAsync(CreatingUserRolesDto creatingUserRolesDto)
|
||||
{
|
||||
if (creatingUserRolesDto.UserId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Ungültige Id!");
|
||||
}
|
||||
|
||||
var user = await _userRepository.GetByIdAsync(creatingUserRolesDto.UserId);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Benutzer nicht gefunden!");
|
||||
}
|
||||
|
||||
if (creatingUserRolesDto.RoleId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Ungültige Id!");
|
||||
}
|
||||
|
||||
var role = await _roleRepository.GetByIdAsync(creatingUserRolesDto.RoleId);
|
||||
|
||||
if (role == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Rolle nicht gefunden!");
|
||||
}
|
||||
|
||||
var userRoles = _mapper.Map<UserRoles>(creatingUserRolesDto);
|
||||
|
||||
var assigned = await _userRolesRepository.CreateAssignmentAsync(userRoles);
|
||||
|
||||
return assigned;
|
||||
}
|
||||
|
||||
//// ASSIGNING ROLES BY NAMES
|
||||
//public async Task<bool> AssignAsync(string username, string roleName)
|
||||
//{
|
||||
// var user = await _userRepository.GetByUsernameAsync(username);
|
||||
// var role = await _roleRepository.GetByNameAsync(roleName);
|
||||
|
||||
// if (user is null || role is null)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// var dto = new CreatingUserRolesDto()
|
||||
// {
|
||||
// RoleId = role.Id,
|
||||
// UserId = user.Id
|
||||
// };
|
||||
|
||||
// return await CreateAssignmentAsync(dto);
|
||||
//}
|
||||
|
||||
// REMOVE ROLE FROM USER
|
||||
public async Task<bool> RemoveRoleFromUserAsync(CreatingUserRolesDto creatingUserRolesDto)
|
||||
{
|
||||
if (creatingUserRolesDto.UserId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Ungültige Id!");
|
||||
}
|
||||
|
||||
var user = await _userRepository.GetByIdAsync(creatingUserRolesDto.UserId);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Benutzer nicht gefunden!");
|
||||
}
|
||||
|
||||
if (creatingUserRolesDto.RoleId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Ungültige Id!");
|
||||
}
|
||||
|
||||
var role = await _roleRepository.GetByIdAsync(creatingUserRolesDto.RoleId);
|
||||
|
||||
if (role == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Rolle nicht gefunden!");
|
||||
}
|
||||
|
||||
var userRole = _mapper.Map<UserRoles>(creatingUserRolesDto);
|
||||
|
||||
if (userRole == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Die Rolle ist dem Benutzer nicht zugewiesen!");
|
||||
}
|
||||
|
||||
var result = await _userRolesRepository.DeleteAssignmentAsync(userRole);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -30,22 +30,8 @@ namespace UserManagement.Application.Services
|
||||
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(creatingUserDto.Password);
|
||||
}
|
||||
|
||||
user.UserRoles = new List<UserRole>();
|
||||
|
||||
foreach (var roleId in creatingUserDto.RoleIds)
|
||||
{
|
||||
var role = await _roleRepository.GetByIdAsync(roleId);
|
||||
if (role is not null)
|
||||
{
|
||||
user.UserRoles.Add(new UserRole { UserId = user.Id, RoleId = role.Id });
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Role with Id {roleId} not found");
|
||||
}
|
||||
}
|
||||
|
||||
var created = await _userRepository.AddAsync(user);
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
@ -53,42 +39,90 @@ namespace UserManagement.Application.Services
|
||||
public async Task<IEnumerable<ReadingUserDto>> GetUsersAsync(bool includeRoles = true)
|
||||
{
|
||||
var users = await _userRepository.GetAllAsync(includeRoles);
|
||||
|
||||
if (users == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Keine Benutzer gefunden!");
|
||||
}
|
||||
|
||||
var readDto = _mapper.Map<IEnumerable<ReadingUserDto>>(users);
|
||||
|
||||
return readDto;
|
||||
}
|
||||
|
||||
// READ BY ID
|
||||
public async Task<ReadingUserDto> GetByIdAsync(int id, bool includeRoles = true)
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
throw new ArgumentException("Ungültige Id!");
|
||||
}
|
||||
|
||||
var user = await _userRepository.GetByIdAsync(id, includeRoles);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Benutzer nicht gefunden!");
|
||||
}
|
||||
|
||||
var readDto = _mapper.Map<ReadingUserDto>(user);
|
||||
|
||||
return readDto;
|
||||
}
|
||||
|
||||
// READ BY USERNAME
|
||||
public async Task<ReadingUserDto> GetByUsernameAsync(string username, bool includeRoles = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(username))
|
||||
{
|
||||
throw new ArgumentException("Ungültiger Benutzername!");
|
||||
}
|
||||
|
||||
var user = await _userRepository.GetByUsernameAsync(username, includeRoles);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Benutzer nicht gefunden!");
|
||||
}
|
||||
|
||||
var readDto = _mapper.Map<ReadingUserDto>(user);
|
||||
|
||||
return readDto;
|
||||
}
|
||||
|
||||
// READ BY ROLE
|
||||
public async Task<IEnumerable<ReadingUserDto>> GetByRoleAsync(string role)
|
||||
{
|
||||
if (string.IsNullOrEmpty(role))
|
||||
{
|
||||
throw new ArgumentException("Ungültige Rolle!");
|
||||
}
|
||||
|
||||
var users = await _userRepository.GetByRoleAsync(role);
|
||||
|
||||
if (users == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Keine Benutzer in dieser Rolle gefunden!");
|
||||
}
|
||||
|
||||
var readDto = _mapper.Map<IEnumerable<ReadingUserDto>>(users);
|
||||
|
||||
return readDto;
|
||||
}
|
||||
|
||||
// UPDATE
|
||||
public async Task<bool> UpdateUserAsync(UpdatingUserDto updatingUserDto)
|
||||
{
|
||||
if (updatingUserDto.Id <= 0)
|
||||
{
|
||||
throw new ArgumentException("Ungültige Id!");
|
||||
}
|
||||
|
||||
var user = await _userRepository.GetByIdAsync(updatingUserDto.Id);
|
||||
|
||||
if (user is null)
|
||||
if (user == null)
|
||||
{
|
||||
return false;
|
||||
throw new KeyNotFoundException("Benutzer nicht gefunden!");
|
||||
}
|
||||
|
||||
_mapper.Map(updatingUserDto, user);
|
||||
@ -98,34 +132,28 @@ namespace UserManagement.Application.Services
|
||||
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(updatingUserDto.Password);
|
||||
}
|
||||
|
||||
user.UserRoles!.Clear();
|
||||
|
||||
foreach(var roleId in updatingUserDto.RoleIds)
|
||||
{
|
||||
var role = await _roleRepository.GetByIdAsync(roleId);
|
||||
if (role is not null)
|
||||
{
|
||||
user.UserRoles.Add(new UserRole { UserId = user.Id, RoleId = role.Id });
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Role with Id {roleId} not found");
|
||||
}
|
||||
}
|
||||
|
||||
bool isUpdated = await _userRepository.UpdateAsync(user);
|
||||
|
||||
return isUpdated;
|
||||
}
|
||||
|
||||
// DELETE
|
||||
public async Task<bool> DeleteUserAsync(int id)
|
||||
{
|
||||
User? user = await _userRepository.GetByIdAsync(id);
|
||||
if (id <= 0)
|
||||
{
|
||||
throw new ArgumentException("Ungültige Id!");
|
||||
}
|
||||
|
||||
if (user is null)
|
||||
return false;
|
||||
var user = await _userRepository.GetByIdAsync(id);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new KeyNotFoundException("Benutzer nicht gefunden!");
|
||||
}
|
||||
|
||||
bool isDeleted = await _userRepository.DeleteAsync(user);
|
||||
|
||||
return isDeleted;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace UserManagement.Domain.Entities
|
||||
@ -16,7 +15,7 @@ namespace UserManagement.Domain.Entities
|
||||
public required string Name { get; set; }
|
||||
|
||||
[Column("USERS")]
|
||||
public ICollection<UserRole>? UserRoles { get; set; } = new Collection<UserRole>();
|
||||
public ICollection<UserRoles>? UserRoles { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("CREATION_DATE", TypeName = "datetime")]
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace UserManagement.Domain.Entities
|
||||
@ -27,6 +26,6 @@ namespace UserManagement.Domain.Entities
|
||||
[Column("PASSWORD_HASH")]
|
||||
public required string PasswordHash { get; set; }
|
||||
|
||||
public ICollection<UserRole>? UserRoles { get; set; } = new Collection<UserRole>();
|
||||
public ICollection<UserRoles>? UserRoles { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,15 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace UserManagement.Domain.Entities
|
||||
{
|
||||
public class UserRole
|
||||
public class UserRoles
|
||||
{
|
||||
[Column("ID")]
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("USER_ID")]
|
||||
public int UserId { get; set; }
|
||||
|
||||
@ -12,7 +12,7 @@ namespace UserManagement.Infrastructure
|
||||
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<Role> Roles { get; set; }
|
||||
public DbSet<UserRole> UserRoles { get; set; }
|
||||
public DbSet<UserRoles> UserRoles { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@ -26,15 +26,15 @@ namespace UserManagement.Infrastructure
|
||||
.HasIndex(r => r.Name)
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<UserRole>()
|
||||
modelBuilder.Entity<UserRoles>()
|
||||
.HasKey(ur => new { ur.UserId, ur.RoleId });
|
||||
|
||||
modelBuilder.Entity<UserRole>()
|
||||
modelBuilder.Entity<UserRoles>()
|
||||
.HasOne(ur => ur.User)
|
||||
.WithMany(u => u.UserRoles)
|
||||
.HasForeignKey(ur => ur.UserId);
|
||||
|
||||
modelBuilder.Entity<UserRole>()
|
||||
modelBuilder.Entity<UserRoles>()
|
||||
.HasOne(ur => ur.Role)
|
||||
.WithMany(r => r.UserRoles)
|
||||
.HasForeignKey(ur => ur.RoleId);
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
using UserManagement.Domain.Entities;
|
||||
|
||||
namespace UserManagement.Infrastructure.Interfaces
|
||||
{
|
||||
public interface IUserRolesRepository
|
||||
{
|
||||
// CREATE ASSIGNMENT
|
||||
Task<bool> CreateAssignmentAsync(UserRoles userRoles);
|
||||
|
||||
// DELETE ASSIGNMENT
|
||||
Task<bool> DeleteAssignmentAsync(UserRoles userRoles);
|
||||
}
|
||||
}
|
||||
@ -63,11 +63,14 @@ namespace UserManagement.Infrastructure.Repositories
|
||||
// READ BY ROLE
|
||||
public async Task<IEnumerable<User>> GetByRoleAsync(string role)
|
||||
{
|
||||
return await _context.Users
|
||||
var query = _context.Users
|
||||
.Include(u => u.UserRoles)!
|
||||
.ThenInclude(ur => ur.Role)
|
||||
.Where(ur => ur.UserRoles!.Any(r => r.Role!.Name == role))
|
||||
.ToListAsync();
|
||||
.Where(ur => ur.UserRoles!.Any(r => r.Role!.Name == role));
|
||||
|
||||
var sql = query.ToQueryString();
|
||||
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
// UPDATE
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using UserManagement.Domain.Entities;
|
||||
using UserManagement.Infrastructure.Interfaces;
|
||||
|
||||
namespace UserManagement.Infrastructure.Repositories
|
||||
{
|
||||
public class UserRolesRepository : IUserRolesRepository
|
||||
{
|
||||
// CTOR
|
||||
private readonly ApplicationDbContext _context;
|
||||
public UserRolesRepository(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// CREATE ASSIGNMENT
|
||||
public async Task<bool> CreateAssignmentAsync(UserRoles userRoles)
|
||||
{
|
||||
await _context.UserRoles.AddAsync(userRoles);
|
||||
var results = await _context.SaveChangesAsync();
|
||||
return results > 0;
|
||||
}
|
||||
|
||||
// DELETE ASSIGNMENT
|
||||
public async Task<bool> DeleteAssignmentAsync(UserRoles userRoles)
|
||||
{
|
||||
_context.UserRoles.Remove(userRoles);
|
||||
var result = await _context.SaveChangesAsync();
|
||||
return result > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user