forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/TelemetryDataCache
This commit is contained in:
commit
95cf8dbd07
32
AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs
Normal file
32
AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
namespace AsbCloudApp.Data.Subsystems
|
||||||
|
{
|
||||||
|
#nullable enable
|
||||||
|
/// <summary>
|
||||||
|
/// Статистика наработки подсистем по активным скважинам
|
||||||
|
/// </summary>
|
||||||
|
public class SubsystemActiveWellStatDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Активная скважина
|
||||||
|
/// </summary>
|
||||||
|
public WellDto Well { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Наработки подсистемы АКБ
|
||||||
|
/// </summary>
|
||||||
|
public SubsystemStatDto? SubsystemAKB { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Наработки подсистемы МСЕ
|
||||||
|
/// </summary>
|
||||||
|
public SubsystemStatDto? SubsystemMSE { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Наработки подсистемы СПИН
|
||||||
|
/// </summary>
|
||||||
|
public SubsystemStatDto? SubsystemSpinMaster { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Наработки подсистемы ТОРК
|
||||||
|
/// </summary>
|
||||||
|
public SubsystemStatDto? SubsystemTorqueMaster { get; set; }
|
||||||
|
}
|
||||||
|
#nullable disable
|
||||||
|
}
|
@ -58,5 +58,25 @@
|
|||||||
/// DTO компании
|
/// DTO компании
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CompanyDto Company { get; set; }
|
public CompanyDto Company { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение отображаемого имени
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string MakeDisplayName()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(Surname))
|
||||||
|
return Login;
|
||||||
|
|
||||||
|
var s = Surname;
|
||||||
|
if (!string.IsNullOrEmpty(Name))
|
||||||
|
{
|
||||||
|
s += $"{Name[0]}.";
|
||||||
|
if (!string.IsNullOrEmpty(Patronymic))
|
||||||
|
s += $" {Patronymic[0]}.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
namespace AsbCloudApp.Repositories
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сервис пользователей
|
/// Репозиторий пользователей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IUserService : ICrudService<UserExtendedDto>
|
public interface IUserRepository : ICrudService<UserExtendedDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Сервис ролей
|
|
||||||
/// </summary>
|
|
||||||
IUserRoleService RoleService { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить список всех прав пользователя (включая наследование групп)
|
/// Получить список всех прав пользователя (включая наследование групп)
|
||||||
/// </summary>
|
/// </summary>
|
@ -1,16 +1,17 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
namespace AsbCloudApp.Repositories
|
||||||
{
|
{
|
||||||
|
#nullable enable
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Репозиторий ролей пользователя
|
/// Разрешения на доступ к данным
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IUserRoleService : ICrudService<UserRoleDto>
|
public interface IUserRoleRepository : ICrudService<UserRoleDto>
|
||||||
{
|
{
|
||||||
// todo: переименовать
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// получить dto по названиям
|
/// получить dto по названиям
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -35,4 +36,5 @@ namespace AsbCloudApp.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool HasPermission(IEnumerable<int> rolesIds, string permissionName);
|
bool HasPermission(IEnumerable<int> rolesIds, string permissionName);
|
||||||
}
|
}
|
||||||
|
#nullable disable
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.DetectedOperation;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -39,6 +40,16 @@ namespace AsbCloudApp.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<DetectedOperationDto>?> GetOperationsAsync(DetectedOperationRequest request, CancellationToken token);
|
Task<IEnumerable<DetectedOperationDto>?> GetOperationsAsync(DetectedOperationRequest request, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить интервалы глубин по всем скважинам
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="telemetryIds">список ИД телеметрий активных скважин</param>
|
||||||
|
/// <param name="gtDate"></param>
|
||||||
|
/// <param name="ltDate"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns>кортеж - ид телеметрии, интервалы глубины забоя (ротор,слайд) </returns>
|
||||||
|
Task<IEnumerable<(int idTelemetry,double depthIntervalRotor, double depthIntervalSlide)>> GetDepthIntervalAllOperationsAsync(IEnumerable<int?> telemetryIds,DateTimeOffset gtDate, DateTimeOffset ltDate, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Удалить операции
|
/// Удалить операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -50,7 +50,8 @@ namespace AsbCloudApp.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сохранение файла
|
/// Сохранение файла
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDto"></param>
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="idCategory"></param>
|
||||||
/// <param name="idUser"></param>
|
/// <param name="idUser"></param>
|
||||||
/// <param name="fileStream"></param>
|
/// <param name="fileStream"></param>
|
||||||
/// <param name="fileName"></param>
|
/// <param name="fileName"></param>
|
||||||
|
@ -47,6 +47,15 @@ namespace AsbCloudApp.Services.Subsystems
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<DatesRangeDto?> GetDateRangeOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token);
|
Task<DatesRangeDto?> GetDateRangeOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token);
|
||||||
|
/// <summary>
|
||||||
|
/// Получение статистики по наработке подсистем по активным скважинам
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idCompany"></param>
|
||||||
|
/// <param name="gtDate"></param>
|
||||||
|
/// <param name="ltDate"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(int idCompany, DateTime? gtDate, DateTime? ltDate, CancellationToken token);
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ namespace AsbCloudDb.Model
|
|||||||
DbSet<RelationUserDrillingProgramPart> RelationDrillingProgramPartUsers { get; }
|
DbSet<RelationUserDrillingProgramPart> RelationDrillingProgramPartUsers { get; }
|
||||||
DbSet<RelationUserRolePermission> RelationUserRolePermissions { get; }
|
DbSet<RelationUserRolePermission> RelationUserRolePermissions { get; }
|
||||||
DbSet<RelationUserUserRole> RelationUserUserRoles { get; }
|
DbSet<RelationUserUserRole> RelationUserUserRoles { get; }
|
||||||
|
DbSet<RelationUserRoleUserRole> RelationUserRoleUserRoles { get; }
|
||||||
DbSet<ReportProperty> ReportProperties { get; }
|
DbSet<ReportProperty> ReportProperties { get; }
|
||||||
DbSet<Subsystem> Subsystems { get; }
|
DbSet<Subsystem> Subsystems { get; }
|
||||||
DbSet<SubsystemOperationTime> SubsystemOperationTimes { get; }
|
DbSet<SubsystemOperationTime> SubsystemOperationTimes { get; }
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Remove="CommonLibs\logo_720x404.png" />
|
||||||
|
<None Remove="CommonLibs\Readme.md" />
|
||||||
<None Remove="Services\DailyReport\DailyReportTemplate.xlsx" />
|
<None Remove="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||||
<None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
<None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||||
<None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" />
|
<None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" />
|
||||||
@ -16,7 +18,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Res\logo_32.png">
|
<Content Include="CommonLibs\logo_720x404.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="CommonLibs\Readme.md">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -43,7 +48,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="CommonLibs\" />
|
|
||||||
<Folder Include="Services\DailyReport\DailyReportBlocks\" />
|
<Folder Include="Services\DailyReport\DailyReportBlocks\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
2
AsbCloudInfrastructure/CommonLibs/Readme.md
Normal file
2
AsbCloudInfrastructure/CommonLibs/Readme.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Библиотека формирования рапортов в формате PDF.
|
||||||
|
Для брендирования положить рядом с библиотекой файл logo_720x404.png
|
BIN
AsbCloudInfrastructure/CommonLibs/logo_720x404.png
Normal file
BIN
AsbCloudInfrastructure/CommonLibs/logo_720x404.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -120,16 +120,12 @@ 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<IUserRoleService, UserRoleService>();
|
|
||||||
services.AddTransient<IWellService, WellService>();
|
services.AddTransient<IWellService, WellService>();
|
||||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||||
services.AddTransient<IWellOperationService, WellOperationService>();
|
services.AddTransient<IWellOperationService, WellOperationService>();
|
||||||
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
||||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||||
//services.AddTransient<IDrillerService, DrillerService>();
|
|
||||||
|
|
||||||
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
|
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
|
||||||
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
||||||
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedServiceBase<OperationValueDto, OperationValue>>();
|
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedServiceBase<OperationValueDto, OperationValue>>();
|
||||||
@ -165,6 +161,8 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IFileRepository, FileRepository>();
|
services.AddTransient<IFileRepository, FileRepository>();
|
||||||
services.AddTransient<IFileStorageRepository, FileStorageRepository>();
|
services.AddTransient<IFileStorageRepository, FileStorageRepository>();
|
||||||
services.AddTransient<IWellCompositeRepository, WellCompositeRepository>();
|
services.AddTransient<IWellCompositeRepository, WellCompositeRepository>();
|
||||||
|
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>();
|
||||||
|
@ -21,6 +21,82 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
private static readonly TimeSpan minCacheTime = TimeSpan.FromSeconds(2);
|
private static readonly TimeSpan minCacheTime = TimeSpan.FromSeconds(2);
|
||||||
private static readonly TimeSpan defaultObsolescence = TimeSpan.FromMinutes(4);
|
private static readonly TimeSpan defaultObsolescence = TimeSpan.FromMinutes(4);
|
||||||
|
|
||||||
|
private class YieldConvertedData<TEntity, TModel> : IEnumerable<TModel>
|
||||||
|
{
|
||||||
|
private struct ConvertedData
|
||||||
|
{
|
||||||
|
public TEntity? Entity;
|
||||||
|
public TModel? Model;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertedData[] data;
|
||||||
|
public Func<TEntity, TModel> convert { get; }
|
||||||
|
|
||||||
|
public YieldConvertedData(TEntity[] entities, Func<TEntity, TModel> convert)
|
||||||
|
{
|
||||||
|
data = (entities.Select(x => new ConvertedData {
|
||||||
|
Entity = x,
|
||||||
|
Model = default }))
|
||||||
|
.ToArray();
|
||||||
|
this.convert = convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
class YieldConvertedDataEnumerator : IEnumerator<TModel>
|
||||||
|
{
|
||||||
|
private readonly ConvertedData[] data;
|
||||||
|
private readonly Func<TEntity, TModel> convert;
|
||||||
|
private int position = -1;
|
||||||
|
|
||||||
|
public YieldConvertedDataEnumerator(ConvertedData[] data, Func<TEntity, TModel> convert)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
this.convert = convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TModel Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (data[position].Entity is TEntity entity)
|
||||||
|
{
|
||||||
|
var dto = convert(entity);
|
||||||
|
data[position].Entity = default;
|
||||||
|
data[position].Model = dto;
|
||||||
|
}
|
||||||
|
return data[position].Model!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object IEnumerator.Current => Current!;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
position++;
|
||||||
|
return (position < data.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
position = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<TModel> GetEnumerator()
|
||||||
|
{
|
||||||
|
var result = new YieldConvertedDataEnumerator(data, convert);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class CacheItem
|
private class CacheItem
|
||||||
{
|
{
|
||||||
internal IEnumerable? Data;
|
internal IEnumerable? Data;
|
||||||
@ -45,14 +121,10 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var convertedData = typedEntityData.Select(convert).ToList();
|
var convertedData = new YieldConvertedData<TEntity, TModel>(typedEntityData.ToArray(), convert);
|
||||||
Data = convertedData;
|
Data = convertedData;
|
||||||
return convertedData;
|
return convertedData;
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
semaphore.Release();
|
semaphore.Release();
|
||||||
@ -67,7 +139,7 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
semaphore.Release();
|
semaphore.Release();
|
||||||
throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while converting cache data");
|
throw new TimeoutException("EfCacheL2.GetData. Can't wait too long while converting cache data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +149,7 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CacheItem GetOrAddCache(string tag, Func<IEnumerable> valueFactory, TimeSpan obsolete)
|
private static CacheItem GetOrAddCache(string tag, Func<object[]> valueFactory, TimeSpan obsolete)
|
||||||
{
|
{
|
||||||
CacheItem cache;
|
CacheItem cache;
|
||||||
while (!caches.ContainsKey(tag))
|
while (!caches.ContainsKey(tag))
|
||||||
@ -85,13 +157,12 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
if (semaphore.Wait(0))
|
if (semaphore.Wait(0))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (!caches.ContainsKey(tag))
|
||||||
{
|
{
|
||||||
cache = new CacheItem();
|
cache = new CacheItem();
|
||||||
caches.Add(tag, cache);
|
caches.Add(tag, cache);
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -133,10 +204,6 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
cache.DateObsolete = dateObsolete;
|
cache.DateObsolete = dateObsolete;
|
||||||
cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
|
cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
cache.semaphore.Release();
|
cache.semaphore.Release();
|
||||||
@ -158,7 +225,7 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<CacheItem> GetOrAddCacheAsync(string tag, Func<CancellationToken, Task<IEnumerable>> valueFactoryAsync, TimeSpan obsolete, CancellationToken token)
|
private static async Task<CacheItem> GetOrAddCacheAsync(string tag, Func<CancellationToken, Task<object[]>> valueFactoryAsync, TimeSpan obsolete, CancellationToken token)
|
||||||
{
|
{
|
||||||
CacheItem cache;
|
CacheItem cache;
|
||||||
while (!caches.ContainsKey(tag))
|
while (!caches.ContainsKey(tag))
|
||||||
@ -166,13 +233,12 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
if (semaphore.Wait(0))
|
if (semaphore.Wait(0))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (!caches.ContainsKey(tag))
|
||||||
{
|
{
|
||||||
cache = new CacheItem();
|
cache = new CacheItem();
|
||||||
caches.Add(tag, cache);
|
caches.Add(tag, cache);
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -214,10 +280,6 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
cache.DateObsolete = dateObsolete;
|
cache.DateObsolete = dateObsolete;
|
||||||
cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
|
cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
cache.semaphore.Release();
|
cache.semaphore.Release();
|
||||||
@ -263,7 +325,7 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
public static IEnumerable<TEntity> FromCache<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence)
|
public static IEnumerable<TEntity> FromCache<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence)
|
||||||
where TEntity : class
|
where TEntity : class
|
||||||
{
|
{
|
||||||
IEnumerable factory() => query.AsNoTracking().ToList();
|
object[] factory() => query.AsNoTracking().ToArray();
|
||||||
var cache = GetOrAddCache(tag, factory, obsolescence);
|
var cache = GetOrAddCache(tag, factory, obsolescence);
|
||||||
return cache.GetData<TEntity>();
|
return cache.GetData<TEntity>();
|
||||||
}
|
}
|
||||||
@ -282,7 +344,7 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
public static IEnumerable<TModel> FromCache<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert)
|
public static IEnumerable<TModel> FromCache<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert)
|
||||||
where TEntity : class
|
where TEntity : class
|
||||||
{
|
{
|
||||||
IEnumerable factory() => query.AsNoTracking().ToList();
|
object[] factory() => query.AsNoTracking().ToArray();
|
||||||
var cache = GetOrAddCache(tag, factory, obsolescence);
|
var cache = GetOrAddCache(tag, factory, obsolescence);
|
||||||
return cache.GetData(convert);
|
return cache.GetData(convert);
|
||||||
}
|
}
|
||||||
@ -306,8 +368,8 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
public static async Task<IEnumerable<TEntity>> FromCacheAsync<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, CancellationToken token = default)
|
public static async Task<IEnumerable<TEntity>> FromCacheAsync<TEntity>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, CancellationToken token = default)
|
||||||
where TEntity : class
|
where TEntity : class
|
||||||
{
|
{
|
||||||
async Task<IEnumerable> factory(CancellationToken token)
|
async Task<object[]> factory(CancellationToken token)
|
||||||
=> await query.AsNoTracking().ToListAsync(token);
|
=> await query.AsNoTracking().ToArrayAsync(token);
|
||||||
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
|
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
|
||||||
return cache.GetData<TEntity>();
|
return cache.GetData<TEntity>();
|
||||||
}
|
}
|
||||||
@ -327,8 +389,8 @@ namespace AsbCloudInfrastructure.EfCache
|
|||||||
public static async Task<IEnumerable<TModel>> FromCacheAsync<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert, CancellationToken token = default)
|
public static async Task<IEnumerable<TModel>> FromCacheAsync<TEntity, TModel>(this IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert, CancellationToken token = default)
|
||||||
where TEntity : class
|
where TEntity : class
|
||||||
{
|
{
|
||||||
async Task<IEnumerable> factory(CancellationToken token)
|
async Task<object[]> factory(CancellationToken token)
|
||||||
=> await query.AsNoTracking().ToListAsync(token);
|
=> await query.AsNoTracking().ToArrayAsync(token);
|
||||||
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
|
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
|
||||||
return cache.GetData(convert);
|
return cache.GetData(convert);
|
||||||
}
|
}
|
||||||
|
228
AsbCloudInfrastructure/Repository/UserRepository.cs
Normal file
228
AsbCloudInfrastructure/Repository/UserRepository.cs
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudDb;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure.EfCache;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Repository
|
||||||
|
{
|
||||||
|
#nullable enable
|
||||||
|
public class UserRepository : IUserRepository
|
||||||
|
{
|
||||||
|
private readonly IAsbCloudDbContext dbContext;
|
||||||
|
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>
|
||||||
|
.NewConfig()
|
||||||
|
.Ignore(dst => dst.Company,
|
||||||
|
dst => dst.FileMarks,
|
||||||
|
dst => dst.Files,
|
||||||
|
dst => dst.RelationUsersUserRoles)
|
||||||
|
.Config;
|
||||||
|
|
||||||
|
public UserRepository(IAsbCloudDbContext dbContext, IUserRoleRepository userRoleRepository) {
|
||||||
|
this.dbContext = dbContext;
|
||||||
|
this.userRoleRepository = userRoleRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> InsertRangeAsync(IEnumerable<UserExtendedDto> newItems, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var dtos = (await GetCacheUserAsync(token)).ToList();
|
||||||
|
if (dtos is null)
|
||||||
|
return Enumerable.Empty<UserExtendedDto>();
|
||||||
|
|
||||||
|
for (var i = 0; i < dtos.Count; i++)
|
||||||
|
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id);
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserExtendedDto? GetOrDefault(int id)
|
||||||
|
{
|
||||||
|
var dto = GetCacheUser().FirstOrDefault(u => u.Id == id);
|
||||||
|
if (dto is null)
|
||||||
|
return null;
|
||||||
|
var entity = Convert(dto);
|
||||||
|
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserExtendedDto?> GetOrDefaultAsync(int id, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var dto = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
|
||||||
|
if (dto is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
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 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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> DeleteAsync(int id, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var dto = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
|
||||||
|
if (dto is null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var entity = Convert(dto);
|
||||||
|
var result = dbContext.Users.Remove(entity);
|
||||||
|
await dbContext.SaveChangesAsync(token);
|
||||||
|
DropCacheUsers();
|
||||||
|
return result.Entity.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<UserRoleDto> GetRolesByIdUser(int idUser, int nestedLevel = 0)
|
||||||
|
{
|
||||||
|
var roles = GetCachRelationUserUserRoleCacheTag().Where(r => r.IdUser == idUser);
|
||||||
|
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 Enumerable.Empty<PermissionDto>();
|
||||||
|
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, 7)
|
||||||
|
.Select(r => r.Caption)
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
private async Task AssertLoginIsBusyAsync(string login, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var existingUserDto = (await GetCacheUserAsync(token))
|
||||||
|
.FirstOrDefault(u => u.Login.ToLower() == login.ToLower());
|
||||||
|
|
||||||
|
if (existingUserDto is not null)
|
||||||
|
throw new ArgumentInvalidException($"Login {login} is busy by {existingUserDto.MakeDisplayName()}, id{existingUserDto.Id}", nameof(login));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<IEnumerable<UserExtendedDto>> GetCacheUserAsync(CancellationToken token)
|
||||||
|
=> dbContext.Users
|
||||||
|
.Include(r => r.Company)
|
||||||
|
.Include(r => r.RelationUsersUserRoles)
|
||||||
|
.FromCacheAsync(userCacheTag, cacheObsolence, Convert, token);
|
||||||
|
private IEnumerable<UserExtendedDto> GetCacheUser()
|
||||||
|
=> dbContext.Users
|
||||||
|
.Include(r => r.Company)
|
||||||
|
.Include(r => r.RelationUsersUserRoles)
|
||||||
|
.FromCache(userCacheTag, cacheObsolence, Convert);
|
||||||
|
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);
|
||||||
|
if (string.IsNullOrEmpty(entity.PasswordHash))
|
||||||
|
entity.PasswordHash = dbContext.Users.FirstOrDefault(u => u.Id == dto.Id)?.PasswordHash;
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual UserExtendedDto Convert(User entity)
|
||||||
|
{
|
||||||
|
var dto = entity.Adapt<UserExtendedDto>();
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#nullable disable
|
||||||
|
}
|
293
AsbCloudInfrastructure/Repository/UserRoleRepository.cs
Normal file
293
AsbCloudInfrastructure/Repository/UserRoleRepository.cs
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
using AsbCloudApp.Comparators;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudDb;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure.EfCache;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Repository
|
||||||
|
{
|
||||||
|
#nullable enable
|
||||||
|
public class UserRoleRepository : IUserRoleRepository
|
||||||
|
{
|
||||||
|
private readonly IAsbCloudDbContext dbContext;
|
||||||
|
private const string userRoleCacheTag = "UserRole";
|
||||||
|
private const string relationUserRoleUserRoleCacheTag = "RelationUserRoleUserRole";
|
||||||
|
private const string relationUserRolePermissionsCacheTag = "RelationUserRolePermissions";
|
||||||
|
private static readonly TimeSpan relationCacheObsolence = TimeSpan.FromMinutes(15);
|
||||||
|
|
||||||
|
public UserRoleRepository(IAsbCloudDbContext dbContext)
|
||||||
|
{
|
||||||
|
this.dbContext = dbContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertAsync(UserRoleDto dto, CancellationToken token)
|
||||||
|
{
|
||||||
|
var entity = dto.Adapt<UserRole>();
|
||||||
|
var updatedEntity = await dbContext.UserRoles.AddAsync(entity, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
dto.Id = updatedEntity.Entity.Id;
|
||||||
|
await UpdatePermissionsAsync(dto, token);
|
||||||
|
await UpdateIncludedRolesAsync(dto, token);
|
||||||
|
|
||||||
|
await dbContext.SaveChangesAsync(token);
|
||||||
|
DropCacheUserRole();
|
||||||
|
return updatedEntity.Entity.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> InsertRangeAsync(IEnumerable<UserRoleDto> newItems, CancellationToken token)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<UserRoleDto>> GetAllAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
var entities = await GetCacheUserRoleAsync(token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return entities.Select(Convert);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserRoleDto? GetOrDefault(int id)
|
||||||
|
{
|
||||||
|
var entity = GetCacheUserRole().FirstOrDefault(x => x.Id == id);
|
||||||
|
if (entity is null)
|
||||||
|
return null;
|
||||||
|
return Convert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserRoleDto?> GetOrDefaultAsync(int id, CancellationToken token)
|
||||||
|
{
|
||||||
|
var entity = (await GetCacheUserRoleAsync(token)
|
||||||
|
.ConfigureAwait(false)).FirstOrDefault(r => r.Id == id);
|
||||||
|
if (entity is null)
|
||||||
|
return null;
|
||||||
|
return Convert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<UserRoleDto>> GetByNamesAsync(IEnumerable<string> names, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (names?.Any() != true)
|
||||||
|
return Enumerable.Empty<UserRoleDto>();
|
||||||
|
|
||||||
|
var entities = (await GetCacheUserRoleAsync(token))
|
||||||
|
.Where(r => names.Contains(r.Caption));
|
||||||
|
|
||||||
|
if (entities?.Count() != names.Count())
|
||||||
|
throw new ArgumentInvalidException("Invalid role names", nameof(names));
|
||||||
|
|
||||||
|
return entities.Select(Convert);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateAsync(UserRoleDto dto, CancellationToken token)
|
||||||
|
{
|
||||||
|
var entity = Convert(dto);
|
||||||
|
await UpdatePermissionsAsync(dto, token);
|
||||||
|
await UpdateIncludedRolesAsync(dto, token);
|
||||||
|
|
||||||
|
var result = dbContext.UserRoles.Upsert(entity);
|
||||||
|
await dbContext.SaveChangesAsync(token);
|
||||||
|
DropCacheUserRole();
|
||||||
|
return result.Entity.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<UserRoleDto> GetNestedById(int id, int recursionLevel = 7)
|
||||||
|
{
|
||||||
|
var role = GetCacheUserRole()
|
||||||
|
.FirstOrDefault(r => r.Id == id);
|
||||||
|
if (role is null)
|
||||||
|
return Enumerable.Empty<UserRoleDto>();
|
||||||
|
|
||||||
|
var roles = new SortedSet<UserRoleDto>(ComparerIId.GetInstance()) { Convert(role) };
|
||||||
|
|
||||||
|
if (recursionLevel <= 0 || role.RelationUserRoleUserRoles?.Any() != true)
|
||||||
|
return roles;
|
||||||
|
|
||||||
|
foreach (var relation in role.RelationUserRoleUserRoles)
|
||||||
|
{
|
||||||
|
var nestedRoles = GetNestedById(relation.IdInclude, --recursionLevel);
|
||||||
|
if (nestedRoles?.Any() != true)
|
||||||
|
continue;
|
||||||
|
foreach (var nestedRole in nestedRoles)
|
||||||
|
roles.Add(nestedRole);
|
||||||
|
}
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> DeleteAsync(int id, CancellationToken token)
|
||||||
|
{
|
||||||
|
var entity = (await GetCacheUserRoleAsync(token)).FirstOrDefault(r => r.Id == id);
|
||||||
|
|
||||||
|
if (entity is not null)
|
||||||
|
{
|
||||||
|
var removeEntity = dbContext.UserRoles.Remove(entity);
|
||||||
|
await dbContext.SaveChangesAsync(token);
|
||||||
|
DropCacheUserRole();
|
||||||
|
return removeEntity.Entity.Id;
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasPermission(IEnumerable<int> rolesIds, string permissionName)
|
||||||
|
{
|
||||||
|
var permissionInfo = GetCacheRelationUserRolePermissions()
|
||||||
|
.FirstOrDefault(p => p. Permission?.Name.ToLower() == permissionName.ToLower())
|
||||||
|
?.Permission;
|
||||||
|
|
||||||
|
if (permissionInfo is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (rolesIds.Contains(1))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var idPermissionInfo = permissionInfo.Id;
|
||||||
|
var entities = GetCacheUserRole()
|
||||||
|
.Where(r => rolesIds.Contains(r.Id));
|
||||||
|
|
||||||
|
foreach (var role in entities)
|
||||||
|
if (HasPermission(role, idPermissionInfo))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasPermission(UserRole userRole, int idPermission, int recursionLevel = 7)
|
||||||
|
{
|
||||||
|
if (userRole.RelationUserRolePermissions.Any(p => p.IdPermission == idPermission))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (recursionLevel <= 0 || userRole.RelationUserRoleUserRoles?.Any() != true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var relation in userRole.RelationUserRoleUserRoles)
|
||||||
|
{
|
||||||
|
var entity = GetCacheUserRole()
|
||||||
|
.First(p => p.Id == relation.IdInclude);
|
||||||
|
if (HasPermission(entity, idPermission, --recursionLevel))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateIncludedRolesAsync(UserRoleDto dto, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (dto?.Roles is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var relations = (await GetCacheRelationUserRoleUserRoleAsync(token).ConfigureAwait(false))
|
||||||
|
.Where(r => r.Id == dto.Id);
|
||||||
|
|
||||||
|
dbContext.RelationUserRoleUserRoles.RemoveRange(relations);
|
||||||
|
|
||||||
|
if (dto.Roles.Any())
|
||||||
|
{
|
||||||
|
var newRelations = dto.Roles.Select(r => new RelationUserRoleUserRole { Id = dto.Id, IdInclude = r.Id });
|
||||||
|
await dbContext.RelationUserRoleUserRoles.AddRangeAsync(newRelations, token);
|
||||||
|
await dbContext.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
DropCacheRelationUserRoleUserRole();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdatePermissionsAsync(UserRoleDto dto, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (dto?.Permissions is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var relations = (await GetCacheRelationUserRolePermissionsAsync(token).ConfigureAwait(false))
|
||||||
|
.Where(r => r.IdUserRole == dto.Id);
|
||||||
|
|
||||||
|
dbContext.RelationUserRolePermissions.RemoveRange(relations);
|
||||||
|
|
||||||
|
if (dto.Permissions.Any())
|
||||||
|
{
|
||||||
|
var newRelations = dto.Permissions.Select(p => new RelationUserRolePermission
|
||||||
|
{
|
||||||
|
IdPermission = p.Id,
|
||||||
|
IdUserRole = dto.Id,
|
||||||
|
});
|
||||||
|
|
||||||
|
await dbContext.RelationUserRolePermissions.AddRangeAsync(newRelations, token);
|
||||||
|
await dbContext.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
DropCacheRelationUserRolePermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<IEnumerable<UserRole>> GetCacheUserRoleAsync(CancellationToken token)
|
||||||
|
=> dbContext.UserRoles
|
||||||
|
.Include(r => r.RelationUserRolePermissions)
|
||||||
|
.Include(r => r.RelationUserRoleUserRoles)
|
||||||
|
.Include(r => r.RelationUsersUserRoles)
|
||||||
|
.FromCacheAsync(userRoleCacheTag, relationCacheObsolence, token);
|
||||||
|
private IEnumerable<UserRole> GetCacheUserRole()
|
||||||
|
=> dbContext.UserRoles
|
||||||
|
.Include(r => r.RelationUserRolePermissions)
|
||||||
|
.Include(r => r.RelationUserRoleUserRoles)
|
||||||
|
.Include(r => r.RelationUsersUserRoles)
|
||||||
|
.FromCache(userRoleCacheTag, relationCacheObsolence);
|
||||||
|
private void DropCacheUserRole()
|
||||||
|
=> dbContext.RelationUserUserRoles.DropCache(userRoleCacheTag);
|
||||||
|
|
||||||
|
private Task<IEnumerable<RelationUserRoleUserRole>> GetCacheRelationUserRoleUserRoleAsync(CancellationToken token)
|
||||||
|
=> dbContext.RelationUserRoleUserRoles
|
||||||
|
.Include(r => r.IncludeRole)
|
||||||
|
.Include(r => r.Role)
|
||||||
|
.FromCacheAsync(relationUserRoleUserRoleCacheTag, relationCacheObsolence, token);
|
||||||
|
private void DropCacheRelationUserRoleUserRole()
|
||||||
|
=> dbContext.RelationUserUserRoles.DropCache(relationUserRoleUserRoleCacheTag);
|
||||||
|
|
||||||
|
private Task<IEnumerable<RelationUserRolePermission>> GetCacheRelationUserRolePermissionsAsync(CancellationToken token)
|
||||||
|
=> dbContext.RelationUserRolePermissions
|
||||||
|
.Include(r => r.UserRole)
|
||||||
|
.Include(r => r.Permission)
|
||||||
|
.FromCacheAsync(relationUserRolePermissionsCacheTag, relationCacheObsolence, token);
|
||||||
|
private IEnumerable<RelationUserRolePermission> GetCacheRelationUserRolePermissions()
|
||||||
|
=> dbContext.RelationUserRolePermissions
|
||||||
|
.Include(r => r.UserRole)
|
||||||
|
.Include(r => r.Permission)
|
||||||
|
.FromCache(relationUserRolePermissionsCacheTag, relationCacheObsolence);
|
||||||
|
private void DropCacheRelationUserRolePermissions()
|
||||||
|
=> dbContext.RelationUserRolePermissions.DropCache(relationUserRolePermissionsCacheTag);
|
||||||
|
|
||||||
|
private UserRoleDto Convert(UserRole entity)
|
||||||
|
{
|
||||||
|
var dto = entity.Adapt<UserRoleDto>();
|
||||||
|
if (entity.RelationUserRolePermissions?.Any() == true)
|
||||||
|
{
|
||||||
|
dto.Permissions = GetCacheRelationUserRolePermissions()
|
||||||
|
.Where(r => entity.Id == r.IdUserRole)
|
||||||
|
.Select(r => Convert(r.Permission));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.RelationUserRoleUserRoles?.Any() == true)
|
||||||
|
{
|
||||||
|
var rolesCache = GetCacheUserRole();
|
||||||
|
dto.Roles = entity.RelationUserRoleUserRoles
|
||||||
|
.Select(rel => Convert(rolesCache
|
||||||
|
.First(r => r.Id == rel.IdInclude)))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PermissionDto Convert(Permission entity)
|
||||||
|
{
|
||||||
|
var dto = entity.Adapt<PermissionDto>();
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UserRole Convert(UserRoleDto dto)
|
||||||
|
{
|
||||||
|
var entity = dto.Adapt<UserRole>();
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#nullable disable
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB |
@ -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));
|
||||||
|
@ -18,7 +18,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
public class DetectedOperationService : IDetectedOperationService
|
public class DetectedOperationService : IDetectedOperationService
|
||||||
{
|
{
|
||||||
public const int IdOperationRotor = 1;
|
public const int IdOperationRotor = 2;
|
||||||
public const int IdOperationSlide = 3;
|
public const int IdOperationSlide = 3;
|
||||||
public const int IdOperationSlipsTime = 14;
|
public const int IdOperationSlipsTime = 14;
|
||||||
public const int idOperationFlushing = 22;
|
public const int idOperationFlushing = 22;
|
||||||
@ -84,6 +84,30 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
|||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(int idTelemetry, double depthIntervalRotor, double depthIntervalSlide)>> GetDepthIntervalAllOperationsAsync(IEnumerable<int?> telemetryIds, DateTimeOffset gtDate, DateTimeOffset ltDate, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = db.Set<DetectedOperation>()
|
||||||
|
.Include(o => o.OperationCategory)
|
||||||
|
.Where(o => o.DateStart >= gtDate)
|
||||||
|
.Where(o => o.DateEnd <= ltDate)
|
||||||
|
.Where(o => telemetryIds.Contains(o.IdTelemetry))
|
||||||
|
.GroupBy(g => g.IdTelemetry)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
IdTelemetry = g.Key,
|
||||||
|
RotorDepthInterval = g.Where(o => o.IdCategory == IdOperationRotor).Sum(o => o.DepthEnd - o.DepthStart),
|
||||||
|
SlideDepthInterval = g.Where(o => o.IdCategory == IdOperationSlide).Sum(o => o.DepthEnd - o.DepthStart)
|
||||||
|
});
|
||||||
|
var data = await query.ToArrayAsync(token);
|
||||||
|
var result = data.Select(g =>
|
||||||
|
(
|
||||||
|
g.IdTelemetry,
|
||||||
|
g.RotorDepthInterval,
|
||||||
|
g.SlideDepthInterval
|
||||||
|
));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private static IEnumerable<DetectedOperationDrillersStatDto> GetOperationsDrillersStat(IEnumerable<DetectedOperationDto> operations)
|
private static IEnumerable<DetectedOperationDrillersStatDto> GetOperationsDrillersStat(IEnumerable<DetectedOperationDto> operations)
|
||||||
{
|
{
|
||||||
var groups = operations.GroupBy(o => o.Driller);
|
var groups = operations.GroupBy(o => o.Driller);
|
||||||
@ -301,6 +325,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
|||||||
var exportService = new DetectedOperationExportService(db, wellService);
|
var exportService = new DetectedOperationExportService(db, wellService);
|
||||||
return exportService.ExportAsync(idsWells, token);
|
return exportService.ExportAsync(idsWells, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
: base(context)
|
: base(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
//TODO: Перенести в сервис "дело скважины"
|
||||||
public async Task<IEnumerable<FileCategoryDto>> GetWellCaseCategoriesAsync(CancellationToken token)
|
public async Task<IEnumerable<FileCategoryDto>> GetWellCaseCategoriesAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
var cache = await GetCacheAsync(token)
|
var cache = await GetCacheAsync(token)
|
||||||
|
@ -25,6 +25,10 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
private readonly ICrudService<SubsystemDto> subsystemService;
|
private readonly ICrudService<SubsystemDto> subsystemService;
|
||||||
private readonly IDetectedOperationService detectedOperationService;
|
private readonly IDetectedOperationService detectedOperationService;
|
||||||
|
public const int IdSubsystemAKB = 1;
|
||||||
|
public const int IdSubsystemMSE = 2;
|
||||||
|
public const int IdSubsystemSpin = 65536;
|
||||||
|
public const int IdSubsystemTorque = 65537;
|
||||||
public SubsystemOperationTimeService(IAsbCloudDbContext db, IWellService wellService, ICrudService<SubsystemDto> subsystemService, IDetectedOperationService detectedOperationService)
|
public SubsystemOperationTimeService(IAsbCloudDbContext db, IWellService wellService, ICrudService<SubsystemDto> subsystemService, IDetectedOperationService detectedOperationService)
|
||||||
{
|
{
|
||||||
this.db = db;
|
this.db = db;
|
||||||
@ -75,7 +79,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
data = Trim(data, begin, end);
|
data = Trim(data, begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtos = data.Select(o => Convert(o, well));
|
var dtos = data.Select(o => Convert(o, well.Timezone.Hours));
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +105,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
return null;
|
return null;
|
||||||
var depthInterval = GetDepthInterval(detectedOperations);
|
var depthInterval = GetDepthInterval(detectedOperations);
|
||||||
|
|
||||||
var statList = CalcStat(data,depthInterval,request, token);
|
var statList = CalcStat(data,depthInterval);
|
||||||
return statList;
|
return statList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +129,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<SubsystemStatDto> CalcStat(IEnumerable<SubsystemOperationTimeDto> dtos, (double depthIntervalRotor, double depthIntervalSlide) depthInterval, SubsystemOperationTimeRequest request, CancellationToken token)
|
private IEnumerable<SubsystemStatDto> CalcStat(IEnumerable<SubsystemOperationTimeDto> dtos, (double depthIntervalRotor, double depthIntervalSlide) depthInterval)
|
||||||
{
|
{
|
||||||
var groupedDataSubsystems = dtos
|
var groupedDataSubsystems = dtos
|
||||||
.GroupBy(o => o.IdSubsystem);
|
.GroupBy(o => o.IdSubsystem);
|
||||||
@ -152,9 +156,8 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
private (double depthIntervalRotor, double depthIntervalSlide) GetDepthInterval (IEnumerable<DetectedOperationDto> detectedOperations)
|
private static (double depthIntervalRotor, double depthIntervalSlide) GetDepthInterval (IEnumerable<DetectedOperationDto> detectedOperations)
|
||||||
{
|
{
|
||||||
|
|
||||||
var depthIntervalRotor = detectedOperations.Where(o => o.IdCategory == 1)
|
var depthIntervalRotor = detectedOperations.Where(o => o.IdCategory == 1)
|
||||||
.Sum(o => o.DepthEnd - o.DepthStart);
|
.Sum(o => o.DepthEnd - o.DepthStart);
|
||||||
var depthIntervalSlide = detectedOperations.Where(o => o.IdCategory == 3)
|
var depthIntervalSlide = detectedOperations.Where(o => o.IdCategory == 3)
|
||||||
@ -163,21 +166,21 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
|
|
||||||
return depthInterval;
|
return depthInterval;
|
||||||
}
|
}
|
||||||
private double GetDepthIntervalSubsystem(int idSubsystem, (double depthIntervalRotor, double depthIntervalSlide) depthInterval)
|
private static double GetDepthIntervalSubsystem(int idSubsystem, (double depthIntervalRotor, double depthIntervalSlide) depthInterval)
|
||||||
{
|
{
|
||||||
var depthIntervalSubsystem = 0d;
|
var depthIntervalSubsystem = 0d;
|
||||||
//AKB - MSE
|
//AKB - MSE
|
||||||
if (idSubsystem == 1 | idSubsystem == 2)
|
if (idSubsystem == IdSubsystemAKB | idSubsystem == IdSubsystemMSE)
|
||||||
{
|
{
|
||||||
depthIntervalSubsystem = depthInterval.depthIntervalRotor + depthInterval.depthIntervalSlide;
|
depthIntervalSubsystem = depthInterval.depthIntervalRotor + depthInterval.depthIntervalSlide;
|
||||||
}
|
}
|
||||||
//Spin
|
//Spin
|
||||||
if (idSubsystem == 65536)
|
if (idSubsystem == IdSubsystemSpin)
|
||||||
{
|
{
|
||||||
depthIntervalSubsystem = depthInterval.depthIntervalSlide;
|
depthIntervalSubsystem = depthInterval.depthIntervalSlide;
|
||||||
}
|
}
|
||||||
//Torque
|
//Torque
|
||||||
if (idSubsystem == 65537)
|
if (idSubsystem == IdSubsystemTorque)
|
||||||
{
|
{
|
||||||
depthIntervalSubsystem = depthInterval.depthIntervalRotor;
|
depthIntervalSubsystem = depthInterval.depthIntervalRotor;
|
||||||
}
|
}
|
||||||
@ -185,6 +188,75 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<IEnumerable<WellDto>> GetActiveWellsByCompany(int idCompany, CancellationToken token)
|
||||||
|
{
|
||||||
|
var listWell = await wellService.GetWellsByCompanyAsync(idCompany, token);
|
||||||
|
var active = listWell.Where(w => w.IdState == 1);
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(int idCompany, DateTime? gtDate, DateTime? ltDate, CancellationToken token)
|
||||||
|
{
|
||||||
|
var wells = await GetActiveWellsByCompany(idCompany, token);
|
||||||
|
if (!wells.Any())
|
||||||
|
return Enumerable.Empty<SubsystemActiveWellStatDto>();
|
||||||
|
|
||||||
|
var hoursOffset = wells
|
||||||
|
.FirstOrDefault(well => well.Timezone is not null)
|
||||||
|
?.Timezone.Hours
|
||||||
|
?? 5d;
|
||||||
|
|
||||||
|
var beginUTC = gtDate.HasValue
|
||||||
|
? gtDate.Value.ToUtcDateTimeOffset(hoursOffset)
|
||||||
|
:DateTime.Today.AddDays(-1).ToUtcDateTimeOffset(hoursOffset);
|
||||||
|
|
||||||
|
var endUTC = ltDate.HasValue
|
||||||
|
? ltDate.Value.ToUtcDateTimeOffset(hoursOffset)
|
||||||
|
: DateTime.Today.ToUtcDateTimeOffset(hoursOffset);
|
||||||
|
|
||||||
|
var telemetryIds = wells
|
||||||
|
.Where(w => w.IdTelemetry is not null)
|
||||||
|
.Select(w => w.IdTelemetry)
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
var query = db.SubsystemOperationTimes
|
||||||
|
.Where(o => telemetryIds.Contains(o.IdTelemetry) &&
|
||||||
|
o.DateStart >= beginUTC &&
|
||||||
|
o.DateEnd <= endUTC)
|
||||||
|
.AsNoTracking();
|
||||||
|
|
||||||
|
var subsystemsOperationTime = await query.ToListAsync(token);
|
||||||
|
|
||||||
|
var depthIntervals = await detectedOperationService
|
||||||
|
.GetDepthIntervalAllOperationsAsync(telemetryIds, beginUTC, endUTC, token);
|
||||||
|
|
||||||
|
var result = wells
|
||||||
|
.Select(well => {
|
||||||
|
var dtos = subsystemsOperationTime
|
||||||
|
.Where(s => s.IdTelemetry == well.IdTelemetry)
|
||||||
|
.Select(s => Convert(s, well.Timezone.Hours));
|
||||||
|
|
||||||
|
var (idTelemetry, depthIntervalRotor, depthIntervalSlide) = depthIntervals
|
||||||
|
.FirstOrDefault(i => i.idTelemetry == well.IdTelemetry);
|
||||||
|
|
||||||
|
var subsystemStat = idTelemetry > 0 && dtos.Any()
|
||||||
|
? CalcStat(dtos, (depthIntervalRotor, depthIntervalSlide))
|
||||||
|
: Enumerable.Empty<SubsystemStatDto>();
|
||||||
|
|
||||||
|
return new SubsystemActiveWellStatDto
|
||||||
|
{
|
||||||
|
Well = well,
|
||||||
|
SubsystemAKB = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAKB),
|
||||||
|
SubsystemMSE = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemMSE),
|
||||||
|
SubsystemSpinMaster = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemSpin),
|
||||||
|
SubsystemTorqueMaster = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemTorque),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<DatesRangeDto?> GetDateRangeOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token)
|
public async Task<DatesRangeDto?> GetDateRangeOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token)
|
||||||
{
|
{
|
||||||
@ -261,11 +333,12 @@ namespace AsbCloudInfrastructure.Services.Subsystems
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, WellDto well)
|
private static SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, double? timezoneHours = null)
|
||||||
{
|
{
|
||||||
var dto = operationTime.Adapt<SubsystemOperationTimeDto>();
|
var dto = operationTime.Adapt<SubsystemOperationTimeDto>();
|
||||||
dto.DateStart = operationTime.DateStart.ToRemoteDateTime(well.Timezone.Hours);
|
var hours = timezoneHours ?? operationTime.Telemetry.TimeZone.Hours;
|
||||||
dto.DateEnd = operationTime.DateEnd.ToRemoteDateTime(well.Timezone.Hours);
|
dto.DateStart = operationTime.DateStart.ToRemoteDateTime(hours);
|
||||||
|
dto.DateEnd = operationTime.DateEnd.ToRemoteDateTime(hours);
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,234 +0,0 @@
|
|||||||
using AsbCloudApp.Comparators;
|
|
||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
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 UserRoleService : IUserRoleService
|
|
||||||
{
|
|
||||||
private readonly CacheTable<UserRole> cacheUserRoles;
|
|
||||||
private readonly CacheTable<RelationUserRolePermission> cacheRelationUserRolePermissions;
|
|
||||||
private readonly CacheTable<RelationUserRoleUserRole> cacheRelationUserRoleUserRole;
|
|
||||||
|
|
||||||
public ISet<string> Includes { get; } = new SortedSet<string>();
|
|
||||||
|
|
||||||
public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb)
|
|
||||||
{
|
|
||||||
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context, nameof(UserRole.RelationUserRolePermissions), nameof(UserRole.RelationUserRoleUserRoles));
|
|
||||||
cacheRelationUserRolePermissions = cacheDb.GetCachedTable<RelationUserRolePermission>((AsbCloudDbContext)context, nameof(RelationUserRolePermission.Permission));
|
|
||||||
cacheRelationUserRoleUserRole = cacheDb.GetCachedTable<RelationUserRoleUserRole>((AsbCloudDbContext)context, nameof(RelationUserRoleUserRole.IncludeRole), nameof(RelationUserRoleUserRole.Role));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> InsertAsync(UserRoleDto dto, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var entity = dto.Adapt<UserRole>();
|
|
||||||
var updatedEntity = await cacheUserRoles.InsertAsync(entity, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
dto.Id = updatedEntity.Id;
|
|
||||||
await UpdatePermissionsAsync(dto, token);
|
|
||||||
await UpdateIncludedRolesAsync(dto, token);
|
|
||||||
|
|
||||||
await cacheUserRoles.RefreshAsync(true, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
return updatedEntity?.Id ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<int> InsertRangeAsync(IEnumerable<UserRoleDto> dtos, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
//var entities = dtos.Adapt<UserRole>();
|
|
||||||
//return await cacheUserRoles.InsertAsync(entities, token).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<UserRoleDto>> GetAllAsync(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var entities = await cacheUserRoles.WhereAsync(token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
var dtos = entities?.Select(Convert);
|
|
||||||
return dtos;
|
|
||||||
}
|
|
||||||
public UserRoleDto GetOrDefault(int id)
|
|
||||||
{
|
|
||||||
var entity = cacheUserRoles.FirstOrDefault(r => r.Id == id);
|
|
||||||
if (entity is null)
|
|
||||||
return null;
|
|
||||||
var dto = Convert(entity);
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<UserRoleDto> GetOrDefaultAsync(int id, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var entity = await cacheUserRoles.FirstOrDefaultAsync(r => r.Id == id, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
if (entity is null)
|
|
||||||
return null;
|
|
||||||
var dto = Convert(entity);
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<UserRoleDto>> GetByNamesAsync(IEnumerable<string> names, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (names?.Any() != true)
|
|
||||||
return null;
|
|
||||||
var entities = await cacheUserRoles.WhereAsync(r => names.Contains(r.Caption), token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
if (entities?.Count() != names.Count())
|
|
||||||
throw new ArgumentInvalidException("Invalid role names", nameof(names));
|
|
||||||
var dtos = entities.Select(Convert);
|
|
||||||
return dtos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> UpdateAsync(UserRoleDto dto, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var entity = Convert(dto);
|
|
||||||
await UpdatePermissionsAsync(dto, token);
|
|
||||||
await UpdateIncludedRolesAsync(dto, token);
|
|
||||||
|
|
||||||
var result = await cacheUserRoles.UpsertAsync(entity, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<UserRoleDto> GetNestedById(int id, int recursionLevel = 7)
|
|
||||||
{
|
|
||||||
var role = cacheUserRoles.FirstOrDefault(r => r.Id == id);
|
|
||||||
if (role is null)
|
|
||||||
return null;
|
|
||||||
var dto = Convert(role);
|
|
||||||
var roles = new SortedSet<UserRoleDto>(ComparerIId.GetInstance()) { dto };
|
|
||||||
|
|
||||||
if (recursionLevel <= 0 || role.RelationUserRoleUserRoles?.Any() != true)
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
foreach (var relation in role.RelationUserRoleUserRoles)
|
|
||||||
{
|
|
||||||
var nestedRoles = GetNestedById(relation.IdInclude, --recursionLevel);
|
|
||||||
if (nestedRoles?.Any() != true)
|
|
||||||
continue;
|
|
||||||
foreach (var nestedRole in nestedRoles)
|
|
||||||
roles.Add(nestedRole);
|
|
||||||
}
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task UpdatePermissionsAsync(UserRoleDto dto, CancellationToken token)
|
|
||||||
{
|
|
||||||
if (dto?.Permissions is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
await cacheRelationUserRolePermissions.RemoveAsync(r => r.IdUserRole == dto.Id, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (dto.Permissions.Any())
|
|
||||||
{
|
|
||||||
var newRelationRoleToPermission = dto.Permissions.Select(p => new RelationUserRolePermission
|
|
||||||
{
|
|
||||||
IdPermission = p.Id,
|
|
||||||
IdUserRole = dto.Id,
|
|
||||||
});
|
|
||||||
|
|
||||||
await cacheRelationUserRolePermissions.InsertAsync(newRelationRoleToPermission, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task UpdateIncludedRolesAsync(UserRoleDto dto, CancellationToken token)
|
|
||||||
{
|
|
||||||
if (dto?.Roles is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
await cacheRelationUserRoleUserRole.RemoveAsync(rel => rel.Id == dto.Id, token);
|
|
||||||
|
|
||||||
if (dto.Roles.Any())
|
|
||||||
{
|
|
||||||
var newRelations = dto.Roles.Select(r => new RelationUserRoleUserRole { Id = dto.Id, IdInclude = r.Id });
|
|
||||||
await cacheRelationUserRoleUserRole.UpsertAsync(newRelations, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<int> DeleteAsync(int id, CancellationToken token = default)
|
|
||||||
=> cacheUserRoles.RemoveAsync(r => r.Id == id, token);
|
|
||||||
|
|
||||||
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
|
|
||||||
=> cacheUserRoles.RemoveAsync(r => ids.Contains(r.Id), token);
|
|
||||||
|
|
||||||
public bool HasPermission(IEnumerable<int> rolesIds, string permissionName)
|
|
||||||
{
|
|
||||||
var permissionInfo = cacheRelationUserRolePermissions
|
|
||||||
.FirstOrDefault(p => p.Permission?.Name.ToLower() == permissionName.ToLower())
|
|
||||||
?.Permission;
|
|
||||||
|
|
||||||
if (permissionInfo is null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (rolesIds.Contains(1))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
var idPermissionInfo = permissionInfo.Id;
|
|
||||||
var roles = cacheUserRoles.Where(r => rolesIds.Contains(r.Id));
|
|
||||||
foreach (var role in roles)
|
|
||||||
if (HasPermission(role, idPermissionInfo))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasPermission(UserRole userRole, int idPermission, int recursionLevel = 7)
|
|
||||||
{
|
|
||||||
if (userRole.RelationUserRolePermissions.Any(p => p.IdPermission == idPermission))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (recursionLevel <= 0 || userRole.RelationUserRoleUserRoles?.Any() != true)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
foreach (var relation in userRole.RelationUserRoleUserRoles)
|
|
||||||
{
|
|
||||||
var includedRole = cacheUserRoles.First(p => p.Id == relation.IdInclude);
|
|
||||||
if (HasPermission(includedRole, idPermission, --recursionLevel))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static UserRole Convert(UserRoleDto dto)
|
|
||||||
{
|
|
||||||
var entity = dto.Adapt<UserRole>();
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UserRoleDto Convert(UserRole entity)
|
|
||||||
{
|
|
||||||
var dto = entity.Adapt<UserRoleDto>();
|
|
||||||
if (entity.RelationUserRolePermissions?.Any() == true)
|
|
||||||
{
|
|
||||||
dto.Permissions = cacheRelationUserRolePermissions
|
|
||||||
.Where(r => entity.Id == r.IdUserRole)
|
|
||||||
.Select(r => Convert(r.Permission));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity.RelationUserRoleUserRoles?.Any() == true)
|
|
||||||
{
|
|
||||||
dto.Roles = entity.RelationUserRoleUserRoles.Select(rel =>
|
|
||||||
{
|
|
||||||
var includedRole = cacheUserRoles.First(r => r.Id == rel.IdInclude);
|
|
||||||
return Convert(includedRole);
|
|
||||||
}).ToList();
|
|
||||||
}
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PermissionDto Convert(Permission entity)
|
|
||||||
{
|
|
||||||
var dto = entity.Adapt<PermissionDto>();
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,197 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
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 IUserRoleService 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, IUserRoleService 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
||||||
|
61
AsbCloudWebApi.Tests/CacheTests/CacheTest.cs
Normal file
61
AsbCloudWebApi.Tests/CacheTests/CacheTest.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure.EfCache;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
|
using Mapster;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.Tests.CacheTests
|
||||||
|
{
|
||||||
|
public class CacheTest
|
||||||
|
{
|
||||||
|
private readonly string userCacheTag = "Users";
|
||||||
|
private static readonly TimeSpan cacheObsolence = TimeSpan.FromMinutes(15);
|
||||||
|
public IEnumerable<User> UsersCache = new List<User> {
|
||||||
|
new User { Id = 1, Name = "test1", Email = "test1@mail.com" },
|
||||||
|
new User { Id = 2, Name = "test2", Email = "test2@mail.com" },
|
||||||
|
new User { Id = 3, Name = "test3", Email = "test3@mail.com" },
|
||||||
|
new User { Id = 4, Name = "test4", Email = "test4@mail.com" },
|
||||||
|
new User { Id = 5, Name = "test5", Email = "test5@mail.com" },
|
||||||
|
new User { Id = 6, Name = "test6", Email = "test6@mail.com" },
|
||||||
|
new User { Id = 7, Name = "test7", Email = "test7@mail.com" }
|
||||||
|
};
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Send_n_requests_cache_user()
|
||||||
|
{
|
||||||
|
const int iterations = 1230;
|
||||||
|
var cache = UsersCache.AsQueryable();
|
||||||
|
var cacheCount = UsersCache.Count();
|
||||||
|
var fail = false;
|
||||||
|
|
||||||
|
var tasks = new int[iterations].Select(_=> new Task(() =>
|
||||||
|
{
|
||||||
|
var data = cache.FromCache(userCacheTag, cacheObsolence, Convert).ToArray();
|
||||||
|
if (data.Count() != cacheCount)
|
||||||
|
fail = true;
|
||||||
|
}))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
foreach(var task in tasks)
|
||||||
|
task.Start();
|
||||||
|
|
||||||
|
Task.WaitAll(tasks);
|
||||||
|
Assert.False(fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserExtendedDto Convert(User entity)
|
||||||
|
{
|
||||||
|
var dto = entity.Adapt<UserExtendedDto>();
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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,
|
||||||
|
@ -1,187 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudInfrastructure.Services;
|
|
||||||
using AsbCloudInfrastructure.Services.Cache;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Tests.ServicesTests
|
|
||||||
{
|
|
||||||
public class UserRoleServiceTest
|
|
||||||
{
|
|
||||||
private readonly AsbCloudDbContext context;
|
|
||||||
private readonly CacheDb cacheDb;
|
|
||||||
|
|
||||||
private readonly List<UserRole> roles = new() {
|
|
||||||
new UserRole { Id = 1_000_001, Caption = "role 1 level 0" },
|
|
||||||
new UserRole { Id = 1_000_002, Caption = "role 2 level 1" },
|
|
||||||
new UserRole { Id = 1_000_003, Caption = "role 3 level 1" },
|
|
||||||
new UserRole { Id = 1_000_004, Caption = "role 4 level 2" },
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly List<RelationUserRoleUserRole> relationRoleRole = new()
|
|
||||||
{
|
|
||||||
new RelationUserRoleUserRole { Id = 1_000_002, IdInclude = 1_000_001 },
|
|
||||||
new RelationUserRoleUserRole { Id = 1_000_003, IdInclude = 1_000_001 },
|
|
||||||
new RelationUserRoleUserRole { Id = 1_000_004, IdInclude = 1_000_002 },
|
|
||||||
new RelationUserRoleUserRole { Id = 1_000_004, IdInclude = 1_000_003 },
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly List<Permission> permissions = new()
|
|
||||||
{
|
|
||||||
new Permission { Id = 2_000_001, Name = "permission 1" },
|
|
||||||
new Permission { Id = 2_000_002, Name = "permission 2" },
|
|
||||||
new Permission { Id = 2_000_003, Name = "permission 3" },
|
|
||||||
new Permission { Id = 2_000_004, Name = "permission 4" },
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly List<RelationUserRolePermission> relationRolePermission = new()
|
|
||||||
{
|
|
||||||
new RelationUserRolePermission { IdUserRole = 1_000_001, IdPermission = 2_000_001 },
|
|
||||||
new RelationUserRolePermission { IdUserRole = 1_000_002, IdPermission = 2_000_002 },
|
|
||||||
new RelationUserRolePermission { IdUserRole = 1_000_003, IdPermission = 2_000_003 },
|
|
||||||
new RelationUserRolePermission { IdUserRole = 1_000_004, IdPermission = 2_000_004 },
|
|
||||||
};
|
|
||||||
|
|
||||||
public UserRoleServiceTest()
|
|
||||||
{
|
|
||||||
cacheDb = new CacheDb();
|
|
||||||
context = TestHelpter.MakeTestContext();
|
|
||||||
context.UserRoles.RemoveRange(roles);
|
|
||||||
context.Permissions.RemoveRange(permissions);
|
|
||||||
context.SaveChanges();
|
|
||||||
context.UserRoles.AddRange(roles);
|
|
||||||
context.Permissions.AddRange(permissions);
|
|
||||||
context.SaveChanges();
|
|
||||||
context.RelationUserRoleUserRoles.AddRange(relationRoleRole);
|
|
||||||
context.RelationUserRolePermissions.AddRange(relationRolePermission);
|
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
~UserRoleServiceTest()
|
|
||||||
{
|
|
||||||
context.UserRoles.RemoveRange(roles);
|
|
||||||
context.Permissions.RemoveRange(permissions);
|
|
||||||
context.RelationUserRoleUserRoles.RemoveRange(relationRoleRole);
|
|
||||||
context.RelationUserRolePermissions.RemoveRange(relationRolePermission);
|
|
||||||
context.SaveChanges();
|
|
||||||
context.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetNestedById_return_4_items()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
var nestedRoles = service.GetNestedById(1_000_004);
|
|
||||||
Assert.Equal(roles.Count, nestedRoles.Count());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void HasPermission_return_true()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
var result = service.HasPermission(new int[] { 1_000_004 }, "permission 1");
|
|
||||||
Assert.True(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void HasPermission_return_false()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
var result = service.HasPermission(new int[] { 1_000_003 }, "permission 2");
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task InsertAsync_returns_id()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
var newRole = new UserRoleDto
|
|
||||||
{
|
|
||||||
Caption = "new role",
|
|
||||||
IdType = 0,
|
|
||||||
};
|
|
||||||
var id = await service.InsertAsync(newRole, CancellationToken.None);
|
|
||||||
Assert.NotEqual(0, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task InsertAsync_updates_relation_to_permission()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
var newRole = new UserRoleDto
|
|
||||||
{
|
|
||||||
Caption = "new role",
|
|
||||||
IdType = 0,
|
|
||||||
Permissions = new[] { new PermissionDto { Id = 2_000_001 } },
|
|
||||||
};
|
|
||||||
var id = await service.InsertAsync(newRole, CancellationToken.None);
|
|
||||||
var entity = await service.GetOrDefaultAsync(id);
|
|
||||||
Assert.Equal(newRole.Permissions.Count(), entity.Permissions.Count());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task InsertAsync_updates_relation_to_role()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
var newRole = new UserRoleDto
|
|
||||||
{
|
|
||||||
Caption = "new role",
|
|
||||||
IdType = 0,
|
|
||||||
Roles = new[] { new UserRoleDto { Id = 1_000_001 } }
|
|
||||||
};
|
|
||||||
var id = await service.InsertAsync(newRole, CancellationToken.None);
|
|
||||||
var entity = await service.GetOrDefaultAsync(id);
|
|
||||||
Assert.Equal(newRole.Roles.Count, entity.Roles.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task UpdateAsync_returns_id()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
const int updateId = 1_000_002;
|
|
||||||
var modRole = new UserRoleDto
|
|
||||||
{
|
|
||||||
Id = updateId,
|
|
||||||
Caption = "role 2 level 1"
|
|
||||||
};
|
|
||||||
var id = await service.UpdateAsync(modRole, CancellationToken.None);
|
|
||||||
Assert.Equal(updateId, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task UpdateAsync_updates_relation_to_permission()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
const int updateId = 1_000_002;
|
|
||||||
var modRole = new UserRoleDto
|
|
||||||
{
|
|
||||||
Id = updateId,
|
|
||||||
Caption = "role 2 level 1",
|
|
||||||
Permissions = new[] { new PermissionDto { Id = 2_000_001 } },
|
|
||||||
};
|
|
||||||
var id = await service.UpdateAsync(modRole, CancellationToken.None);
|
|
||||||
var entity = await service.GetOrDefaultAsync(id);
|
|
||||||
Assert.Equal(modRole.Permissions.Count(), entity.Permissions.Count());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task UpdateAsync_updates_relation_to_role()
|
|
||||||
{
|
|
||||||
var service = new UserRoleService(context, cacheDb);
|
|
||||||
const int updateId = 1_000_002;
|
|
||||||
var modRole = new UserRoleDto
|
|
||||||
{
|
|
||||||
Id = updateId,
|
|
||||||
Caption = "role 2 level 1",
|
|
||||||
Roles = new[] { new UserRoleDto { Id = 1_000_001 } }
|
|
||||||
};
|
|
||||||
var id = await service.UpdateAsync(modRole, CancellationToken.None);
|
|
||||||
var entity = await service.GetOrDefaultAsync(id);
|
|
||||||
Assert.Equal(modRole.Roles.Count(), entity.Roles.Count());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
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<IUserRoleService> roleService;
|
|
||||||
|
|
||||||
public UserServiceTest()
|
|
||||||
{
|
|
||||||
context = TestHelpter.MakeTestContext();
|
|
||||||
cacheDb = new CacheDb();
|
|
||||||
roleService = new Mock<IUserRoleService>();
|
|
||||||
|
|
||||||
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, roleService.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, roleService.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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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,
|
||||||
|
@ -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)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -12,9 +13,9 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
[Route("api/admin/role")]
|
[Route("api/admin/role")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class AdminUserRoleController : CrudController<UserRoleDto, IUserRoleService>
|
public class AdminUserRoleController : CrudController<UserRoleDto, IUserRoleRepository>
|
||||||
{
|
{
|
||||||
public AdminUserRoleController(IUserRoleService service)
|
public AdminUserRoleController(IUserRoleRepository service)
|
||||||
: base(service)
|
: base(service)
|
||||||
{
|
{
|
||||||
UpdateForbidAsync = async (dto, token) =>
|
UpdateForbidAsync = async (dto, token) =>
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -46,6 +46,24 @@ namespace AsbCloudWebApi.Controllers.Subsystems
|
|||||||
return Ok(subsystemResult);
|
return Ok(subsystemResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// получить статистику по активным скважинам
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="GtDate"> Больше или равно дате </param>
|
||||||
|
/// <param name="LtDate"> Меньше или равно дате </param>
|
||||||
|
/// <param name="token"> Токен </param>
|
||||||
|
/// <returns> </returns>
|
||||||
|
[HttpGet("statByActiveWell")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<SubsystemActiveWellStatDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||||
|
public async Task<IActionResult> GetStatByWellAsync(DateTime? GtDate, DateTime? LtDate, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var idCompany = User.GetCompanyId();
|
||||||
|
if (!idCompany.HasValue)
|
||||||
|
return Forbid();
|
||||||
|
var subsystemResult = await subsystemOperationTimeService.GetStatByActiveWells(idCompany.Value, GtDate, LtDate, token);
|
||||||
|
return Ok(subsystemResult);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// получить список подсистем общий.
|
/// получить список подсистем общий.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -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,8 +70,8 @@ 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(idUser!.Value, permissionName);
|
isAuthorized = userService.HasPermission(idUser.Value, permissionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAuthorized)
|
if (isAuthorized)
|
||||||
|
Loading…
Reference in New Issue
Block a user