user service with editing, removing and reading accounts methods, controller actions for this service

This commit is contained in:
2024-08-22 00:23:02 +03:00
parent d1d3a1ab73
commit 85bac2b0a4
8 changed files with 140 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
using ApplicationLayer.Services.AuthServices.LoginService; using ApplicationLayer.Services.ApprovingAuthorities;
using ApplicationLayer.Services.AuthServices.LoginService;
using ApplicationLayer.Services.AuthServices.RegisterService; using ApplicationLayer.Services.AuthServices.RegisterService;
using ApplicationLayer.Services.VisaApplications.Handlers; using ApplicationLayer.Services.VisaApplications.Handlers;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -14,6 +15,7 @@ public static class DependencyInjection
services.AddScoped<IVisaApplicationRequestsHandler, VisaApplicationRequestsHandler>(); services.AddScoped<IVisaApplicationRequestsHandler, VisaApplicationRequestsHandler>();
services.AddScoped<IRegisterService, RegisterService>(); services.AddScoped<IRegisterService, RegisterService>();
services.AddScoped<IUsersService, UsersService>();
if (isDevelopment) if (isDevelopment)
{ {

View File

@@ -0,0 +1,24 @@
using ApplicationLayer.Services.AuthServices.Requests;
using Domains.Users;
namespace ApplicationLayer.Services.ApprovingAuthorities
{
/// user accounts service
public interface IUsersService
{
/// Returns all user accounts with role of approving authority
/// <param name="cancellationToken">Cancellation token</param>
Task<List<User>> GetAuthoritiesAccountsAsync(CancellationToken cancellationToken);
/// Changes authentication data for an account
/// <param name="userId">identifier of account</param>
/// <param name="data">request data with new email and password</param>
/// <param name="cancellationToken">Cancellation token</param>
Task ChangeAccountAuthDataAsync(Guid userId, RegisterRequest data, CancellationToken cancellationToken);
/// Removes user account
/// <param name="userId">Identifier of account</param>
/// <param name="cancellationToken">Cancellation token</param>
Task RemoveUserAccount(Guid userId, CancellationToken cancellationToken);
}
}

View File

@@ -0,0 +1,34 @@
using ApplicationLayer.InfrastructureServicesInterfaces;
using ApplicationLayer.Services.AuthServices.NeededServices;
using ApplicationLayer.Services.AuthServices.Requests;
using Domains.Users;
namespace ApplicationLayer.Services.ApprovingAuthorities
{
public class UsersService(IUsersRepository users, IUnitOfWork unitOfWork) : IUsersService
{
async Task<List<User>> IUsersService.GetAuthoritiesAccountsAsync(CancellationToken cancellationToken)
{
return await users.GetAllOfRoleAsync(Role.ApprovingAuthority, cancellationToken);
}
async Task IUsersService.ChangeAccountAuthDataAsync(Guid userId, RegisterRequest data, CancellationToken cancellationToken)
{
var user = await users.GetByIdAsync(userId, cancellationToken);
user.Email = data.Email;
user.Password = data.Password;
await users.UpdateAsync(user, cancellationToken);
await unitOfWork.SaveAsync(cancellationToken);
}
async Task IUsersService.RemoveUserAccount(Guid userId, CancellationToken cancellationToken)
{
var user = await users.GetByIdAsync(userId, cancellationToken);
users.Remove(user);
await unitOfWork.SaveAsync(cancellationToken);
}
}
}

View File

@@ -11,5 +11,11 @@ namespace ApplicationLayer.Services.AuthServices.NeededServices
/// <param name="cancellationToken">Cancellation token</param> /// <param name="cancellationToken">Cancellation token</param>
/// <returns>User or null if not found</returns> /// <returns>User or null if not found</returns>
Task<User?> FindByEmailAsync(string email, CancellationToken cancellationToken); Task<User?> FindByEmailAsync(string email, CancellationToken cancellationToken);
/// Returns all accounts with specific role
/// <param name="role">role</param>
/// <param name="cancellationToken">cancellation token</param>
/// <returns>list of accounts</returns>
Task<List<User>> GetAllOfRoleAsync(Role role, CancellationToken cancellationToken);
} }
} }

View File

@@ -13,5 +13,10 @@ namespace Infrastructure.Database.Users.Repositories
{ {
return await LoadDomain().SingleOrDefaultAsync(u => u.Email == email, cancellationToken); return await LoadDomain().SingleOrDefaultAsync(u => u.Email == email, cancellationToken);
} }
async Task<List<User>> IUsersRepository.GetAllOfRoleAsync(Role role, CancellationToken cancellationToken)
{
return await LoadDomain().Where(u => u.Role == role).ToListAsync(cancellationToken);
}
} }
} }

View File

@@ -1,6 +1,8 @@
using ApplicationLayer.Services.AuthServices.LoginService; using ApplicationLayer.Services.ApprovingAuthorities;
using ApplicationLayer.Services.AuthServices.LoginService;
using ApplicationLayer.Services.AuthServices.RegisterService; using ApplicationLayer.Services.AuthServices.RegisterService;
using ApplicationLayer.Services.AuthServices.Requests; using ApplicationLayer.Services.AuthServices.Requests;
using Domains.Users;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SchengenVisaApi.Common; using SchengenVisaApi.Common;
@@ -9,14 +11,17 @@ namespace SchengenVisaApi.Controllers
{ {
///<summary> Controller for user-auth and registration </summary> ///<summary> Controller for user-auth and registration </summary>
[ApiController] [ApiController]
[Route("auth")] [Route("users")]
public class UsersController(IRegisterService registerService, ILoginService loginService) : ControllerBase public class UsersController(
IRegisterService registerService,
ILoginService loginService,
IUsersService authorityService) : VisaApiControllerBase
{ {
/// <summary> Adds applicant with user account to DB </summary> /// <summary> Adds applicant with user account to DB </summary>
[HttpPost] [HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
[Route("applicant")] [Route("register")]
public async Task<IActionResult> Register(RegisterApplicantRequest request, CancellationToken cancellationToken) public async Task<IActionResult> Register(RegisterApplicantRequest request, CancellationToken cancellationToken)
{ {
await registerService.Register(request, cancellationToken); await registerService.Register(request, cancellationToken);
@@ -42,10 +47,55 @@ namespace SchengenVisaApi.Controllers
[HttpGet] [HttpGet]
[ProducesResponseType<string>(StatusCodes.Status200OK)] [ProducesResponseType<string>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status403Forbidden)]
[Route("login")]
public async Task<IActionResult> Login(string email, string password, CancellationToken cancellationToken) public async Task<IActionResult> Login(string email, string password, CancellationToken cancellationToken)
{ {
var result = await loginService.LoginAsync(new UserLoginRequest(email, password), cancellationToken); var result = await loginService.LoginAsync(new UserLoginRequest(email, password), cancellationToken);
return Ok(result); return Ok(result);
} }
/// <summary> Returns list of authority accounts </summary>
/// <remarks> Accessible only for admins </remarks>
[HttpGet]
[ProducesResponseType<List<User>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[Route("authority")]
[Authorize(policy: PolicyConstants.AdminPolicy)]
public async Task<IActionResult> GetAuthorityAccounts(CancellationToken cancellationToken)
{
var result = await authorityService.GetAuthoritiesAccountsAsync(cancellationToken);
return Ok(result);
}
/// <summary> Changes authority's account authentication data </summary>
/// <remarks> Accessible only for admins </remarks>
[HttpPut]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[Route("authority/{authorityAccountId:guid}")]
[Authorize(policy: PolicyConstants.AdminPolicy)]
public async Task<IActionResult> ChangeAuthorityAuthData(Guid authorityAccountId, RegisterRequest authData, CancellationToken cancellationToken)
{
await authorityService.ChangeAccountAuthDataAsync(authorityAccountId, authData, cancellationToken);
return Ok();
}
/// <summary> Removes authority's account authentication data </summary>
/// <remarks> Accessible only for admins </remarks>
[HttpDelete]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[Route("authority/{authorityAccountId:guid}")]
[Authorize(policy: PolicyConstants.AdminPolicy)]
public async Task<IActionResult> RemoveAuthorityAccount(Guid authorityAccountId, CancellationToken cancellationToken)
{
await authorityService.RemoveUserAccount(authorityAccountId, cancellationToken);
return Ok();
}
} }
} }

View File

@@ -0,0 +1,12 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
namespace SchengenVisaApi.Controllers
{
/// Base controller class for api controllers in project
public abstract class VisaApiControllerBase : ControllerBase
{
/// Returns identifier of authenticated user
protected Guid GetUserId() => Guid.Parse(HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value);
}
}

View File

@@ -11,8 +11,8 @@ namespace SchengenVisaApi.Controllers;
/// <summary> Controller for <see cref="Domains.VisaApplicationDomain"/> </summary> /// <summary> Controller for <see cref="Domains.VisaApplicationDomain"/> </summary>
[ApiController] [ApiController]
[Route("[controller]")] [Route("visaApplication")]
public class VisaApplicationController(IVisaApplicationRequestsHandler visaApplicationRequestsHandler) : ControllerBase public class VisaApplicationController(IVisaApplicationRequestsHandler visaApplicationRequestsHandler) : VisaApiControllerBase
{ {
//todo should return only pending applications //todo should return only pending applications
//todo should return model //todo should return model
@@ -59,6 +59,4 @@ public class VisaApplicationController(IVisaApplicationRequestsHandler visaAppli
await visaApplicationRequestsHandler.HandleCreateRequest(userId, request, cancellationToken); await visaApplicationRequestsHandler.HandleCreateRequest(userId, request, cancellationToken);
return Ok(); return Ok();
} }
private Guid GetUserId() => Guid.Parse(HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value);
} }