Registration and actions for approving authorities

This commit is contained in:
2024-08-19 23:12:01 +03:00
parent 0afe775d85
commit 8c58574b5a
19 changed files with 86 additions and 91 deletions

View File

@@ -14,8 +14,4 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0-preview.7.24405.7" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0-preview.7.24405.7" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,7 +1,6 @@
using ApplicationLayer.Services.AuthServices.LoginService; using ApplicationLayer.Services.AuthServices.LoginService;
using ApplicationLayer.Services.AuthServices.RegisterService; using ApplicationLayer.Services.AuthServices.RegisterService;
using ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests; using ApplicationLayer.Services.Locations.RequestHandlers;
using ApplicationLayer.Services.Locations.RequestHandlers.ApplicantRequests;
using ApplicationLayer.Services.VisaApplications.Handlers; using ApplicationLayer.Services.VisaApplications.Handlers;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -15,7 +14,6 @@ public static class DependencyInjection
{ {
services.AddScoped<IVisaApplicationRequestsHandler, VisaApplicationRequestsHandler>(); services.AddScoped<IVisaApplicationRequestsHandler, VisaApplicationRequestsHandler>();
services.AddScoped<ILocationRequestsHandler, LocationRequestsHandler>(); services.AddScoped<ILocationRequestsHandler, LocationRequestsHandler>();
services.AddScoped<IEditLocationsRequestsHandler, EditLocationsRequestsHandler>();
services.AddScoped<IRegisterService, RegisterService>(); services.AddScoped<IRegisterService, RegisterService>();

View File

@@ -3,5 +3,5 @@ using ApplicationLayer.Services.AuthServices.Requests;
namespace ApplicationLayer.Services.AuthServices.RegisterService.Exceptions namespace ApplicationLayer.Services.AuthServices.RegisterService.Exceptions
{ {
public class UserAlreadyExistsException(RegisterApplicantRequest request) : AlreadyExistsException($"User with email '{request.Email}' already exists"); public class UserAlreadyExistsException(RegisterRequest request) : AlreadyExistsException($"User with email '{request.Email}' already exists");
} }

View File

@@ -2,10 +2,13 @@
namespace ApplicationLayer.Services.AuthServices.RegisterService namespace ApplicationLayer.Services.AuthServices.RegisterService
{ {
/// Handles <see cref="RegisterApplicantRequest"/> /// Handles register request
public interface IRegisterService public interface IRegisterService
{ {
/// Handle <see cref="RegisterApplicantRequest"/> /// Handle <see cref="RegisterApplicantRequest"/>
Task Register(RegisterApplicantRequest request, CancellationToken cancellationToken); Task Register(RegisterApplicantRequest request, CancellationToken cancellationToken);
/// Handles <see cref="RegisterRequest"/> and adds approving authority account
Task RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken);
} }
} }

View File

@@ -18,6 +18,7 @@ namespace ApplicationLayer.Services.AuthServices.RegisterService
{ {
async Task IRegisterService.Register(RegisterApplicantRequest request, CancellationToken cancellationToken) async Task IRegisterService.Register(RegisterApplicantRequest request, CancellationToken cancellationToken)
{ {
//todo move to validation layer
if (await users.FindByEmailAsync(request.Email, cancellationToken) is not null) if (await users.FindByEmailAsync(request.Email, cancellationToken) is not null)
{ {
throw new UserAlreadyExistsException(request); throw new UserAlreadyExistsException(request);
@@ -38,9 +39,7 @@ namespace ApplicationLayer.Services.AuthServices.RegisterService
var placeOfWork = new PlaceOfWork var placeOfWork = new PlaceOfWork
{ {
Name = request.PlaceOfWork.Name, Name = request.PlaceOfWork.Name, Address = placeOfWorkAddress, PhoneNum = request.PlaceOfWork.PhoneNum
Address = placeOfWorkAddress,
PhoneNum = request.PlaceOfWork.PhoneNum
}; };
var applicant = new Applicant var applicant = new Applicant
@@ -67,5 +66,21 @@ namespace ApplicationLayer.Services.AuthServices.RegisterService
await unitOfWork.SaveAsync(cancellationToken); await unitOfWork.SaveAsync(cancellationToken);
} }
async Task IRegisterService.RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken)
{
//todo move to validation layer
if (await users.FindByEmailAsync(request.Email, cancellationToken) is not null)
{
throw new UserAlreadyExistsException(request);
}
//TODO mapper
var user = new User { Email = request.Email, Password = request.Password, Role = Role.ApprovingAuthority };
await users.AddAsync(user, cancellationToken);
await unitOfWork.SaveAsync(cancellationToken);
}
} }
} }

View File

@@ -18,5 +18,5 @@ namespace ApplicationLayer.Services.AuthServices.Requests
Name MotherName, Name MotherName,
string JobTitle, string JobTitle,
PlaceOfWorkModel PlaceOfWork, PlaceOfWorkModel PlaceOfWork,
bool IsNonResident); bool IsNonResident) : RegisterRequest(Email, Password);
} }

View File

@@ -0,0 +1,4 @@
namespace ApplicationLayer.Services.AuthServices.Requests
{
public record RegisterRequest(string Email, string Password);
}

View File

@@ -1,11 +0,0 @@
using ApplicationLayer.Services.Locations.Requests;
namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests
{
/// Handles edit requests of locations from admins
public interface IEditLocationsRequestsHandler
{
/// Handles add country requests
Task AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken);
}
}

View File

@@ -1,12 +0,0 @@
using Domains.LocationDomain;
namespace ApplicationLayer.Services.Locations.RequestHandlers.ApplicantRequests
{
/// Handles location requests
public interface ILocationRequestsHandler
{
/// Handle get request
/// <returns>List of available countries</returns>
Task<List<Country>> HandleGetRequestAsync(CancellationToken cancellationToken);
}
}

View File

@@ -1,14 +0,0 @@
using ApplicationLayer.Services.Locations.NeededServices;
using Domains.LocationDomain;
namespace ApplicationLayer.Services.Locations.RequestHandlers.ApplicantRequests
{
/// <inheritdoc cref="ILocationRequestsHandler"/>
public class LocationRequestsHandler(ICountriesRepository countries) : ILocationRequestsHandler
{
async Task<List<Country>> ILocationRequestsHandler.HandleGetRequestAsync(CancellationToken cancellationToken)
{
return await countries.GetAllAsync(cancellationToken);
}
}
}

View File

@@ -1,6 +1,6 @@
using ApplicationLayer.GeneralExceptions; using ApplicationLayer.GeneralExceptions;
namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests.Exceptions namespace ApplicationLayer.Services.Locations.RequestHandlers.Exceptions
{ {
public class CountryAlreadyExists(string countryName) : AlreadyExistsException($"{countryName} already exists."); public class CountryAlreadyExists(string countryName) : AlreadyExistsException($"{countryName} already exists.");
} }

View File

@@ -1,6 +1,6 @@
using ApplicationLayer.GeneralExceptions; using ApplicationLayer.GeneralExceptions;
namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests.Exceptions namespace ApplicationLayer.Services.Locations.RequestHandlers.Exceptions
{ {
public class MultipleIdenticalCitiesInCountryException() : ApiException("There are multiple cities with one name in the country."); public class MultipleIdenticalCitiesInCountryException() : ApiException("There are multiple cities with one name in the country.");
} }

View File

@@ -0,0 +1,16 @@
using ApplicationLayer.Services.Locations.Requests;
using Domains.LocationDomain;
namespace ApplicationLayer.Services.Locations.RequestHandlers
{
/// Handles location requests
public interface ILocationRequestsHandler
{
/// Handle get request
/// <returns>List of available countries</returns>
Task<List<Country>> HandleGetRequestAsync(CancellationToken cancellationToken);
/// Handles add country requests
Task AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken);
}
}

View File

@@ -1,15 +1,20 @@
using ApplicationLayer.GeneralNeededServices; using ApplicationLayer.GeneralNeededServices;
using ApplicationLayer.Services.Locations.NeededServices; using ApplicationLayer.Services.Locations.NeededServices;
using ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests.Exceptions; using ApplicationLayer.Services.Locations.RequestHandlers.Exceptions;
using ApplicationLayer.Services.Locations.Requests; using ApplicationLayer.Services.Locations.Requests;
using Domains.LocationDomain; using Domains.LocationDomain;
namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests namespace ApplicationLayer.Services.Locations.RequestHandlers
{ {
/// <inheritdoc cref="IEditLocationsRequestsHandler"/> /// <inheritdoc cref="ILocationRequestsHandler"/>
public class EditLocationsRequestsHandler(ICountriesRepository countries, IUnitOfWork unitOfWork) : IEditLocationsRequestsHandler public class LocationRequestsHandler(ICountriesRepository countries, IUnitOfWork unitOfWork) : ILocationRequestsHandler
{ {
async Task IEditLocationsRequestsHandler.AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken) async Task<List<Country>> ILocationRequestsHandler.HandleGetRequestAsync(CancellationToken cancellationToken)
{
return await countries.GetAllAsync(cancellationToken);
}
async Task ILocationRequestsHandler.AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken)
{ {
if (await countries.FindByName(request.CountryName, cancellationToken) is not null) if (await countries.FindByName(request.CountryName, cancellationToken) is not null)
{ {
@@ -21,6 +26,7 @@ namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests
throw new MultipleIdenticalCitiesInCountryException(); throw new MultipleIdenticalCitiesInCountryException();
} }
//todo mapper
var country = new Country var country = new Country
{ {
Name = request.CountryName, Name = request.CountryName,

View File

@@ -1,30 +0,0 @@
using ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests;
using ApplicationLayer.Services.Locations.Requests;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SchengenVisaApi.Common;
namespace SchengenVisaApi.Controllers
{
[ApiController]
[Route("admin")]
[Authorize(policy: PolicyConstants.AdminPolicy)]
public class AdminController(IEditLocationsRequestsHandler requestsHandler) : ControllerBase
{
[HttpPost]
[Route("country")]
public async Task<IActionResult> AddCountry(AddCountryRequest request, CancellationToken cancellationToken)
{
await requestsHandler.AddCountryAsync(request, cancellationToken);
return Ok();
}
[HttpPost]
[Route("authorities")]
public async Task<IActionResult> AddAuthority(AddCountryRequest request, CancellationToken cancellationToken)
{
await requestsHandler.AddCountryAsync(request, cancellationToken);
return Ok();
}
}
}

View File

@@ -1,5 +1,8 @@
using ApplicationLayer.Services.Locations.RequestHandlers.ApplicantRequests; using ApplicationLayer.Services.Locations.RequestHandlers;
using ApplicationLayer.Services.Locations.Requests;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SchengenVisaApi.Common;
namespace SchengenVisaApi.Controllers namespace SchengenVisaApi.Controllers
{ {
@@ -12,5 +15,14 @@ namespace SchengenVisaApi.Controllers
{ {
return Ok(await requestsHandler.HandleGetRequestAsync(cancellationToken)); return Ok(await requestsHandler.HandleGetRequestAsync(cancellationToken));
} }
[HttpPost]
[Route("country")]
[Authorize(policy: PolicyConstants.AdminPolicy)]
public async Task<IActionResult> AddCountry(AddCountryRequest request, CancellationToken cancellationToken)
{
await requestsHandler.AddCountryAsync(request, cancellationToken);
return Ok();
}
} }
} }

View File

@@ -1,7 +1,9 @@
using ApplicationLayer.Services.AuthServices.LoginService; 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 Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SchengenVisaApi.Common;
namespace SchengenVisaApi.Controllers namespace SchengenVisaApi.Controllers
{ {
@@ -10,12 +12,22 @@ namespace SchengenVisaApi.Controllers
public class UsersController(IRegisterService registerService, ILoginService loginService) : ControllerBase public class UsersController(IRegisterService registerService, ILoginService loginService) : ControllerBase
{ {
[HttpPost] [HttpPost]
[Route("applicant")]
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);
return Created(); return Created();
} }
[HttpPost]
[Authorize(policy: PolicyConstants.AdminPolicy)]
[Route("authority")]
public async Task<IActionResult> RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken)
{
await registerService.RegisterAuthority(request, cancellationToken);
return Created();
}
[HttpGet] [HttpGet]
public async Task<IActionResult> Login(string email, string password, CancellationToken cancellationToken) public async Task<IActionResult> Login(string email, string password, CancellationToken cancellationToken)
{ {

View File

@@ -9,11 +9,10 @@ namespace SchengenVisaApi.Controllers;
[ApiController] [ApiController]
[Route("[controller]")] [Route("[controller]")]
[Authorize(policy: PolicyConstants.ApplicantPolicy)]
public class VisaApplicationController(IVisaApplicationRequestsHandler visaApplicationRequestsHandler) : ControllerBase public class VisaApplicationController(IVisaApplicationRequestsHandler visaApplicationRequestsHandler) : ControllerBase
{ {
//TODO remove
[HttpGet] [HttpGet]
[Authorize(policy: PolicyConstants.ApprovingAuthorityPolicy)]
public async Task<IActionResult> Get(CancellationToken cancellationToken) public async Task<IActionResult> Get(CancellationToken cancellationToken)
{ {
var result = await visaApplicationRequestsHandler.Get(cancellationToken); var result = await visaApplicationRequestsHandler.Get(cancellationToken);
@@ -21,6 +20,7 @@ public class VisaApplicationController(IVisaApplicationRequestsHandler visaAppli
} }
[HttpPost] [HttpPost]
[Authorize(policy: PolicyConstants.ApplicantPolicy)]
public void Create(VisaApplicationCreateRequest request, CancellationToken cancellationToken) public void Create(VisaApplicationCreateRequest request, CancellationToken cancellationToken)
{ {
var userId = Guid.Parse(HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value); var userId = Guid.Parse(HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value);

View File

@@ -1,6 +1,6 @@
using ApplicationLayer.GeneralExceptions; using ApplicationLayer.GeneralExceptions;
using ApplicationLayer.Services.AuthServices.LoginService.Exceptions; using ApplicationLayer.Services.AuthServices.LoginService.Exceptions;
using ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests.Exceptions; using ApplicationLayer.Services.Locations.RequestHandlers.Exceptions;
using Domains; using Domains;
using Infrastructure.Database.GeneralExceptions; using Infrastructure.Database.GeneralExceptions;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;