forked from ddrilling/AsbCloudServer
Add/refactor services for permissions authorization model.
Rename some fields in DB.permission.
This commit is contained in:
parent
1ec22744c3
commit
551c60c4ff
@ -1,9 +1,7 @@
|
|||||||
namespace AsbCloudApp.Data
|
namespace AsbCloudApp.Data
|
||||||
{
|
{
|
||||||
public class PermissionDto
|
public class PermissionDto : PermissionBaseDto
|
||||||
{
|
{
|
||||||
public int IdUserRole { get; set; }
|
public int IdUserRole { get; set; }
|
||||||
public int IdPermission { get; set; }
|
|
||||||
public int PermissionValue { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
9
AsbCloudApp/Data/PermissionRoleDto.cs
Normal file
9
AsbCloudApp/Data/PermissionRoleDto.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace AsbCloudApp.Data
|
||||||
|
{
|
||||||
|
public class PermissionBaseDto
|
||||||
|
{
|
||||||
|
public int IdPermissionInfo { get; set; }
|
||||||
|
public string PermissionName { get; set; }
|
||||||
|
public int Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class UserBaseDto
|
|
||||||
{
|
|
||||||
public string Login { get; set; }
|
|
||||||
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public string Surname { get; set; }
|
|
||||||
|
|
||||||
public string Patronymic { get; set; }
|
|
||||||
|
|
||||||
public string Email { get; set; }
|
|
||||||
|
|
||||||
public string Phone { get; set; }
|
|
||||||
|
|
||||||
public string Position { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +1,16 @@
|
|||||||
namespace AsbCloudApp.Data
|
namespace AsbCloudApp.Data
|
||||||
{
|
{
|
||||||
public class UserDto : UserBaseDto, IId
|
public class UserDto: IId
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
public string Login { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Surname { get; set; }
|
||||||
|
public string Patronymic { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string Phone { get; set; }
|
||||||
|
public string Position { get; set; }
|
||||||
public int? IdCompany { get; set; }
|
public int? IdCompany { get; set; }
|
||||||
|
|
||||||
public string Password { get; set; }
|
|
||||||
|
|
||||||
public CompanyDto Company { get; set; }
|
public CompanyDto Company { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
AsbCloudApp/Data/UserExtendedDto.cs
Normal file
9
AsbCloudApp/Data/UserExtendedDto.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data
|
||||||
|
{
|
||||||
|
public class UserExtendedDto : UserDto
|
||||||
|
{
|
||||||
|
public IEnumerable<string> RoleNames { get; set; }
|
||||||
|
}
|
||||||
|
}
|
9
AsbCloudApp/Data/UserRegistrationDto.cs
Normal file
9
AsbCloudApp/Data/UserRegistrationDto.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data
|
||||||
|
{
|
||||||
|
public class UserRegistrationDto : UserDto
|
||||||
|
{
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ namespace AsbCloudApp.Data
|
|||||||
public string Caption { get; set; }
|
public string Caption { get; set; }
|
||||||
public int? IdParent { get; set; }
|
public int? IdParent { get; set; }
|
||||||
public int IdType { get; set; }
|
public int IdType { get; set; }
|
||||||
public IEnumerable<PermissionDto> Permissions { get; set; }
|
public IEnumerable<PermissionBaseDto> Permissions { get; set; }
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public virtual ICollection<UserDto> Users { get; set; }
|
public virtual ICollection<UserDto> Users { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,9 @@
|
|||||||
|
|
||||||
namespace AsbCloudApp.Data
|
namespace AsbCloudApp.Data
|
||||||
{
|
{
|
||||||
public class UserTokenDto : UserBaseDto
|
public class UserTokenDto : UserExtendedDto
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public IEnumerable<PermissionBaseDto> Permissions { get; set; }
|
||||||
public string CompanyName { get; set; }
|
|
||||||
public IEnumerable<string> RoleNames { get; set; }
|
|
||||||
public IDictionary<string, int> Permissions { get; set; }
|
|
||||||
public string Token { get; set; }
|
public string Token { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,6 @@ namespace AsbCloudApp.Services
|
|||||||
string password, CancellationToken token = default);
|
string password, CancellationToken token = default);
|
||||||
|
|
||||||
string Refresh(ClaimsPrincipal user);
|
string Refresh(ClaimsPrincipal user);
|
||||||
int Register(UserDto userDto);
|
int Register(UserRegistrationDto userDto);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,15 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
namespace AsbCloudApp.Services
|
||||||
{
|
{
|
||||||
public interface IUserRoleService: ICrudService<UserRoleDto>
|
public interface IUserRoleService : ICrudService<UserRoleDto>
|
||||||
{
|
{
|
||||||
|
Task<UserRoleDto> GetByNameAsync(string name, CancellationToken token = default);
|
||||||
|
List<UserRoleDto> GetNestedById(int id, int counter = 10);
|
||||||
|
IEnumerable<PermissionBaseDto> GetNestedPermissions(IEnumerable<UserRoleDto> roles);
|
||||||
|
bool HasPermission(IEnumerable<int> rolesIds, string permissionName, int permissionMask = 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
15
AsbCloudApp/Services/IUserService.cs
Normal file
15
AsbCloudApp/Services/IUserService.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using AsbCloudApp.Data;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Services
|
||||||
|
{
|
||||||
|
public interface IUserService : ICrudService<UserExtendedDto>
|
||||||
|
{
|
||||||
|
IUserRoleService RoleService { get; }
|
||||||
|
IEnumerable<PermissionBaseDto> GetNestedPermissions(int idUser);
|
||||||
|
IEnumerable<UserRoleDto> GetRolesByIdUser(int idUser);
|
||||||
|
bool HasAnyRoleOf(int idUser, IEnumerable<string> roleNames);
|
||||||
|
bool HasAnyRoleOf(int idUser, IEnumerable<int> roleIds);
|
||||||
|
public bool HasPermission(int idUser, string permissionName, int permissionMask = 0);
|
||||||
|
}
|
||||||
|
}
|
2978
AsbCloudDb/Migrations/20211210074746_Rename_Permissions_fields.Designer.cs
generated
Normal file
2978
AsbCloudDb/Migrations/20211210074746_Rename_Permissions_fields.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Migrations
|
||||||
|
{
|
||||||
|
public partial class Rename_Permissions_fields : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_t_permission_t_permission_info_id_permission",
|
||||||
|
table: "t_permission");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "permission_value",
|
||||||
|
table: "t_permission",
|
||||||
|
newName: "value");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "id_permission",
|
||||||
|
table: "t_permission",
|
||||||
|
newName: "id_permission_info");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_t_permission_id_permission",
|
||||||
|
table: "t_permission",
|
||||||
|
newName: "IX_t_permission_id_permission_info");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_t_permission_t_permission_info_id_permission_info",
|
||||||
|
table: "t_permission",
|
||||||
|
column: "id_permission_info",
|
||||||
|
principalTable: "t_permission_info",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_t_permission_t_permission_info_id_permission_info",
|
||||||
|
table: "t_permission");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "value",
|
||||||
|
table: "t_permission",
|
||||||
|
newName: "permission_value");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "id_permission_info",
|
||||||
|
table: "t_permission",
|
||||||
|
newName: "id_permission");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_t_permission_id_permission_info",
|
||||||
|
table: "t_permission",
|
||||||
|
newName: "IX_t_permission_id_permission");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_t_permission_t_permission_info_id_permission",
|
||||||
|
table: "t_permission",
|
||||||
|
column: "id_permission",
|
||||||
|
principalTable: "t_permission_info",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -687,17 +687,17 @@ namespace AsbCloudDb.Migrations
|
|||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("id_user_role");
|
.HasColumnName("id_user_role");
|
||||||
|
|
||||||
b.Property<int>("IdPermission")
|
b.Property<int>("IdPermissionInfo")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("id_permission");
|
.HasColumnName("id_permission_info");
|
||||||
|
|
||||||
b.Property<int>("PermissionValue")
|
b.Property<int>("Value")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("permission_value");
|
.HasColumnName("value");
|
||||||
|
|
||||||
b.HasKey("IdUserRole", "IdPermission");
|
b.HasKey("IdUserRole", "IdPermissionInfo");
|
||||||
|
|
||||||
b.HasIndex("IdPermission");
|
b.HasIndex("IdPermissionInfo");
|
||||||
|
|
||||||
b.ToTable("t_permission");
|
b.ToTable("t_permission");
|
||||||
|
|
||||||
@ -2605,7 +2605,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
{
|
{
|
||||||
b.HasOne("AsbCloudDb.Model.PermissionInfo", "PermissionInfo")
|
b.HasOne("AsbCloudDb.Model.PermissionInfo", "PermissionInfo")
|
||||||
.WithMany("Permissions")
|
.WithMany("Permissions")
|
||||||
.HasForeignKey("IdPermission")
|
.HasForeignKey("IdPermissionInfo")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ namespace AsbCloudDb.Model
|
|||||||
|
|
||||||
modelBuilder.Entity<Permission>(entity =>
|
modelBuilder.Entity<Permission>(entity =>
|
||||||
{
|
{
|
||||||
entity.HasKey(e => new { e.IdUserRole, e.IdPermission });
|
entity.HasKey(e => new { e.IdUserRole, e.IdPermissionInfo });
|
||||||
});
|
});
|
||||||
|
|
||||||
FillData(modelBuilder);
|
FillData(modelBuilder);
|
||||||
@ -456,13 +456,6 @@ namespace AsbCloudDb.Model
|
|||||||
select well;
|
select well;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<User> GetUsersByLogin(string login)
|
|
||||||
=> Users
|
|
||||||
.Include(e => e.RelationUsersUserRoles)
|
|
||||||
.ThenInclude(r => r.UserRole)
|
|
||||||
.Include(e => e.Company)
|
|
||||||
.Where(e => e.Login == login);
|
|
||||||
|
|
||||||
public async Task<(DateTime From, DateTime To)> GetDatesRangeAsync<TEntity>(int idTelemetry,
|
public async Task<(DateTime From, DateTime To)> GetDatesRangeAsync<TEntity>(int idTelemetry,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
where TEntity : class, ITelemetryData
|
where TEntity : class, ITelemetryData
|
||||||
|
@ -51,7 +51,6 @@ namespace AsbCloudDb.Model
|
|||||||
DbSet<TEntity> Set<TEntity>() where TEntity : class;
|
DbSet<TEntity> Set<TEntity>() where TEntity : class;
|
||||||
|
|
||||||
IQueryable<Well> GetWellsForCompany(int idCompany);
|
IQueryable<Well> GetWellsForCompany(int idCompany);
|
||||||
IQueryable<User> GetUsersByLogin(string login);
|
|
||||||
Task<(DateTime From, DateTime To)> GetDatesRangeAsync<T>(int idTelemetry, CancellationToken token) where T : class, ITelemetryData;
|
Task<(DateTime From, DateTime To)> GetDatesRangeAsync<T>(int idTelemetry, CancellationToken token) where T : class, ITelemetryData;
|
||||||
Task<IEnumerable<(double? MinDepth, double? MaxDepth, DateTime BeginPeriodDate)>> GetDepthToIntervalAsync(int telemetryId,
|
Task<IEnumerable<(double? MinDepth, double? MaxDepth, DateTime BeginPeriodDate)>> GetDepthToIntervalAsync(int telemetryId,
|
||||||
int intervalHoursTimestamp, int workStartTimestamp, double timezoneOffset, CancellationToken token);
|
int intervalHoursTimestamp, int workStartTimestamp, double timezoneOffset, CancellationToken token);
|
||||||
|
@ -9,17 +9,17 @@ namespace AsbCloudDb.Model
|
|||||||
[Column("id_user_role")]
|
[Column("id_user_role")]
|
||||||
public int IdUserRole { get; set; }
|
public int IdUserRole { get; set; }
|
||||||
|
|
||||||
[Column("id_permission")]
|
[Column("id_permission_info")]
|
||||||
public int IdPermission { get; set; }
|
public int IdPermissionInfo { get; set; }
|
||||||
|
|
||||||
[Column("permission_value")]
|
[Column("value")]
|
||||||
public int PermissionValue { get; set; }
|
public int Value { get; set; }
|
||||||
|
|
||||||
[ForeignKey(nameof(IdUserRole))]
|
[ForeignKey(nameof(IdUserRole))]
|
||||||
[InverseProperty(nameof(Model.UserRole.Permissions))]
|
[InverseProperty(nameof(Model.UserRole.Permissions))]
|
||||||
public virtual UserRole UserRole { get; set; }
|
public virtual UserRole UserRole { get; set; }
|
||||||
|
|
||||||
[ForeignKey(nameof(IdPermission))]
|
[ForeignKey(nameof(IdPermissionInfo))]
|
||||||
[InverseProperty(nameof(Model.PermissionInfo.Permissions))]
|
[InverseProperty(nameof(Model.PermissionInfo.Permissions))]
|
||||||
public virtual PermissionInfo PermissionInfo { get; set; }
|
public virtual PermissionInfo PermissionInfo { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,16 @@
|
|||||||
# Миграции
|
# Миграции
|
||||||
|
## EF tools
|
||||||
|
https://docs.microsoft.com/ru-ru/ef/core/cli/dotnet
|
||||||
|
|
||||||
|
Установка:
|
||||||
|
```
|
||||||
|
dotnet tool install --global dotnet-ef
|
||||||
|
```
|
||||||
|
Обновление:
|
||||||
|
```
|
||||||
|
dotnet tool update --global dotnet-ef
|
||||||
|
```
|
||||||
|
|
||||||
## Создать миграцию
|
## Создать миграцию
|
||||||
```
|
```
|
||||||
dotnet ef migrations add <MigrationName> --project AsbCloudDb
|
dotnet ef migrations add <MigrationName> --project AsbCloudDb
|
||||||
|
@ -56,6 +56,7 @@ 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<IUserRoleService, UserRoleService>();
|
||||||
services.AddTransient<IWellService, WellService>();
|
services.AddTransient<IWellService, WellService>();
|
||||||
services.AddTransient<IWellCompositeService, WellCompositeService>();
|
services.AddTransient<IWellCompositeService, WellCompositeService>();
|
||||||
@ -64,7 +65,6 @@ namespace AsbCloudInfrastructure
|
|||||||
|
|
||||||
// admin crud services:
|
// admin crud services:
|
||||||
services.AddTransient<ICrudService<WellDto>, CrudServiceBase<WellDto, Well>>();
|
services.AddTransient<ICrudService<WellDto>, CrudServiceBase<WellDto, Well>>();
|
||||||
services.AddTransient<ICrudService<UserDto>, CrudServiceBase<UserDto, User>>();
|
|
||||||
services.AddTransient<ICrudService<TelemetryDto>, CrudServiceBase<TelemetryDto, Telemetry>>();
|
services.AddTransient<ICrudService<TelemetryDto>, CrudServiceBase<TelemetryDto, Telemetry>>();
|
||||||
services.AddTransient<ICrudService<PermissionInfoDto>, CrudServiceBase<PermissionInfoDto, PermissionInfo>>();
|
services.AddTransient<ICrudService<PermissionInfoDto>, CrudServiceBase<PermissionInfoDto, PermissionInfo>>();
|
||||||
services.AddTransient<ICrudService<DrillParamsDto>, DrillParamsService>();
|
services.AddTransient<ICrudService<DrillParamsDto>, DrillParamsService>();
|
||||||
|
@ -13,16 +13,14 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudInfrastructure.Services.Cache;
|
using AsbCloudInfrastructure.Services.Cache;
|
||||||
|
using Mapster;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services
|
namespace AsbCloudInfrastructure.Services
|
||||||
{
|
{
|
||||||
public class AuthService : IAuthService
|
public class AuthService : IAuthService
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
private readonly IAsbCloudDbContext db;
|
||||||
private readonly CacheTable<UserRole> cacheUserRoles;
|
private readonly IUserService userService;
|
||||||
private readonly CacheTable<RelationUserUserRole> cacheUsersUserRoles;
|
|
||||||
private readonly CacheTable<PermissionInfo> cachePermissions;
|
|
||||||
private readonly CacheTable<Permission> cacheUserRolesPermissions;
|
|
||||||
|
|
||||||
public const string issuer = "a";
|
public const string issuer = "a";
|
||||||
public const string audience = "a";
|
public const string audience = "a";
|
||||||
@ -37,13 +35,10 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
private readonly HashAlgorithm hashAlgorithm;
|
private readonly HashAlgorithm hashAlgorithm;
|
||||||
private readonly Random rnd;
|
private readonly Random rnd;
|
||||||
|
|
||||||
public AuthService(IAsbCloudDbContext db, CacheDb cacheDb)
|
public AuthService(IAsbCloudDbContext db, CacheDb cacheDb, IUserService userService)
|
||||||
{
|
{
|
||||||
this.db = db;
|
this.db = db;
|
||||||
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)db);
|
this.userService = userService;
|
||||||
cacheUsersUserRoles = cacheDb.GetCachedTable<RelationUserUserRole>((AsbCloudDbContext)db);
|
|
||||||
cachePermissions = cacheDb.GetCachedTable<PermissionInfo>((AsbCloudDbContext)db);
|
|
||||||
cacheUserRolesPermissions = cacheDb.GetCachedTable<Permission>((AsbCloudDbContext)db);
|
|
||||||
hashAlgorithm = SHA384.Create();
|
hashAlgorithm = SHA384.Create();
|
||||||
rnd = new Random((int)(DateTime.Now.Ticks % 2147480161));
|
rnd = new Random((int)(DateTime.Now.Ticks % 2147480161));
|
||||||
}
|
}
|
||||||
@ -57,22 +52,13 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
if (identity == default || user.State == 0)
|
if (identity == default || user.State == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var userRoles = GetUserRoles(user.Id);
|
var userDto = await userService.GetAsync(user.Id, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
var roleNames = userRoles.Select(r => r.Caption);
|
|
||||||
|
|
||||||
return new UserTokenDto
|
var userTokenDto = userDto.Adapt<UserTokenDto>();
|
||||||
{
|
userTokenDto.Permissions = userService.GetNestedPermissions(userDto.Id);
|
||||||
Id = user.Id,
|
userTokenDto.Token = MakeToken(identity.Claims);
|
||||||
Name = user.Name,
|
return userTokenDto;
|
||||||
CompanyName = user.Company.Caption,
|
|
||||||
Login = user.Login,
|
|
||||||
Patronymic = user.Patronymic,
|
|
||||||
RoleNames = roleNames,
|
|
||||||
Permissions = GetUserPermissions(userRoles),
|
|
||||||
Surname = user.Surname,
|
|
||||||
Token = MakeToken(identity.Claims),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Refresh(ClaimsPrincipal user)
|
public string Refresh(ClaimsPrincipal user)
|
||||||
@ -80,7 +66,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
return MakeToken(user.Claims);
|
return MakeToken(user.Claims);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Register(UserDto userDto)
|
public int Register(UserRegistrationDto userDto)
|
||||||
{
|
{
|
||||||
if (userDto.Login is null || userDto.Login.Length is < 3 or > 50)
|
if (userDto.Login is null || userDto.Login.Length is < 3 or > 50)
|
||||||
return -1;
|
return -1;
|
||||||
@ -177,33 +163,12 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
return new JwtSecurityTokenHandler().WriteToken(jwt);
|
return new JwtSecurityTokenHandler().WriteToken(jwt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<UserRole> GetUserRoles(int idUser)
|
|
||||||
{
|
|
||||||
var userRolesIds = cacheUsersUserRoles.Where(r =>
|
|
||||||
r.IdUser == idUser).Select(r => r.IdUserRole);
|
|
||||||
|
|
||||||
return cacheUserRoles.Where(r => userRolesIds.Contains(r.Id));
|
|
||||||
}
|
|
||||||
|
|
||||||
private IDictionary<string, int> GetUserPermissions(IEnumerable<UserRole> userRoles)
|
|
||||||
{
|
|
||||||
var rolesIds = userRoles.Select(r => r.Id);
|
|
||||||
var userPermissionsInfo = cacheUserRolesPermissions.Where(p =>
|
|
||||||
rolesIds.Contains(p.IdUserRole))
|
|
||||||
.Select(perm => new { perm.IdPermission, perm.PermissionValue });
|
|
||||||
|
|
||||||
return userPermissionsInfo.Select(p => new
|
|
||||||
{
|
|
||||||
PermissionName = cachePermissions.FirstOrDefault(c => c.Id == p.IdPermission)?.Name,
|
|
||||||
p.PermissionValue
|
|
||||||
}).ToDictionary(k => k.PermissionName, v => v.PermissionValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<(ClaimsIdentity Identity, User User)> GetClaimsUserAsync(string login,
|
private async Task<(ClaimsIdentity Identity, User User)> GetClaimsUserAsync(string login,
|
||||||
string password, CancellationToken token = default)
|
string password, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var user = await db
|
var user = await db.Users
|
||||||
.GetUsersByLogin(login)
|
.Include(e => e.Company)
|
||||||
|
.Where(e => e.Login == login)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.FirstOrDefaultAsync(token)
|
.FirstOrDefaultAsync(token)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
@ -220,6 +185,10 @@ 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);
|
||||||
|
if (roles is not null)
|
||||||
|
foreach (var role in roles)
|
||||||
|
claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role.Caption));
|
||||||
|
|
||||||
var claimsIdentity = new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
|
var claimsIdentity = new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
|
||||||
return (claimsIdentity, user);
|
return (claimsIdentity, user);
|
||||||
|
@ -31,10 +31,10 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<int> InsertRangeAsync(IEnumerable<PermissionDto> dtos, CancellationToken token)
|
public async Task<int> InsertRangeAsync(IEnumerable<PermissionDto> dtos, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entities = dtos.Select(Convert);
|
var entities = dtos.Select(Convert);
|
||||||
return cachePermission.InsertAsync(entities, token);
|
return (await cachePermission.InsertAsync(entities, token))?.Count()??0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> UpdateAsync(PermissionDto dto, CancellationToken token)
|
public async Task<int> UpdateAsync(PermissionDto dto, CancellationToken token)
|
||||||
@ -47,7 +47,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
|
|
||||||
public Task<int> DeleteAsync(int idUserRole, int idPermission, CancellationToken token)
|
public Task<int> DeleteAsync(int idUserRole, int idPermission, CancellationToken token)
|
||||||
{
|
{
|
||||||
bool predicate(Permission p) => p.IdUserRole == idUserRole && p.IdPermission == idPermission;
|
bool predicate(Permission p) => p.IdUserRole == idUserRole && p.IdPermissionInfo == idPermission;
|
||||||
return DeleteAsync(predicate, token);
|
return DeleteAsync(predicate, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,9 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
public PermissionDto Convert(Permission src)
|
public PermissionDto Convert(Permission src)
|
||||||
{
|
{
|
||||||
var dto = src.Adapt<PermissionDto>();
|
var dto = src.Adapt<PermissionDto>();
|
||||||
|
dto.PermissionName = src.PermissionInfo?.Name;
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,22 +8,42 @@ using AsbCloudDb.Model;
|
|||||||
using AsbCloudInfrastructure.Services.Cache;
|
using AsbCloudInfrastructure.Services.Cache;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services
|
namespace AsbCloudInfrastructure.Services
|
||||||
{
|
{
|
||||||
public class UserRoleService : IUserRoleService
|
public class UserRoleService : IUserRoleService
|
||||||
{
|
{
|
||||||
private readonly CacheTable<UserRole> cacheUserRoles;
|
private readonly CacheTable<UserRole> cacheUserRoles;
|
||||||
|
private readonly CacheTable<PermissionInfo> cachePermissionInfo;
|
||||||
private readonly IPermissionService permissionService;
|
private readonly IPermissionService permissionService;
|
||||||
|
|
||||||
public List<string> Includes { get; } = new();
|
public List<string> Includes { get; } = new();
|
||||||
|
|
||||||
public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb, IPermissionService permissionService)
|
public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb, IPermissionService permissionService)
|
||||||
{
|
{
|
||||||
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context, new [] { nameof(UserRole.Permissions) });
|
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context, new [] { nameof(UserRole.Permissions) });
|
||||||
|
cachePermissionInfo = cacheDb.GetCachedTable<PermissionInfo>((AsbCloudDbContext)context);
|
||||||
this.permissionService = permissionService;
|
this.permissionService = permissionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertAsync(UserRoleDto dto, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var entity = dto.Adapt<UserRole>();
|
||||||
|
var updatedEntity = await cacheUserRoles.InsertAsync(entity, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
await UpdatePermissionsAsync(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)
|
public async Task<IEnumerable<UserRoleDto>> GetAllAsync(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var entities = await cacheUserRoles.WhereAsync(token)
|
var entities = await cacheUserRoles.WhereAsync(token)
|
||||||
@ -40,60 +60,98 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> InsertAsync(UserRoleDto dto, CancellationToken token = default)
|
public async Task<UserRoleDto> GetByNameAsync(string name, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var entity = dto.Adapt<UserRole>();
|
var entity = await cacheUserRoles.FirstOrDefaultAsync(r => r.Caption == name, token)
|
||||||
var updatedEntity = await cacheUserRoles.InsertAsync(entity, token).ConfigureAwait(false);
|
|
||||||
if (dto.Permissions?.Any() != true)
|
|
||||||
return updatedEntity?.Id ?? 0;
|
|
||||||
foreach (var permission in dto.Permissions)
|
|
||||||
permission.IdUserRole = updatedEntity.Id;
|
|
||||||
await permissionService.InsertRangeAsync(dto.Permissions, token).ConfigureAwait(false);
|
|
||||||
await cacheUserRoles.RefreshAsync(true, token)
|
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
return updatedEntity?.Id ?? 0;
|
var dto = entity?.Adapt<UserRoleDto>();
|
||||||
}
|
return dto;
|
||||||
|
|
||||||
public async Task<int> InsertRangeAsync(IEnumerable<UserRoleDto> dtos, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var entities = dtos.Adapt<UserRole>();
|
|
||||||
return await cacheUserRoles.InsertAsync(entities, token).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> UpdateAsync(int id, UserRoleDto dto, CancellationToken token = default)
|
public async Task<int> UpdateAsync(int id, UserRoleDto dto, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
dto.Id = id;
|
||||||
var entity = dto.Adapt<UserRole>();
|
var entity = dto.Adapt<UserRole>();
|
||||||
entity.Id = id;
|
await UpdatePermissionsAsync(dto, token);
|
||||||
|
|
||||||
await cacheUserRoles.UpsertAsync(entity, token)
|
await cacheUserRoles.UpsertAsync(entity, token)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
if(dto.Permissions is not null)
|
|
||||||
{
|
|
||||||
await permissionService.DeleteAllByRoleAsync(id, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (dto.Permissions.Any())
|
|
||||||
{
|
|
||||||
foreach (var permission in dto.Permissions)
|
|
||||||
permission.IdUserRole = id;
|
|
||||||
|
|
||||||
await permissionService.InsertRangeAsync(dto.Permissions, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
await cacheUserRoles.RefreshAsync(true, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<Permission> GetNestedPermissions(UserRole role, int counter = 10)
|
public List<UserRoleDto> GetNestedById(int id, int recursionLevel = 7)
|
||||||
|
{
|
||||||
|
var role = cacheUserRoles.FirstOrDefault(r => r.Id == id);
|
||||||
|
if (role is null)
|
||||||
|
return null;
|
||||||
|
var dto = role.Adapt<UserRoleDto>();
|
||||||
|
if (role.IdParent is null || recursionLevel == 0)
|
||||||
|
return new List<UserRoleDto> { dto };
|
||||||
|
var parentRoles = GetNestedById((int)role.IdParent, --recursionLevel) ??
|
||||||
|
new List<UserRoleDto>();
|
||||||
|
parentRoles.Add(dto);
|
||||||
|
return parentRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<PermissionBaseDto> GetNestedPermissions(IEnumerable<UserRoleDto> roles)
|
||||||
|
{
|
||||||
|
var permissions = new Dictionary<int, PermissionBaseDto>(16);
|
||||||
|
foreach (var roleDto in roles)
|
||||||
|
{
|
||||||
|
var role = cacheUserRoles.FirstOrDefault(r => r.Id == roleDto.Id);
|
||||||
|
var rolePermissions = GetNestedPermissions(role, 10);
|
||||||
|
if ((rolePermissions?.Any()) != true)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var newPermission in rolePermissions)
|
||||||
|
{
|
||||||
|
if (permissions.ContainsKey(newPermission.IdPermissionInfo))
|
||||||
|
{
|
||||||
|
permissions[newPermission.IdPermissionInfo].Value |= newPermission.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
permissions.Add(newPermission.IdPermissionInfo,
|
||||||
|
new PermissionBaseDto
|
||||||
|
{
|
||||||
|
IdPermissionInfo = newPermission.IdPermissionInfo,
|
||||||
|
PermissionName = newPermission.PermissionInfo?.Name ??
|
||||||
|
cachePermissionInfo.FirstOrDefault(p => p.Id == newPermission.IdPermissionInfo).Name,
|
||||||
|
Value = newPermission.Value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions.Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdatePermissionsAsync(UserRoleDto roleDto, CancellationToken token)
|
||||||
|
{
|
||||||
|
await permissionService.DeleteAllByRoleAsync(roleDto.Id, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
if (!roleDto.Permissions.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var newPermissions = roleDto.Permissions.Select(p => new PermissionDto
|
||||||
|
{
|
||||||
|
IdPermissionInfo = p.IdPermissionInfo,
|
||||||
|
IdUserRole = roleDto.Id,
|
||||||
|
PermissionName = p.PermissionName,
|
||||||
|
Value = p.Value,
|
||||||
|
});
|
||||||
|
|
||||||
|
await permissionService.InsertRangeAsync(newPermissions, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Permission> GetNestedPermissions(UserRole role, int recursionLevel = 7)
|
||||||
{
|
{
|
||||||
var permissions = role.Permissions.ToList();
|
var permissions = role.Permissions.ToList();
|
||||||
if (role.IdParent is null)
|
if (role.IdParent is null)
|
||||||
return permissions;
|
return permissions;
|
||||||
if (counter == 0)
|
if (recursionLevel == 0)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"User role with id: {role.Id} has more than 10 nested childs");
|
Trace.WriteLine($"User role with id: {role.Id} has more than 10 nested childs");
|
||||||
return permissions;
|
return permissions;
|
||||||
@ -103,29 +161,9 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
if (parentRole is null)
|
if (parentRole is null)
|
||||||
return permissions;
|
return permissions;
|
||||||
|
|
||||||
var parentPermissions = GetNestedPermissions(parentRole, --counter);
|
var parentPermissions = GetNestedPermissions(parentRole, --recursionLevel);
|
||||||
Merge(ref permissions, parentPermissions);
|
|
||||||
return permissions;
|
return permissions.Union(parentPermissions);
|
||||||
}
|
|
||||||
|
|
||||||
private static void Merge(ref List<Permission> permissions, IEnumerable<Permission> newPermissions)
|
|
||||||
{
|
|
||||||
foreach (var newPermission in newPermissions)
|
|
||||||
{
|
|
||||||
var permissionIndex = permissions.FindIndex(p => p.IdPermission == newPermission.IdPermission);
|
|
||||||
if (permissionIndex == -1)
|
|
||||||
permissions.Add(newPermission);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var permission = permissions[permissionIndex];
|
|
||||||
permissions[permissionIndex] = new Permission
|
|
||||||
{
|
|
||||||
IdPermission = permission.IdPermission,
|
|
||||||
IdUserRole = permission.IdUserRole,
|
|
||||||
PermissionValue = permission.PermissionValue | newPermission.PermissionValue,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<int> DeleteAsync(int id, CancellationToken token = default)
|
public Task<int> DeleteAsync(int id, CancellationToken token = default)
|
||||||
@ -133,5 +171,35 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
|
|
||||||
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
|
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
|
||||||
=> cacheUserRoles.RemoveAsync(r => ids.Contains(r.Id), token);
|
=> cacheUserRoles.RemoveAsync(r => ids.Contains(r.Id), token);
|
||||||
|
|
||||||
|
public bool HasPermission(IEnumerable<int> rolesIds, string permissionName, int permissionMask = 0)
|
||||||
|
{
|
||||||
|
var permissionInfo = cachePermissionInfo.FirstOrDefault(p => p.Name.ToLower() == permissionName.ToLower());
|
||||||
|
|
||||||
|
if (permissionInfo is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (permissionMask == 0)
|
||||||
|
permissionMask = -1;
|
||||||
|
|
||||||
|
var idPermissionInfo = permissionInfo.Id;
|
||||||
|
var roles = cacheUserRoles.Where(r => rolesIds.Contains(r.Id));
|
||||||
|
foreach (var role in roles)
|
||||||
|
if (HasPermission(role, idPermissionInfo, permissionMask))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasPermission(UserRole userRole, int idPermissionInfo, int permissionMask, int recursionLevel = 7)
|
||||||
|
{
|
||||||
|
if (userRole.Permissions.Any(p => p.IdPermissionInfo == idPermissionInfo && (p.Value & permissionMask) > 0))
|
||||||
|
return true;
|
||||||
|
if (userRole.IdParent is not null && recursionLevel > 0)
|
||||||
|
{
|
||||||
|
var parentRole = cacheUserRoles.FirstOrDefault(p => p.Id == userRole.IdParent);
|
||||||
|
return HasPermission(parentRole, idPermissionInfo, permissionMask, --recursionLevel);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
166
AsbCloudInfrastructure/Services/UserService.cs
Normal file
166
AsbCloudInfrastructure/Services/UserService.cs
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
using AsbCloudApp.Data;
|
||||||
|
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 List<string> Includes { get; }
|
||||||
|
public IUserRoleService RoleService { get; }
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var entity = dto.Adapt<User>();
|
||||||
|
var updatedEntity = await cacheUsers.InsertAsync(entity, token).ConfigureAwait(false);
|
||||||
|
await UpdateRolesCacheForUserAsync((int)updatedEntity.Id, dto.RoleNames, token);
|
||||||
|
return updatedEntity?.Id ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.Adapt<UserExtendedDto>().ToList();
|
||||||
|
for (var i = 0; i < dtos.Count; i++)
|
||||||
|
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id);
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserExtendedDto> GetAsync(int id, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var entity = await cacheUsers.FirstOrDefaultAsync(u=>u.Id == id, token).ConfigureAwait(false);
|
||||||
|
var dto = entity.Adapt<UserExtendedDto>();
|
||||||
|
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateAsync(int id, UserExtendedDto dto, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var entity = dto.Adapt<User>();
|
||||||
|
await UpdateRolesCacheForUserAsync(id, dto.RoleNames, token);
|
||||||
|
|
||||||
|
var result = await cacheUsers.UpsertAsync(entity, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> DeleteAsync(int id, CancellationToken token = default)
|
||||||
|
=> cacheUsers.RemoveAsync(r => r.Id == id, token);
|
||||||
|
|
||||||
|
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
|
||||||
|
=> cacheUsers.RemoveAsync(r => ids.Contains(r.Id), token);
|
||||||
|
|
||||||
|
private IEnumerable<string> GetRolesNamesByIdUser(int idUser)
|
||||||
|
=> GetRolesByIdUser(idUser)
|
||||||
|
?.Select(r => r.Caption)
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
public IEnumerable<UserRoleDto> GetRolesByIdUser(int idUser)
|
||||||
|
{
|
||||||
|
var roles = cacheRelationUserToRoles.Where(r => r.IdUser == idUser);
|
||||||
|
if (roles?.Any() != true)
|
||||||
|
return null;
|
||||||
|
return roles.SelectMany(r => RoleService.GetNestedById(r.IdUserRole));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<PermissionBaseDto> GetNestedPermissions(int idUser)
|
||||||
|
{
|
||||||
|
var roles = GetRolesByIdUser(idUser);
|
||||||
|
return RoleService.GetNestedPermissions(roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<string> newRoleNames, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (newRoleNames?.Any() != true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var relatrions = new List<RelationUserUserRole>(newRoleNames.Count());
|
||||||
|
foreach (var roleName in newRoleNames)
|
||||||
|
{
|
||||||
|
var role = await RoleService.GetByNameAsync(roleName, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
if (role != null)
|
||||||
|
relatrions.Add(new()
|
||||||
|
{
|
||||||
|
IdUser = idUser,
|
||||||
|
IdUserRole = role.Id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await cacheRelationUserToRoles.RemoveAsync(r => r.IdUser == idUser, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
await cacheRelationUserToRoles.InsertAsync(relatrions, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasAnyRoleOf(int idUser, IEnumerable<string> roleNames)
|
||||||
|
{
|
||||||
|
if(!roleNames.Any())
|
||||||
|
return true;
|
||||||
|
var userRoleNames = GetRolesNamesByIdUser(idUser);
|
||||||
|
foreach (var roleName in userRoleNames)
|
||||||
|
if (roleNames.Contains(roleName))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasAnyRoleOf(int idUser, IEnumerable<int> roleIds)
|
||||||
|
{
|
||||||
|
if (!roleIds.Any())
|
||||||
|
return true;
|
||||||
|
var userRoles = GetRolesByIdUser(idUser);
|
||||||
|
foreach (var role in userRoles)
|
||||||
|
if (roleIds.Contains(role.Id))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasPermission(int idUser, string permissionName, int permissionMask = 0)
|
||||||
|
{
|
||||||
|
var relationsToRoles = cacheRelationUserToRoles.Where(r=>r.IdUser == idUser);
|
||||||
|
if (relationsToRoles is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return RoleService.HasPermission(relationsToRoles.Select(r => r.IdUserRole),
|
||||||
|
permissionName,
|
||||||
|
permissionMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,12 +8,12 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
[Route("api/admin/user")]
|
[Route("api/admin/user")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class AdminUserController : CrudController<UserDto, ICrudService<UserDto>>
|
public class AdminUserController : CrudController<UserExtendedDto, ICrudService<UserExtendedDto>>
|
||||||
{
|
{
|
||||||
public AdminUserController(ICrudService<UserDto> service)
|
public AdminUserController(IUserService service)
|
||||||
: base(service)
|
:base(service)
|
||||||
{
|
{}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
/// <param name="user">Информация о новом пользователе</param>
|
/// <param name="user">Информация о новом пользователе</param>
|
||||||
/// <returns code="200">Ок</returns>
|
/// <returns code="200">Ок</returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Register(UserDto user)
|
public IActionResult Register(UserRegistrationDto user)
|
||||||
{
|
{
|
||||||
var code = authService.Register(user);
|
var code = authService.Register(user);
|
||||||
return code switch
|
return code switch
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Middlewares
|
namespace AsbCloudWebApi.Middlewares
|
||||||
|
Loading…
Reference in New Issue
Block a user