#7205798 Перенос сервиса пользователей и ролей в репозиторий

This commit is contained in:
ai.astrakhantsev 2022-10-27 11:22:39 +05:00
parent 5ea6919738
commit 211f300973
16 changed files with 270 additions and 434 deletions

View File

@ -1,41 +1,35 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using System; using AsbCloudApp.Services;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Repositories namespace AsbCloudApp.Repositories
{ {
/// <summary> /// <summary>
/// Репозиторий пользователей /// Репозиторий пользователей
/// </summary> /// </summary>
public interface IUserRepository public interface IUserRepository : ICrudService<UserExtendedDto>
{ {
/// <summary> /// <summary>
/// Добавление пользователя /// Получить список всех прав пользователя (включая наследование групп)
/// </summary>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<UserExtendedDto> InsertAsync(UserExtendedDto dto, CancellationToken token);
/// <summary>
/// Обновление ролей пользователя
/// </summary> /// </summary>
/// <param name="idUser"></param> /// <param name="idUser"></param>
/// <param name="newRoles"></param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<UserRoleDto> newRoles, CancellationToken token); IEnumerable<PermissionDto> GetNestedPermissions(int idUser);
/// <summary> /// <summary>
/// Получить пользователя по логину /// Получить список ролей пользователя (включая наследование)
/// </summary> /// </summary>
/// <param name="login"></param> /// <param name="idUser"></param>
/// <param name="token"></param> /// <param name="nestedLevel"></param>
/// <returns></returns> /// <returns></returns>
Task<UserExtendedDto?> GetUserByLoginAsync(string login, CancellationToken token); IEnumerable<UserRoleDto> GetRolesByIdUser(int idUser, int nestedLevel = 0);
/// <summary>
/// определяет есть ли у пользователя указанное разрешение
/// </summary>
/// <param name="idUser"></param>
/// <param name="permissionName"></param>
/// <returns></returns>
public bool HasPermission(int idUser, string permissionName);
} }
} }

View File

@ -1,40 +0,0 @@
using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using System.Collections.Generic;
namespace AsbCloudApp.Services
{
/// <summary>
/// Сервис пользователей
/// </summary>
public interface IUserService : ICrudService<UserExtendedDto>
{
/// <summary>
/// Сервис ролей
/// </summary>
IUserRoleRepository RoleService { get; }
/// <summary>
/// Получить список всех прав пользователя (включая наследование групп)
/// </summary>
/// <param name="idUser"></param>
/// <returns></returns>
IEnumerable<PermissionDto> GetNestedPermissions(int idUser);
/// <summary>
/// Получить список ролей пользователя (включая наследование)
/// </summary>
/// <param name="idUser"></param>
/// <param name="nestedLevel"></param>
/// <returns></returns>
IEnumerable<UserRoleDto> GetRolesByIdUser(int idUser, int nestedLevel = 0);
/// <summary>
/// определяет есть ли у пользователя указанное разрешение
/// </summary>
/// <param name="idUser"></param>
/// <param name="permissionName"></param>
/// <returns></returns>
public bool HasPermission(int idUser, string permissionName);
}
}

View File

@ -120,7 +120,6 @@ namespace AsbCloudInfrastructure
services.AddTransient<ITelemetryService, TelemetryService>(); services.AddTransient<ITelemetryService, TelemetryService>();
services.AddTransient<ITelemetryUserService, TelemetryUserService>(); services.AddTransient<ITelemetryUserService, TelemetryUserService>();
services.AddTransient<ITimezoneService, TimezoneService>(); services.AddTransient<ITimezoneService, TimezoneService>();
services.AddTransient<IUserService, UserService>();
services.AddTransient<IWellService, WellService>(); services.AddTransient<IWellService, WellService>();
services.AddTransient<IWellOperationImportService, WellOperationImportService>(); services.AddTransient<IWellOperationImportService, WellOperationImportService>();
services.AddTransient<IWellOperationService, WellOperationService>(); services.AddTransient<IWellOperationService, WellOperationService>();
@ -163,6 +162,7 @@ namespace AsbCloudInfrastructure
services.AddTransient<IFileStorageRepository, FileStorageRepository>(); services.AddTransient<IFileStorageRepository, FileStorageRepository>();
services.AddTransient<IWellCompositeRepository, WellCompositeRepository>(); services.AddTransient<IWellCompositeRepository, WellCompositeRepository>();
services.AddTransient<IUserRoleRepository, UserRoleRepository>(); services.AddTransient<IUserRoleRepository, UserRoleRepository>();
services.AddTransient<IUserRepository, UserRepository>();
// Subsystem service // Subsystem service
services.AddTransient<ICrudService<SubsystemDto>, CrudCacheServiceBase<SubsystemDto, Subsystem>>(); services.AddTransient<ICrudService<SubsystemDto>, CrudCacheServiceBase<SubsystemDto, Subsystem>>();
services.AddTransient<ISubsystemService, SubsystemService>(); services.AddTransient<ISubsystemService, SubsystemService>();

View File

@ -1,9 +1,13 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudDb;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.EfCache; using AsbCloudInfrastructure.EfCache;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -14,8 +18,11 @@ namespace AsbCloudInfrastructure.Repository
#nullable enable #nullable enable
public class UserRepository : IUserRepository public class UserRepository : IUserRepository
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext dbContext;
private static readonly System.TimeSpan cacheObsolescence = System.TimeSpan.FromMinutes(15); private readonly IUserRoleRepository userRoleRepository;
private const string userCacheTag = "User";
private const string relationUserUserRoleCacheTag = "RelationUserUserRole";
private static readonly TimeSpan cacheObsolence = TimeSpan.FromMinutes(15);
private static readonly TypeAdapterConfig userTypeAdapterConfig = TypeAdapterConfig<UserExtendedDto, User> private static readonly TypeAdapterConfig userTypeAdapterConfig = TypeAdapterConfig<UserExtendedDto, User>
.NewConfig() .NewConfig()
.Ignore(dst => dst.Company, .Ignore(dst => dst.Company,
@ -24,75 +31,209 @@ namespace AsbCloudInfrastructure.Repository
dst => dst.RelationUsersUserRoles) dst => dst.RelationUsersUserRoles)
.Config; .Config;
public UserRepository(IAsbCloudDbContext db) { public UserRepository(IAsbCloudDbContext dbContext, IUserRoleRepository userRoleRepository) {
this.db = db; this.dbContext = dbContext;
this.userRoleRepository = userRoleRepository;
} }
public async Task<UserExtendedDto> InsertAsync(UserExtendedDto dto, CancellationToken token) public async Task<int> InsertAsync(UserExtendedDto dto, CancellationToken token = default)
{ {
dto.Id = default; dto.Id = default;
var updatedEntity = await db.Users.AddAsync(Convert(dto), token).ConfigureAwait(false); var entity = Convert(dto);
return Convert(updatedEntity.Entity); await AssertLoginIsBusyAsync(dto.Login, token);
var userRoles = await userRoleRepository.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
var updatedEntity = await dbContext.Users.AddAsync(entity, token).ConfigureAwait(false);
if (userRoles?.Any() == true)
await UpdateRolesCacheForUserAsync(updatedEntity.Entity.Id, userRoles, token);
await dbContext.SaveChangesAsync(token);
DropCacheUsers();
return updatedEntity?.Entity?.Id ?? 0;
} }
public async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<UserRoleDto> newRoles, CancellationToken token) public Task<int> InsertRangeAsync(IEnumerable<UserExtendedDto> newItems, CancellationToken token = default)
{ {
var entity = await db.RelationUserUserRoles.FirstOrDefaultAsync(x => x.IdUser == idUser, token).ConfigureAwait(false); throw new NotImplementedException();
if (entity is not null)
{
db.RelationUserUserRoles.Remove(entity);
if (newRoles?.Any() == true)
await db.RelationUserUserRoles.AddRangeAsync(newRoles.Select(role => new RelationUserUserRole
{
IdUser = idUser,
IdUserRole = role.Id
}), token).ConfigureAwait(false);
}
} }
public async Task<UserExtendedDto?> GetUserByLoginAsync(string login, CancellationToken token) public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token = default)
{ {
var entities = await db.Users.FromCacheAsync("Users", cacheObsolescence, token).ConfigureAwait(false); var entities = await GetCacheUserAsync(token);
var entity = entities.FirstOrDefault(x => x.Login.ToLower() == login.ToLower());
if (entity is not null)
return Convert(entity);
return null;
}
public async Task<IEnumerable<UserExtendedDto>?> GetAllAsync(CancellationToken token = default)
{
var entities = await db.Users.FromCacheAsync("Users", cacheObsolescence, token).ConfigureAwait(false);
if (entities is null)
return null;
var dtos = entities.Select(Convert).ToList(); var dtos = entities.Select(Convert).ToList();
//for (var i = 0; i < dtos.Count; i++) for (var i = 0; i < dtos.Count; i++)
// dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id, token); dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id);
return dtos; return dtos;
} }
//private async Task<IEnumerable<string>> GetRolesNamesByIdUser(int idUser, CancellationToken token) public UserExtendedDto? GetOrDefault(int id)
//=> await GetRolesByIdUser(idUser, token) {
// ?.Select(r => r.Caption) var entity = GetCacheUser().FirstOrDefault(u => u.Id == id);
// .Distinct(); if (entity is null)
return null;
var dto = Convert(entity);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto;
}
//public async Task<IEnumerable<UserRoleDto>> GetRolesByIdUser(int idUser, CancellationToken token, int nestedLevel = 0) public async Task<UserExtendedDto?> GetOrDefaultAsync(int id, CancellationToken token = default)
//{ {
// var allRoles = await db.RelationUserUserRoles.FromCacheAsync("RelationUserUserRoles", cacheObsolescence, token).ConfigureAwait(false); var entity = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
// var roles = allRoles.Where(r => r.IdUser == idUser); if (entity is null)
// if (roles?.Any() != true) return null;
// return null; var dto = Convert(entity);
// return roles.SelectMany(r => RoleService.GetNestedById(r.IdUserRole, nestedLevel)); dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
//} return dto;
}
private User Convert(UserExtendedDto dto) public async Task<int> UpdateAsync(UserExtendedDto dto, CancellationToken token = default)
{
if (dto.Id <= 1)
throw new ArgumentInvalidException($"Invalid id {dto.Id}. You can't edit this user.", nameof(dto));
var oldUser = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == dto.Id);
if (oldUser is null)
return 0;
if (oldUser.Login != dto.Login)
await AssertLoginIsBusyAsync(dto.Login, token);
var userRoles = await userRoleRepository.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
if (userRoles is not null)
await UpdateRolesCacheForUserAsync(dto.Id, userRoles, token);
var entity = Convert(dto);
var result = dbContext.Users.Upsert(entity);
await dbContext.SaveChangesAsync(token);
DropCacheUsers();
return result?.Entity?.Id ?? 0;
}
public async Task<int> DeleteAsync(int id, CancellationToken token = default)
{
var entity = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
if (entity is null)
return 0;
var result = dbContext.Users.Remove(entity);
await dbContext.SaveChangesAsync(token);
DropCacheUsers();
return result?.Entity?.Id ?? 0;
}
public async Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
{
var entities = (await GetCacheUserAsync(token)).Where(r => ids.Contains(r.Id));
if (entities is null)
return 0;
var count = entities.Count();
dbContext.Users.RemoveRange(entities);
await dbContext.SaveChangesAsync(token);
DropCacheUsers();
return count;
}
public IEnumerable<UserRoleDto>? GetRolesByIdUser(int idUser, int nestedLevel = 0)
{
var roles = GetCachRelationUserUserRoleCacheTag().Where(r => r.IdUser == idUser);
if (roles is null)
return null;
return roles.SelectMany(r => userRoleRepository.GetNestedById(r.IdUserRole, nestedLevel));
}
public IEnumerable<PermissionDto>? GetNestedPermissions(int idUser)
{
var roles = GetRolesByIdUser(idUser, 7);
if (roles is null)
return null;
var permissions = roles
.Where(r => r.Permissions is not null)
.SelectMany(r => r.Permissions);
return permissions;
}
public bool HasPermission(int idUser, string permissionName)
{
if (idUser == 1)
return true;
var relationsToRoles = GetCachRelationUserUserRoleCacheTag().Where(r => r.IdUser == idUser);
if (relationsToRoles is null)
return false;
return userRoleRepository.HasPermission(relationsToRoles.Select(r => r.IdUserRole),
permissionName);
}
private IEnumerable<string>? GetRolesNamesByIdUser(int idUser)
=> GetRolesByIdUser(idUser)
?.Select(r => r.Caption)
.Distinct();
private async Task AssertLoginIsBusyAsync(string login, CancellationToken token = default)
{
var existingUser = (await GetCacheUserAsync(token))
.FirstOrDefault(u => u.Login.ToLower() == login.ToLower());
if (existingUser is not null)
throw new ArgumentInvalidException($"Login {login} is busy by {existingUser.MakeDisplayName()}, id{existingUser.Id}", nameof(login));
}
private Task<IEnumerable<User>> GetCacheUserAsync(CancellationToken token)
=> dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles)
.FromCacheAsync(userCacheTag, cacheObsolence, token);
private IEnumerable<User> GetCacheUser()
=> dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles)
.FromCache(userCacheTag, cacheObsolence);
private void DropCacheUsers()
=> dbContext.Users.DropCache(userCacheTag);
private Task<IEnumerable<RelationUserUserRole>> GetCacheRelationUserUserRoleAsync(CancellationToken token)
=> dbContext.RelationUserUserRoles
.Include(r => r.UserRole)
.Include(r => r.User)
.FromCacheAsync(relationUserUserRoleCacheTag, cacheObsolence, token);
private IEnumerable<RelationUserUserRole> GetCachRelationUserUserRoleCacheTag()
=> dbContext.RelationUserUserRoles
.Include(r => r.UserRole)
.Include(r => r.User)
.FromCache(relationUserUserRoleCacheTag, cacheObsolence);
private void DropCacheRelationUserUserRoleCacheTag()
=> dbContext.RelationUserUserRoles.DropCache(relationUserUserRoleCacheTag);
private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<UserRoleDto> newRoles, CancellationToken token)
{
var relations = (await GetCacheRelationUserUserRoleAsync(token)).Where(r => r.IdUser == idUser);
dbContext.RelationUserUserRoles.RemoveRange(relations);
if (newRoles?.Any() == true)
await dbContext.RelationUserUserRoles.AddRangeAsync(newRoles.Select(role => new RelationUserUserRole
{
IdUser = idUser,
IdUserRole = role.Id
}), token).ConfigureAwait(false);
await dbContext.SaveChangesAsync(token);
DropCacheRelationUserUserRoleCacheTag();
}
protected virtual User Convert(UserExtendedDto dto)
{ {
var entity = dto.Adapt<User>(userTypeAdapterConfig); var entity = dto.Adapt<User>(userTypeAdapterConfig);
if (string.IsNullOrEmpty(entity.PasswordHash)) if (string.IsNullOrEmpty(entity.PasswordHash))
entity.PasswordHash = db.Users.FirstOrDefault(u => u.Id == dto.Id)?.PasswordHash; entity.PasswordHash = dbContext.Users.FirstOrDefault(u => u.Id == dto.Id)?.PasswordHash;
return entity; return entity;
} }
private UserExtendedDto Convert(User entity) protected virtual UserExtendedDto Convert(User entity)
{ {
var dto = entity.Adapt<UserExtendedDto>(); var dto = entity.Adapt<UserExtendedDto>();
return dto; return dto;

View File

@ -38,7 +38,8 @@ namespace AsbCloudInfrastructure.Repository
await UpdatePermissionsAsync(dto, token); await UpdatePermissionsAsync(dto, token);
await UpdateIncludedRolesAsync(dto, token); await UpdateIncludedRolesAsync(dto, token);
dbContext.UserRoles.DropCache(); await dbContext.SaveChangesAsync(token);
DropCacheUserRole();
return updatedEntity?.Entity?.Id ?? 0; return updatedEntity?.Entity?.Id ?? 0;
} }
@ -98,6 +99,7 @@ namespace AsbCloudInfrastructure.Repository
await UpdateIncludedRolesAsync(dto, token); await UpdateIncludedRolesAsync(dto, token);
var result = dbContext.UserRoles.Upsert(entity); var result = dbContext.UserRoles.Upsert(entity);
await dbContext.SaveChangesAsync(token);
DropCacheUserRole(); DropCacheUserRole();
return result?.Entity?.Id ?? 0; return result?.Entity?.Id ?? 0;
} }

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using Mapster; using Mapster;
@ -21,7 +22,7 @@ namespace AsbCloudInfrastructure.Services
public class AuthService : IAuthService public class AuthService : IAuthService
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly IUserService userService; private readonly IUserRepository userRepository;
public const string issuer = "a"; public const string issuer = "a";
public const string audience = "a"; public const string audience = "a";
@ -36,10 +37,10 @@ namespace AsbCloudInfrastructure.Services
private readonly HashAlgorithm hashAlgorithm; private readonly HashAlgorithm hashAlgorithm;
private readonly Random rnd; private readonly Random rnd;
public AuthService(IAsbCloudDbContext db, IUserService userService) public AuthService(IAsbCloudDbContext db, IUserRepository userRepository)
{ {
this.db = db; this.db = db;
this.userService = userService; this.userRepository = userRepository;
hashAlgorithm = SHA384.Create(); hashAlgorithm = SHA384.Create();
rnd = new Random((int)(DateTime.Now.Ticks % 2147480161)); rnd = new Random((int)(DateTime.Now.Ticks % 2147480161));
} }
@ -165,12 +166,12 @@ namespace AsbCloudInfrastructure.Services
if (identity is null || user.IdState == 0) if (identity is null || user.IdState == 0)
return null; return null;
var userDto = await userService.GetOrDefaultAsync(user.Id, token); var userDto = await userRepository.GetOrDefaultAsync(user.Id, token);
if (userDto is null) if (userDto is null)
return null; return null;
var dto = userDto.Adapt<UserTokenDto>(); var dto = userDto.Adapt<UserTokenDto>();
dto.Permissions = userService.GetNestedPermissions(userDto.Id); dto.Permissions = userRepository.GetNestedPermissions(userDto.Id);
dto.Token = MakeToken(identity.Claims); dto.Token = MakeToken(identity.Claims);
return dto; return dto;
} }
@ -209,7 +210,7 @@ namespace AsbCloudInfrastructure.Services
new (ClaimsIdentity.DefaultNameClaimType, user.Login), new (ClaimsIdentity.DefaultNameClaimType, user.Login),
new (claimNameIdCompany, user.IdCompany?.ToString()!), new (claimNameIdCompany, user.IdCompany?.ToString()!),
}; };
var roles = userService.GetRolesByIdUser(user.Id); var roles = userRepository.GetRolesByIdUser(user.Id);
if (roles is not null) if (roles is not null)
foreach (var role in roles) foreach (var role in roles)
claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role.Caption)); claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role.Caption));

View File

@ -1,5 +1,6 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Exceptions; using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Repository;
@ -21,7 +22,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
private readonly IAsbCloudDbContext context; private readonly IAsbCloudDbContext context;
private readonly FileService fileService; private readonly FileService fileService;
private readonly IUserService userService; private readonly IUserRepository userRepository;
private readonly IWellService wellService; private readonly IWellService wellService;
private readonly IConfiguration configuration; private readonly IConfiguration configuration;
private readonly IBackgroundWorkerService backgroundWorker; private readonly IBackgroundWorkerService backgroundWorker;
@ -51,7 +52,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
public DrillingProgramService( public DrillingProgramService(
IAsbCloudDbContext context, IAsbCloudDbContext context,
FileService fileService, FileService fileService,
IUserService userService, IUserRepository userRepository,
IWellService wellService, IWellService wellService,
IConfiguration configuration, IConfiguration configuration,
IBackgroundWorkerService backgroundWorker, IBackgroundWorkerService backgroundWorker,
@ -59,7 +60,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
{ {
this.context = context; this.context = context;
this.fileService = fileService; this.fileService = fileService;
this.userService = userService; this.userRepository = userRepository;
this.wellService = wellService; this.wellService = wellService;
this.configuration = configuration; this.configuration = configuration;
this.backgroundWorker = backgroundWorker; this.backgroundWorker = backgroundWorker;
@ -127,7 +128,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
Parts = parts, Parts = parts,
Program = files.FirstOrDefault(f => f.IdCategory == idFileCategoryDrillingProgram) Program = files.FirstOrDefault(f => f.IdCategory == idFileCategoryDrillingProgram)
.Adapt<FileInfoDto>(), .Adapt<FileInfoDto>(),
PermissionToEdit = userService.HasPermission(idUser, "DrillingProgram.edit"), PermissionToEdit = userRepository.HasPermission(idUser, "DrillingProgram.edit"),
}; };
if (parts.Any()) if (parts.Any())
@ -226,7 +227,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
public async Task<int> AddUserAsync(int idWell, int idFileCategory, int idUser, int idUserRole, CancellationToken token = default) public async Task<int> AddUserAsync(int idWell, int idFileCategory, int idUser, int idUserRole, CancellationToken token = default)
{ {
var user = await userService.GetOrDefaultAsync(idUser, token); var user = await userRepository.GetOrDefaultAsync(idUser, token);
if (user is null) if (user is null)
throw new ArgumentInvalidException($"User id == {idUser} does not exist", nameof(idUser)); throw new ArgumentInvalidException($"User id == {idUser} does not exist", nameof(idUser));

View File

@ -1,198 +0,0 @@
using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.Cache;
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services
{
public class UserService : IUserService
{
private readonly CacheTable<User> cacheUsers;
private readonly CacheTable<RelationUserUserRole> cacheRelationUserToRoles;
public ISet<string> Includes { get; } = new SortedSet<string>();
public IUserRoleRepository RoleService { get; }
private static readonly TypeAdapterConfig userTypeAdapterConfig = TypeAdapterConfig<UserExtendedDto, User>
.NewConfig()
.Ignore(dst => dst.Company,
dst => dst.FileMarks,
dst => dst.Files,
dst => dst.RelationUsersUserRoles)
.Config;
public UserService(IAsbCloudDbContext context, CacheDb cacheDb, IUserRoleRepository roleService)
{
var db = (AsbCloudDbContext)context;
cacheUsers = cacheDb.GetCachedTable<User>(
db,
new[] {
nameof(User.RelationUsersUserRoles),
nameof(User.Company),
});
cacheRelationUserToRoles = cacheDb.GetCachedTable<RelationUserUserRole>(
db,
new[] {
nameof(RelationUserUserRole.User),
nameof(RelationUserUserRole.UserRole),
});
RoleService = roleService;
}
public async Task<int> InsertAsync(UserExtendedDto dto, CancellationToken token = default)
{
dto.Id = default;
var entity = Convert(dto);
await AssertLoginIsBusyAsync(dto.Login, token);
var userRoles = await RoleService.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
var updatedEntity = await cacheUsers.InsertAsync(entity, token).ConfigureAwait(false);
if (userRoles?.Any() == true)
await UpdateRolesCacheForUserAsync(updatedEntity.Id, userRoles, token);
return updatedEntity?.Id ?? 0;
}
private async Task AssertLoginIsBusyAsync(string login, CancellationToken token = default)
{
var existingUser = await cacheUsers.FirstOrDefaultAsync(u => u.Login.ToLower() == login.ToLower(), token);
if (existingUser is not null)
throw new ArgumentInvalidException($"Login {login} is busy by {existingUser.MakeDisplayName()}, id{existingUser.Id}", nameof(login));
}
public Task<int> InsertRangeAsync(IEnumerable<UserExtendedDto> newItems, CancellationToken token = default)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token = default)
{
var entities = (await cacheUsers.WhereAsync(token).ConfigureAwait(false))
.ToList();
if (entities.Count == 0)
return null;
var dtos = entities.Select(Convert).ToList();
for (var i = 0; i < dtos.Count; i++)
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id);
return dtos;
}
public UserExtendedDto GetOrDefault(int id)
{
var entity = cacheUsers.FirstOrDefault(u => u.Id == id);
var dto = Convert(entity);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto;
}
public async Task<UserExtendedDto> GetOrDefaultAsync(int id, CancellationToken token = default)
{
var entity = await cacheUsers.FirstOrDefaultAsync(u => u.Id == id, token).ConfigureAwait(false);
var dto = Convert(entity);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto;
}
public async Task<int> UpdateAsync(UserExtendedDto dto, CancellationToken token = default)
{
if (dto.Id <= 1)
throw new ArgumentInvalidException($"Invalid id {dto.Id}. You can't edit this user.", nameof(dto));
var oldUser = await cacheUsers.FirstOrDefaultAsync(u => u.Id == dto.Id, token);
if (oldUser.Login != dto.Login)
await AssertLoginIsBusyAsync(dto.Login, token);
var userRoles = await RoleService.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
await UpdateRolesCacheForUserAsync(dto.Id, userRoles, token);
var entity = Convert(dto);
var result = await cacheUsers.UpsertAsync(entity, token)
.ConfigureAwait(false);
return result;
}
public Task<int> DeleteAsync(int id, CancellationToken token = default)
{
if (id <= 1)
return Task.FromResult(0);
return cacheUsers.RemoveAsync(r => r.Id == id, token);
}
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
{
var filteredIds = ids.Where(i => i > 1).ToList();
return cacheUsers.RemoveAsync(r => filteredIds.Contains(r.Id), token);
}
private IEnumerable<string> GetRolesNamesByIdUser(int idUser)
=> GetRolesByIdUser(idUser)
?.Select(r => r.Caption)
.Distinct();
public IEnumerable<UserRoleDto> GetRolesByIdUser(int idUser, int nestedLevel = 0)
{
var roles = cacheRelationUserToRoles.Where(r => r.IdUser == idUser);
if (roles?.Any() != true)
return null;
return roles.SelectMany(r => RoleService.GetNestedById(r.IdUserRole, nestedLevel));
}
public IEnumerable<PermissionDto> GetNestedPermissions(int idUser)
{
var roles = GetRolesByIdUser(idUser, 7);
if (roles?.Any() != true)
return null;
var permissions = roles
.Where(r => r.Permissions is not null)
.SelectMany(r => r.Permissions);
return permissions;
}
private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<UserRoleDto> newRoles, CancellationToken token)
{
await cacheRelationUserToRoles.RemoveAsync(r => r.IdUser == idUser, token)
.ConfigureAwait(false);
if (newRoles?.Any() == true)
await cacheRelationUserToRoles.InsertAsync(newRoles.Select(role => new RelationUserUserRole
{
IdUser = idUser,
IdUserRole = role.Id
}), token).ConfigureAwait(false);
}
public bool HasPermission(int idUser, string permissionName)
{
if (idUser == 1)
return true;
var relationsToRoles = cacheRelationUserToRoles.Where(r => r.IdUser == idUser);
if (relationsToRoles is null)
return false;
return RoleService.HasPermission(relationsToRoles.Select(r => r.IdUserRole),
permissionName);
}
protected virtual User Convert(UserExtendedDto dto)
{
var entity = dto.Adapt<User>(userTypeAdapterConfig);
if (string.IsNullOrEmpty(entity.PasswordHash))
entity.PasswordHash = cacheUsers.FirstOrDefault(u => u.Id == dto.Id)?.PasswordHash;
return entity;
}
protected virtual UserExtendedDto Convert(User entity)
{
var dto = entity.Adapt<UserExtendedDto>();
return dto;
}
}
}

View File

@ -1,5 +1,6 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Exceptions; using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests; using AsbCloudApp.Requests;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
@ -24,7 +25,7 @@ namespace AsbCloudInfrastructure.Services
{ {
private readonly IAsbCloudDbContext context; private readonly IAsbCloudDbContext context;
private readonly FileService fileService; private readonly FileService fileService;
private readonly IUserService userService; private readonly IUserRepository userRepository;
private readonly IWellService wellService; private readonly IWellService wellService;
private readonly IConfiguration configuration; private readonly IConfiguration configuration;
private readonly IEmailService emailService; private readonly IEmailService emailService;
@ -34,7 +35,7 @@ namespace AsbCloudInfrastructure.Services
public WellFinalDocumentsService(IAsbCloudDbContext context, public WellFinalDocumentsService(IAsbCloudDbContext context,
FileService fileService, FileService fileService,
IUserService userService, IUserRepository userRepository,
IWellService wellService, IWellService wellService,
IConfiguration configuration, IConfiguration configuration,
IEmailService emailService, IEmailService emailService,
@ -42,7 +43,7 @@ namespace AsbCloudInfrastructure.Services
{ {
this.context = context; this.context = context;
this.fileService = fileService; this.fileService = fileService;
this.userService = userService; this.userRepository = userRepository;
this.wellService = wellService; this.wellService = wellService;
this.configuration = configuration; this.configuration = configuration;
this.emailService = emailService; this.emailService = emailService;
@ -120,7 +121,7 @@ namespace AsbCloudInfrastructure.Services
var result = new WellCaseDto var result = new WellCaseDto
{ {
IdWell = idWell, IdWell = idWell,
PermissionToSetPubliher = userService.HasPermission(idUser, "WellFinalDocument.editPublisher"), PermissionToSetPubliher = userRepository.HasPermission(idUser, "WellFinalDocument.editPublisher"),
WellFinalDocuments = docs, WellFinalDocuments = docs,
}; };
return result; return result;
@ -133,7 +134,7 @@ namespace AsbCloudInfrastructure.Services
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var allUsers = await userService.GetAllAsync(token) var allUsers = await userRepository.GetAllAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
return allUsers.Where(x => { return allUsers.Where(x => {
@ -181,7 +182,7 @@ namespace AsbCloudInfrastructure.Services
{ {
foreach (var item in dtos) foreach (var item in dtos)
{ {
var user = await userService.GetOrDefaultAsync(item.IdUser, token); var user = await userRepository.GetOrDefaultAsync(item.IdUser, token);
if (user?.Email is not null) if (user?.Email is not null)
{ {
var category = await fileCategoryService.GetOrDefaultAsync(item.IdCategory, token); var category = await fileCategoryService.GetOrDefaultAsync(item.IdCategory, token);

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Repository;
@ -79,7 +80,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
}; };
private readonly Mock<FileService> fileServiceMock; private readonly Mock<FileService> fileServiceMock;
private readonly Mock<IUserService> userServiceMock; private readonly Mock<IUserRepository> userRepositoryMock;
private readonly Mock<IWellService> wellServiceMock; private readonly Mock<IWellService> wellServiceMock;
private readonly Mock<IConfiguration> configurationMock; private readonly Mock<IConfiguration> configurationMock;
private readonly Mock<IBackgroundWorkerService> backgroundWorkerMock; private readonly Mock<IBackgroundWorkerService> backgroundWorkerMock;
@ -98,7 +99,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
db.SaveChanges(); db.SaveChanges();
fileServiceMock = new Mock<FileService>(); fileServiceMock = new Mock<FileService>();
userServiceMock = new Mock<IUserService>(); userRepositoryMock = new Mock<IUserRepository>();
wellServiceMock = new Mock<IWellService>(); wellServiceMock = new Mock<IWellService>();
configurationMock = new Mock<IConfiguration>(); configurationMock = new Mock<IConfiguration>();
backgroundWorkerMock = new Mock<IBackgroundWorkerService>(); backgroundWorkerMock = new Mock<IBackgroundWorkerService>();
@ -110,7 +111,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -127,7 +128,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -146,7 +147,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -163,13 +164,13 @@ namespace AsbCloudWebApi.Tests.ServicesTests
db.DrillingProgramParts.Add(new DrillingProgramPart { IdFileCategory = 1001, IdWell = idWell }); db.DrillingProgramParts.Add(new DrillingProgramPart { IdFileCategory = 1001, IdWell = idWell });
db.SaveChanges(); db.SaveChanges();
userServiceMock.Setup((s) => s.GetOrDefaultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>())) userRepositoryMock.Setup((s) => s.GetOrDefaultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(publisher1.Adapt<UserExtendedDto>())); .Returns(Task.FromResult(publisher1.Adapt<UserExtendedDto>()));
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -198,13 +199,13 @@ namespace AsbCloudWebApi.Tests.ServicesTests
IdUserRole = idUserRole IdUserRole = idUserRole
}); });
db.SaveChanges(); db.SaveChanges();
userServiceMock.Setup((s) => s.GetOrDefaultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>())) userRepositoryMock.Setup((s) => s.GetOrDefaultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(publisher1.Adapt<UserExtendedDto>())); .Returns(Task.FromResult(publisher1.Adapt<UserExtendedDto>()));
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -230,7 +231,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -261,7 +262,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -299,7 +300,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -326,7 +327,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -353,7 +354,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,
@ -383,7 +384,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var service = new DrillingProgramService( var service = new DrillingProgramService(
db, db,
fileServiceMock.Object, fileServiceMock.Object,
userServiceMock.Object, userRepositoryMock.Object,
wellServiceMock.Object, wellServiceMock.Object,
configurationMock.Object, configurationMock.Object,
backgroundWorkerMock.Object, backgroundWorkerMock.Object,

View File

@ -1,76 +0,0 @@
using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.Cache;
using Moq;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace AsbCloudWebApi.Tests.ServicesTests
{
public class UserServiceTest
{
private readonly AsbCloudDbContext context;
private readonly CacheDb cacheDb;
private readonly Mock<IUserRoleRepository> roleRepository;
public UserServiceTest()
{
context = TestHelpter.MakeTestContext();
cacheDb = new CacheDb();
roleRepository = new Mock<IUserRoleRepository>();
context.Users.RemoveRange(context.Users.Where(u => u.Id > 1));
context.SaveChanges();
}
~UserServiceTest()
{
context.Users.RemoveRange(context.Users.Where(u => u.Id > 1));
context.SaveChanges();
}
[Fact]
public async Task InsertAsync_returns_id()
{
var service = new UserService(context, cacheDb, roleRepository.Object);
var dto = new UserExtendedDto
{
Id = 0,
IdCompany = 1,
Email = "test@test.test",
Login = "test",
Name = "test",
Company = new CompanyDto { Caption = "test", Id = 1 },
Patronymic = "test",
Phone = "test",
Position = "test",
Surname = "test",
};
var id = await service.InsertAsync(dto, CancellationToken.None);
Assert.NotEqual(0, id);
}
[Fact]
public async Task InsertAsync_busy_login_throws_exceprion()
{
var service = new UserService(context, cacheDb, roleRepository.Object);
var dto = new UserExtendedDto
{
Id = 5,
Email = "test@test.test",
Login = "test clone"
};
await service.InsertAsync(dto, CancellationToken.None);
await Assert.ThrowsAsync<ArgumentException>(() => service.InsertAsync(dto, CancellationToken.None));
}
}
}

View File

@ -10,6 +10,8 @@ using Xunit;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using AsbCloudApp.Repositories;
using AsbCloudInfrastructure.Repository;
namespace AsbCloudWebApi.Tests.ServicesTests namespace AsbCloudWebApi.Tests.ServicesTests
{ {
@ -18,7 +20,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
private readonly AsbCloudDbContext context; private readonly AsbCloudDbContext context;
private WellFinalDocumentsService service; private WellFinalDocumentsService service;
private readonly Mock<FileService> fileServiceMock; private readonly Mock<FileService> fileServiceMock;
private readonly Mock<IUserService> userServiceMock; private readonly Mock<IUserRepository> userRepositoryMock;
private readonly Mock<IWellService> wellServiceMock; private readonly Mock<IWellService> wellServiceMock;
private readonly Mock<IConfiguration> configurationMock; private readonly Mock<IConfiguration> configurationMock;
private readonly Mock<IEmailService> emailServiceMock; private readonly Mock<IEmailService> emailServiceMock;
@ -45,8 +47,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests
context.SaveChanges(); context.SaveChanges();
fileServiceMock = new Mock<FileService>(); fileServiceMock = new Mock<FileService>();
userServiceMock = new Mock<IUserService>(); userRepositoryMock = new Mock<IUserRepository>();
userServiceMock.Setup(x => x.GetAllAsync(CancellationToken.None)).Returns(Task.Run(() => users.Select(x => (UserExtendedDto)x))); userRepositoryMock.Setup(x => x.GetAllAsync(CancellationToken.None)).Returns(Task.Run(() => users.Select(x => (UserExtendedDto)x)));
wellServiceMock = new Mock<IWellService>(); wellServiceMock = new Mock<IWellService>();
configurationMock = new Mock<IConfiguration>(); configurationMock = new Mock<IConfiguration>();
@ -56,7 +58,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests
service = new WellFinalDocumentsService( service = new WellFinalDocumentsService(
context: context, context: context,
fileService: fileServiceMock.Object, fileService: fileServiceMock.Object,
userService: userServiceMock.Object, userRepository: userRepositoryMock.Object,
wellService: wellServiceMock.Object, wellService: wellServiceMock.Object,
configuration: configurationMock.Object, configuration: configurationMock.Object,
emailService: emailServiceMock.Object, emailService: emailServiceMock.Object,

View File

@ -1,5 +1,7 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudInfrastructure.Repository;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -13,7 +15,7 @@ namespace AsbCloudWebApi.Controllers
[Authorize] [Authorize]
public class AdminUserController : CrudController<UserExtendedDto, ICrudService<UserExtendedDto>> public class AdminUserController : CrudController<UserExtendedDto, ICrudService<UserExtendedDto>>
{ {
public AdminUserController(IUserService service) public AdminUserController(IUserRepository service)
: base(service) : base(service)
{ } { }

View File

@ -1,5 +1,7 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudInfrastructure.Repository;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations; using Swashbuckle.AspNetCore.Annotations;
@ -16,12 +18,12 @@ namespace AsbCloudWebApi.Controllers
public class AuthController : ControllerBase public class AuthController : ControllerBase
{ {
private readonly IAuthService authService; private readonly IAuthService authService;
private readonly IUserService userService; private readonly IUserRepository userRepository;
public AuthController(IAuthService authService, IUserService userService) public AuthController(IAuthService authService, IUserRepository userRepository)
{ {
this.authService = authService; this.authService = authService;
this.userService = userService; this.userRepository = userRepository;
} }
/// <summary> /// <summary>
@ -97,7 +99,7 @@ namespace AsbCloudWebApi.Controllers
if (editorUserId is null) if (editorUserId is null)
return Forbid(); return Forbid();
if (!((editorUserId == idUser) || userService.HasPermission((int)editorUserId, "Auth.edit"))) if (!((editorUserId == idUser) || userRepository.HasPermission((int)editorUserId, "Auth.edit")))
return Forbid(); return Forbid();
var code = authService.ChangePassword(idUser, newPassword); var code = authService.ChangePassword(idUser, newPassword);

View File

@ -8,6 +8,8 @@ using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository;
using AsbCloudApp.Repositories;
namespace AsbCloudWebApi.Controllers namespace AsbCloudWebApi.Controllers
{ {
@ -42,7 +44,7 @@ namespace AsbCloudWebApi.Controllers
[Permission] [Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> SaveFilesAsync(int idWell, int idCategory, public async Task<IActionResult> SaveFilesAsync(int idWell, int idCategory,
[FromForm] IFormFileCollection files, [FromServices] IUserService userService, CancellationToken token = default) [FromForm] IFormFileCollection files, [FromServices] IUserRepository userRepository, CancellationToken token = default)
{ {
int? idCompany = User.GetCompanyId(); int? idCompany = User.GetCompanyId();
int? idUser = User.GetUserId(); int? idUser = User.GetUserId();
@ -54,7 +56,7 @@ namespace AsbCloudWebApi.Controllers
idWell, token).ConfigureAwait(false)) idWell, token).ConfigureAwait(false))
return Forbid(); return Forbid();
if (!userService.HasPermission((int)idUser, $"File.edit{idCategory}")) if (!userRepository.HasPermission((int)idUser, $"File.edit{idCategory}"))
return Forbid(); return Forbid();
foreach (var file in files) foreach (var file in files)
@ -140,7 +142,7 @@ namespace AsbCloudWebApi.Controllers
[Permission] [Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> DeleteAsync(int idWell, int idFile, public async Task<IActionResult> DeleteAsync(int idWell, int idFile,
[FromServices] IUserService userService, [FromServices] IUserRepository userRepository,
CancellationToken token = default) CancellationToken token = default)
{ {
int? idUser = User.GetUserId(); int? idUser = User.GetUserId();
@ -156,7 +158,7 @@ namespace AsbCloudWebApi.Controllers
if (fileInfo is null) if (fileInfo is null)
return NotFound(idFile); return NotFound(idFile);
if (!userService.HasPermission((int)idUser, $"File.edit{fileInfo?.IdCategory}")) if (!userRepository.HasPermission((int)idUser, $"File.edit{fileInfo?.IdCategory}"))
return Forbid(); return Forbid();
var result = await fileService.MarkAsDeletedAsync(idFile, token); var result = await fileService.MarkAsDeletedAsync(idFile, token);

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Services; using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -69,7 +70,7 @@ namespace AsbCloudWebApi.Middlewares
PermissionAttribute.Registered.Add(permissionName); PermissionAttribute.Registered.Add(permissionName);
} }
var userService = context.RequestServices.GetRequiredService<IUserService>(); var userService = context.RequestServices.GetRequiredService<IUserRepository>();
isAuthorized = userService.HasPermission((int)idUser, permissionName); isAuthorized = userService.HasPermission((int)idUser, permissionName);
} }