using AutoMapper; using FluentValidation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using PARR.API.Contracts.V1; using PARR.API.Contracts.V1.Requests; using PARR.API.Contracts.V1.Requests.Queries; using PARR.API.Contracts.V1.Responses; using PARR.API.Contracts.V1.Responses.Base; using PARR.API.Controllers.V1.Base; using PARR.API.Extensions; using PARR.API.Services.Interfaces; using PARR.DAL.Models; using PARR.DAL.Services.Interfaces; using PARR.Domain.Common.Pagination; using PARR.Domain.Common.Roles; namespace PARR.API.Controllers.V1 { /// /// Управление пользователями /// [Authorize(Roles = ParrRoles.Administrator.Role)] public class UserController : BaseApiController { private readonly IMapper mapper; private readonly IUserService userService; private readonly IValidator validator; private readonly IUriService uriService; private readonly ILogger logger; public UserController( IMapper mapper, IUserService userService, IValidator validator, IUriService uriService, ILogger logger ) { this.mapper = mapper; this.userService = userService; this.validator = validator; this.uriService = uriService; this.logger = logger; } /// /// Список пользователей постранично /// /// /// [HttpGet(ApiRoutes.User.GetAll)] public async Task GetAll([FromQuery] PaginationQuery paginationQuery) { var paginationFilter = mapper.Map(paginationQuery); IQueryable query = userService.Get() .Include(t => t.Roles).ThenInclude(t => t.Role) .OrderBy(t => t.Name); var users = await userService.GetPage(query, paginationFilter).ToListAsync(); if (!users.Any()) return NoContent(); var userResponse = mapper.Map>(users); var paginationResponse = new PagedResponse(userResponse, true).GetPaginatedProps(paginationFilter, query); return Ok(paginationResponse); } /// /// Получить пользователя по id /// /// /// [HttpGet(ApiRoutes.User.Get)] public async Task GetById([FromRoute] Guid id) { var user = await userService.Get() .Include(t => t.Roles).ThenInclude(t => t.Role) .FirstOrDefaultAsync(t => t.Id == id); if (user == null) return NotFound(); var response = mapper.Map(user); return Ok(new Response(response, true)); } /// /// Удалить пользователя /// /// /// [HttpDelete(ApiRoutes.User.Delete)] public async Task Delete([FromRoute] Guid id) { var user = await userService.GetAsync(id); if (user == null) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении пользователя. Не найден пользователь с id: {id}" } })); if (!userService.Delete(user) || !await userService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении пользователя." } })); logger.LogInformation($"Пользователь {User.Identity?.Name} удалил пользователя: {user.Id}, {user.Ip}, {user.Name}"); return NoContent(); } /// /// Создать пользователя /// /// /// [HttpPost(ApiRoutes.User.Create)] public async Task Create([FromBody] UserRequest request) { var resultValidate = await validator.ValidateAsync(request); if (!resultValidate.IsValid) return BadRequest(new Response(resultValidate.Errors)); var existIp = await userService.Get().FirstOrDefaultAsync(t => t.Ip == request.Ip); if (existIp != null) return BadRequest(new Response(false, new List { new ErrorModel { FieldName = nameof(request.Ip), Message = $"Ip {request.Ip} занят другим пользователем." } })); var user = new User { Id = Guid.NewGuid(), Ip = request.Ip, Name = request.Name, Description = request.Description }; if (!await userService.CreateAsync(user) || !await userService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при создани пользователя." } })); logger.LogInformation($"Пользователь {User.Identity?.Name} добавил пользователя: {user.Id}, {user.Ip}, {user.Name}"); var locationUri = uriService.GetUri(ApiRoutes.User.Get, ApiRoutes.User.getParam, user.Id); return Created(locationUri, new Response(mapper.Map(user), true)); } /// /// Обновить пользователя /// /// /// /// [HttpPut(ApiRoutes.User.Update)] public async Task Update([FromRoute] Guid id, [FromBody] UserRequest request) { var resultValidate = await validator.ValidateAsync(request); if (!resultValidate.IsValid) return BadRequest(new Response(resultValidate.Errors)); var orig = await userService.Get() .Include(t => t.Roles).ThenInclude(t => t.Role) .FirstOrDefaultAsync(t => t.Id == id); if (orig == null) return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при изменении пользователя." } })); //хочет изменить свой ip if (orig.Ip != request.Ip) { var existIp = await userService.Get().FirstOrDefaultAsync(t => t.Ip == request.Ip); if (existIp != null) return BadRequest(new Response(false, new List { new ErrorModel { FieldName = nameof(request.Ip), Message = $"Ip {request.Ip} занят другим пользователем." } })); } orig.Ip = request.Ip; orig.Name = request.Name; orig.Description = request.Description; if (!await userService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при изменении пользователя." } })); logger.LogInformation($"Пользователь {User.Identity?.Name} обновил пользователя: {orig.Id}, {orig.Ip}, {orig.Name}"); return Ok(new Response(mapper.Map(orig), true)); } } }