diff --git a/DepartmentPortal/Common/CommonTools/Attributes/ViewModelPropertyAttribute.cs b/DepartmentPortal/Common/CommonTools/Attributes/ViewModelPropertyAttribute.cs
new file mode 100644
index 0000000..3e2ea0c
--- /dev/null
+++ b/DepartmentPortal/Common/CommonTools/Attributes/ViewModelPropertyAttribute.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace CommonTools.Attributes
+{
+ [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
+ public class ViewModelPropertyAttribute : Attribute
+ {
+ ///
+ /// Название на форме
+ ///
+ public string DisplayName { get; set; }
+
+ ///
+ /// Скрывать или нет
+ ///
+ public bool IsHide { get; set; }
+
+ ///
+ /// Ширина колонки
+ ///
+ public int ColumnWidth { get; set; }
+
+ ///
+ /// Конструктор
+ ///
+ /// Название на форме
+ /// Скрывать или нет
+ /// Ширина колонки
+ public ViewModelPropertyAttribute(string displayName, int columnWidth, bool isHide = false)
+ {
+ DisplayName = displayName;
+ ColumnWidth = columnWidth;
+ IsHide = isHide;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/CommonTools/OperationResultModels/OperationResultModel.cs b/DepartmentPortal/Common/CommonTools/OperationResultModels/OperationResultModel.cs
index 93d1616..ab9056b 100644
--- a/DepartmentPortal/Common/CommonTools/OperationResultModels/OperationResultModel.cs
+++ b/DepartmentPortal/Common/CommonTools/OperationResultModels/OperationResultModel.cs
@@ -25,7 +25,7 @@ namespace CommonTools.OperationResultModels
public List<(string Title, string Message)> Errors { get; private set; }
///
- /// Какой-то объект, получаемый по результатам операции (например, id)
+ /// Объект, получаемый по результатам операции
///
public object Result { get; private set; }
@@ -38,42 +38,4 @@ namespace CommonTools.OperationResultModels
StatusCode = ResultServiceStatusCode.Success;
}
}
-
- ///
- /// Результат любой операции
- ///
- ///
- public class OperationResultModel
- where T : ElementViewModel
- {
- ///
- /// Успешность операции
- ///
- public bool IsSucceeded { get; private set; }
-
- ///
- /// Статус операции
- ///
- public ResultServiceStatusCode StatusCode { get; private set; }
-
- ///
- /// Спсиок ошибок
- ///
- public List> Errors { get; private set; }
-
- ///
- /// Какой-то объект, получаемый по результатам операции (например, id)
- ///
- public T Result { get; private set; }
-
- ///
- /// Конструктор по умолчанию
- ///
- public OperationResultModel()
- {
- Errors = new List>();
- IsSucceeded = true;
- StatusCode = 0;
- }
- }
}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/CommonTools/ViewModels/ElementViewModel.cs b/DepartmentPortal/Common/CommonTools/ViewModels/ElementViewModel.cs
index 1106ed9..1479933 100644
--- a/DepartmentPortal/Common/CommonTools/ViewModels/ElementViewModel.cs
+++ b/DepartmentPortal/Common/CommonTools/ViewModels/ElementViewModel.cs
@@ -1,4 +1,5 @@
-using System;
+using CommonTools.Attributes;
+using System;
namespace CommonTools.ViewModels
{
@@ -7,6 +8,7 @@ namespace CommonTools.ViewModels
///
public class ElementViewModel
{
+ [ViewModelProperty("Идентификатор", 1, true)]
public Guid Id { get; set; }
}
}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/DatabaseContext.cs b/DepartmentPortal/Common/DatabaseCore/DatabaseContext.cs
new file mode 100644
index 0000000..7ef1c95
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/DatabaseContext.cs
@@ -0,0 +1,33 @@
+using DatabaseCore.Models.Security;
+using Microsoft.EntityFrameworkCore;
+
+namespace DatabaseCore
+{
+ public class DatabaseContext : DbContext
+ {
+ public DatabaseContext() : base() { }
+
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+ if (optionsBuilder.IsConfigured == false)
+ {
+#if RELEASE
+ var connectionString = ModelTools.ServiceProvider.ServiceProviderLoader.GetConfigData("connectionString");
+ optionsBuilder.UseSqlServer(connectionString);
+#endif
+
+#if DEBUG
+ optionsBuilder.UseSqlServer(@"Data Source=CHESHIR\SQLEXPRESS;Initial Catalog=DepartmentDatabasePortal;persist security info=True;user id=admin;password=cheshirSA123;MultipleActiveResultSets=True;");
+#endif
+ }
+ base.OnConfiguring(optionsBuilder);
+ }
+
+
+ public virtual DbSet Accesses { set; get; }
+ public virtual DbSet EnviromentSettings { set; get; }
+ public virtual DbSet Roles { set; get; }
+ public virtual DbSet Users { set; get; }
+ public virtual DbSet UserRoles { set; get; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/DatabaseCore.csproj b/DepartmentPortal/Common/DatabaseCore/DatabaseCore.csproj
new file mode 100644
index 0000000..b5aca4a
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/DatabaseCore.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net5.0
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
diff --git a/DepartmentPortal/Common/DatabaseCore/DatabaseManager.cs b/DepartmentPortal/Common/DatabaseCore/DatabaseManager.cs
new file mode 100644
index 0000000..6bdd322
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/DatabaseManager.cs
@@ -0,0 +1,13 @@
+namespace DatabaseCore
+{
+ ///
+ /// Работа с БД
+ ///
+ public static class DatabaseManager
+ {
+ ///
+ /// Получение объекта от класса DbContext
+ ///
+ public static DatabaseContext GetContext => new();
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Migrations/20210326072923_AddSecurityModels.Designer.cs b/DepartmentPortal/Common/DatabaseCore/Migrations/20210326072923_AddSecurityModels.Designer.cs
new file mode 100644
index 0000000..e9c7b52
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Migrations/20210326072923_AddSecurityModels.Designer.cs
@@ -0,0 +1,211 @@
+//
+using System;
+using DatabaseCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace DatabaseCore.Migrations
+{
+ [DbContext(typeof(DatabaseContext))]
+ [Migration("20210326072923_AddSecurityModels")]
+ partial class AddSecurityModels
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("ProductVersion", "5.0.4")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Access", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AccessType")
+ .HasColumnType("int");
+
+ b.Property("DateCreate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateDelete")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Operation")
+ .HasColumnType("int");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("Accesses");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.EnviromentSetting", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Key")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("EnviromentSettings");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Role", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DateCreate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateDelete")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("RoleName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RolePriority")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("Roles");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.User", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Avatar")
+ .HasColumnType("varbinary(max)");
+
+ b.Property("CountAttempt")
+ .HasColumnType("int");
+
+ b.Property("DateBanned")
+ .HasColumnType("datetime2");
+
+ b.Property("DateCreate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateDelete")
+ .HasColumnType("datetime2");
+
+ b.Property("DateLastVisit")
+ .HasColumnType("datetime2");
+
+ b.Property("DateLocked")
+ .HasColumnType("datetime2");
+
+ b.Property("EmployeeId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("IsBanned")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LecturerId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("StudentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserName")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.UserRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserRoles");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Access", b =>
+ {
+ b.HasOne("DatabaseCore.Models.Security.Role", "Role")
+ .WithMany("Access")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Role");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.UserRole", b =>
+ {
+ b.HasOne("DatabaseCore.Models.Security.Role", "Role")
+ .WithMany("UserRoles")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DatabaseCore.Models.Security.User", "User")
+ .WithMany("UserRoles")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Role");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Role", b =>
+ {
+ b.Navigation("Access");
+
+ b.Navigation("UserRoles");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.User", b =>
+ {
+ b.Navigation("UserRoles");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/DepartmentPortal/Common/DatabaseCore/Migrations/20210326072923_AddSecurityModels.cs b/DepartmentPortal/Common/DatabaseCore/Migrations/20210326072923_AddSecurityModels.cs
new file mode 100644
index 0000000..04aafc8
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Migrations/20210326072923_AddSecurityModels.cs
@@ -0,0 +1,146 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace DatabaseCore.Migrations
+{
+ public partial class AddSecurityModels : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "EnviromentSettings",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ Key = table.Column(type: "nvarchar(max)", nullable: true),
+ Value = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_EnviromentSettings", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Roles",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ RoleName = table.Column(type: "nvarchar(max)", nullable: true),
+ RolePriority = table.Column(type: "int", nullable: false),
+ DateCreate = table.Column(type: "datetime2", nullable: false),
+ DateDelete = table.Column(type: "datetime2", nullable: true),
+ IsDeleted = table.Column(type: "bit", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Roles", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Users",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ UserName = table.Column(type: "nvarchar(max)", nullable: true),
+ PasswordHash = table.Column(type: "nvarchar(max)", nullable: true),
+ StudentId = table.Column(type: "uniqueidentifier", nullable: true),
+ LecturerId = table.Column(type: "uniqueidentifier", nullable: true),
+ EmployeeId = table.Column(type: "uniqueidentifier", nullable: true),
+ Avatar = table.Column(type: "varbinary(max)", nullable: true),
+ DateLastVisit = table.Column(type: "datetime2", nullable: true),
+ IsBanned = table.Column(type: "bit", nullable: false),
+ DateBanned = table.Column(type: "datetime2", nullable: true),
+ CountAttempt = table.Column(type: "int", nullable: false),
+ DateLocked = table.Column(type: "datetime2", nullable: true),
+ DateCreate = table.Column(type: "datetime2", nullable: false),
+ DateDelete = table.Column(type: "datetime2", nullable: true),
+ IsDeleted = table.Column(type: "bit", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Users", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Accesses",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ RoleId = table.Column(type: "uniqueidentifier", nullable: false),
+ Operation = table.Column(type: "int", nullable: false),
+ AccessType = table.Column(type: "int", nullable: false),
+ DateCreate = table.Column(type: "datetime2", nullable: false),
+ DateDelete = table.Column(type: "datetime2", nullable: true),
+ IsDeleted = table.Column(type: "bit", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Accesses", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Accesses_Roles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "Roles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserRoles",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ RoleId = table.Column(type: "uniqueidentifier", nullable: false),
+ UserId = table.Column(type: "uniqueidentifier", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserRoles", x => x.Id);
+ table.ForeignKey(
+ name: "FK_UserRoles_Roles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "Roles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_UserRoles_Users_UserId",
+ column: x => x.UserId,
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Accesses_RoleId",
+ table: "Accesses",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserRoles_RoleId",
+ table: "UserRoles",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserRoles_UserId",
+ table: "UserRoles",
+ column: "UserId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "Accesses");
+
+ migrationBuilder.DropTable(
+ name: "EnviromentSettings");
+
+ migrationBuilder.DropTable(
+ name: "UserRoles");
+
+ migrationBuilder.DropTable(
+ name: "Roles");
+
+ migrationBuilder.DropTable(
+ name: "Users");
+ }
+ }
+}
diff --git a/DepartmentPortal/Common/DatabaseCore/Migrations/DatabaseContextModelSnapshot.cs b/DepartmentPortal/Common/DatabaseCore/Migrations/DatabaseContextModelSnapshot.cs
new file mode 100644
index 0000000..fe854ca
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Migrations/DatabaseContextModelSnapshot.cs
@@ -0,0 +1,209 @@
+//
+using System;
+using DatabaseCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace DatabaseCore.Migrations
+{
+ [DbContext(typeof(DatabaseContext))]
+ partial class DatabaseContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("ProductVersion", "5.0.4")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Access", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AccessType")
+ .HasColumnType("int");
+
+ b.Property("DateCreate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateDelete")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Operation")
+ .HasColumnType("int");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("Accesses");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.EnviromentSetting", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Key")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("EnviromentSettings");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Role", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DateCreate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateDelete")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("RoleName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RolePriority")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("Roles");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.User", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Avatar")
+ .HasColumnType("varbinary(max)");
+
+ b.Property("CountAttempt")
+ .HasColumnType("int");
+
+ b.Property("DateBanned")
+ .HasColumnType("datetime2");
+
+ b.Property("DateCreate")
+ .HasColumnType("datetime2");
+
+ b.Property("DateDelete")
+ .HasColumnType("datetime2");
+
+ b.Property("DateLastVisit")
+ .HasColumnType("datetime2");
+
+ b.Property("DateLocked")
+ .HasColumnType("datetime2");
+
+ b.Property("EmployeeId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("IsBanned")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LecturerId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("StudentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserName")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.UserRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserRoles");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Access", b =>
+ {
+ b.HasOne("DatabaseCore.Models.Security.Role", "Role")
+ .WithMany("Access")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Role");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.UserRole", b =>
+ {
+ b.HasOne("DatabaseCore.Models.Security.Role", "Role")
+ .WithMany("UserRoles")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DatabaseCore.Models.Security.User", "User")
+ .WithMany("UserRoles")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Role");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.Role", b =>
+ {
+ b.Navigation("Access");
+
+ b.Navigation("UserRoles");
+ });
+
+ modelBuilder.Entity("DatabaseCore.Models.Security.User", b =>
+ {
+ b.Navigation("UserRoles");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/DepartmentPortal/Common/DatabaseCore/Models/BaseEntity.cs b/DepartmentPortal/Common/DatabaseCore/Models/BaseEntity.cs
new file mode 100644
index 0000000..4819b48
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Models/BaseEntity.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace DatabaseCore.Models
+{
+ ///
+ /// Базовый набор для сущности
+ ///
+ [DataContract]
+ public class BaseEntity : IdEntity
+ {
+ [DataMember]
+ public DateTime DateCreate { get; set; }
+
+ [DataMember]
+ public DateTime? DateDelete { get; set; }
+
+ [DataMember]
+ public bool IsDeleted { get; set; }
+
+ public BaseEntity() : base()
+ {
+ DateCreate = DateTime.Now;
+ DateDelete = null;
+ IsDeleted = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Models/IdEntity.cs b/DepartmentPortal/Common/DatabaseCore/Models/IdEntity.cs
new file mode 100644
index 0000000..eb15cd0
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Models/IdEntity.cs
@@ -0,0 +1,24 @@
+using ModelTools.Attributes;
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Runtime.Serialization;
+
+namespace DatabaseCore.Models
+{
+ ///
+ /// Тип Id для всеъ сущностей
+ ///
+ [DataContract]
+ public class IdEntity
+ {
+ [DataMember]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ [MapConfiguration("Id")]
+ public Guid Id { get; set; }
+
+ public IdEntity() : base()
+ {
+ Id = Guid.NewGuid();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Models/Security/Access.cs b/DepartmentPortal/Common/DatabaseCore/Models/Security/Access.cs
new file mode 100644
index 0000000..c4a0b5c
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Models/Security/Access.cs
@@ -0,0 +1,38 @@
+using ModelTools.Attributes;
+using ModelTools.Enums;
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.Serialization;
+
+namespace DatabaseCore.Models.Security
+{
+ ///
+ /// Класс, описывающий возможные действия для роли
+ ///
+ [DataContract]
+ [EntityDescription("Access", "Доступные действия для ролей")]
+ [EntityDependency("Role", "RoleId", "Доступные дейсвтиия создаются под конкретную роль")]
+ public class Access : BaseEntity
+ {
+ [Required]
+ [DataMember]
+ [MapConfiguration("RoleId")]
+ public Guid RoleId { get; set; }
+
+ [Required]
+ [DataMember]
+ [MapConfiguration("Operation")]
+ public AccessOperation Operation { get; set; }
+
+ [Required]
+ [DataMember]
+ [MapConfiguration("AccessType")]
+ public AccessType AccessType { get; set; }
+
+ //-------------------------------------------------------------------------
+
+ public virtual Role Role { get; set; }
+
+ //-------------------------------------------------------------------------
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Models/Security/EnviromentSetting.cs b/DepartmentPortal/Common/DatabaseCore/Models/Security/EnviromentSetting.cs
new file mode 100644
index 0000000..dfd0fb6
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Models/Security/EnviromentSetting.cs
@@ -0,0 +1,21 @@
+using ModelTools.Attributes;
+using System.Runtime.Serialization;
+
+namespace DatabaseCore.Models.Security
+{
+ ///
+ /// Класс, описывающий общие настройки системы
+ ///
+ [DataContract]
+ [EntityDescription("EnviromentSetting", "Общие настройки системы")]
+ public class EnviromentSetting : IdEntity
+ {
+ [DataMember]
+ [MapConfiguration("Key")]
+ public string Key { get; set; }
+
+ [DataMember]
+ [MapConfiguration("Value")]
+ public string Value { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Models/Security/Role.cs b/DepartmentPortal/Common/DatabaseCore/Models/Security/Role.cs
new file mode 100644
index 0000000..40f4cf2
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Models/Security/Role.cs
@@ -0,0 +1,33 @@
+using ModelTools.Attributes;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Runtime.Serialization;
+
+namespace DatabaseCore.Models.Security
+{
+ ///
+ /// Класс, описывающий роль в системе
+ ///
+ [DataContract]
+ [EntityDescription("Role", "Роли в системе")]
+ public class Role : BaseEntity
+ {
+ [DataMember]
+ [MapConfiguration("RoleName")]
+ public string RoleName { get; set; }
+
+ [DataMember]
+ [MapConfiguration("RolePriority")]
+ public int RolePriority { get; set; }
+
+ //-------------------------------------------------------------------------
+
+ //-------------------------------------------------------------------------
+
+ [ForeignKey("RoleId")]
+ public virtual List Access { get; set; }
+
+ [ForeignKey("RoleId")]
+ public virtual List UserRoles { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Models/Security/User.cs b/DepartmentPortal/Common/DatabaseCore/Models/Security/User.cs
new file mode 100644
index 0000000..6e5aa34
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Models/Security/User.cs
@@ -0,0 +1,63 @@
+using ModelTools.Attributes;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Runtime.Serialization;
+
+namespace DatabaseCore.Models.Security
+{
+ ///
+ /// Класс, описывающий пользователя системы
+ ///
+ [DataContract]
+ [EntityDescription("User", "Пользователи системы")]
+ public class User : BaseEntity
+ {
+ [DataMember]
+ [MapConfiguration("Login")]
+ public string UserName { get; set; }
+
+ [DataMember]
+ [MapConfiguration("Password")]
+ public string PasswordHash { get; set; }
+
+ [DataMember]
+ [MapConfiguration("StudentId")]
+ public Guid? StudentId { get; set; }
+
+ [DataMember]
+ [MapConfiguration("LecturerId")]
+ public Guid? LecturerId { get; set; }
+
+ [DataMember]
+ [MapConfiguration("EmployeeId")]
+ public Guid? EmployeeId { get; set; }
+
+ [DataMember]
+ [MapConfiguration("Avatar")]
+ public byte[] Avatar { get; set; }
+
+ [DataMember]
+ [MapConfiguration("DateLastVisit")]
+ public DateTime? DateLastVisit { get; set; }
+
+ [DataMember]
+ [MapConfiguration("IsBanned")]
+ public bool IsBanned { get; set; }
+
+ [DataMember]
+ [MapConfiguration("DateBanned")]
+ public DateTime? DateBanned { get; set; }
+
+ [DataMember]
+ [MapConfiguration("CountAttempt")]
+ public int CountAttempt { get; set; }
+
+ //-------------------------------------------------------------------------
+
+ //-------------------------------------------------------------------------
+
+ [ForeignKey("UserId")]
+ public virtual List UserRoles { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Models/Security/UserRole.cs b/DepartmentPortal/Common/DatabaseCore/Models/Security/UserRole.cs
new file mode 100644
index 0000000..b2e3bfb
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Models/Security/UserRole.cs
@@ -0,0 +1,30 @@
+using ModelTools.Attributes;
+using System;
+using System.Runtime.Serialization;
+
+namespace DatabaseCore.Models.Security
+{
+ ///
+ /// Связка пользователь - роль
+ ///
+ [DataContract]
+ [EntityDescription("UserRole", "Связь пользователей системы с ролями, которые им назначены")]
+ [EntityDependency("Role", "RoleId", "К какой роли относится пользователь")]
+ [EntityDependency("User", "UserId", "К какой роли относится пользователь")]
+ public class UserRole : BaseEntity
+ {
+ [DataMember]
+ public Guid RoleId { get; set; }
+
+ [DataMember]
+ public Guid UserId { get; set; }
+
+ //-------------------------------------------------------------------------
+
+ public virtual Role Role { get; set; }
+
+ public virtual User User { get; set; }
+
+ //-------------------------------------------------------------------------
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/Scripts/SecureMigrationScript.cs b/DepartmentPortal/Common/DatabaseCore/Scripts/SecureMigrationScript.cs
new file mode 100644
index 0000000..be16bc8
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/Scripts/SecureMigrationScript.cs
@@ -0,0 +1,57 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace DatabaseCore.Scripts
+{
+ ///
+ /// Скрипты для миграции данных по безопасности
+ ///
+ public static class SecureMigrationScript
+ {
+ private static readonly string clearMigration =
+@"DELETE FROM DepartmentDatabasePortal.dbo.EnviromentSettings
+GO
+DELETE FROM DepartmentDatabasePortal.dbo.Accesses;
+GO
+DELETE FROM DepartmentDatabasePortal.dbo.UserRoles;
+GO
+DELETE FROM DepartmentDatabasePortal.dbo.Users;
+GO
+DELETE FROM DepartmentDatabasePortal.dbo.Roles;
+GO";
+
+ private static readonly string roleMigration =
+@"INSERT INTO DepartmentDatabasePortal.dbo.Roles(Id, RoleName, RolePriority, DateCreate, DateDelete, IsDeleted)
+SELECT Id, RoleName, RolePriority, DateCreate, DateDelete, IsDeleted FROM DepartmentDatabaseContext.dbo.DepartmentRoles";
+
+ private static readonly string userMigration =
+@"INSERT INTO DepartmentDatabasePortal.dbo.Users(Id, UserName, PasswordHash, StudentId, LecturerId, Avatar, DateLastVisit, IsBanned, DateBanned, CountAttempt, DateCreate, DateDelete, IsDeleted)
+SELECT Id, UserName, PasswordHash, StudentId, LecturerId, Avatar, DateLastVisit, IsLocked, DateBanned, CountAttempt, DateCreate, DateDelete, IsDeleted FROM DepartmentDatabaseContext.dbo.DepartmentUsers";
+
+ private static readonly string userroleMigration =
+@"INSERT INTO DepartmentDatabasePortal.dbo.UserRoles(Id, UserId, RoleId, DateCreate, DateDelete, IsDeleted)
+SELECT Id, UserId, RoleId, DateCreate, DateDelete, IsDeleted FROM DepartmentDatabaseContext.dbo.DepartmentUserRoles";
+
+ private static readonly string accessMigration =
+@"INSERT INTO DepartmentDatabasePortal.dbo.Accesses(Id, Operation, AccessType, RoleId, DateCreate, DateDelete, IsDeleted)
+SELECT Id, Operation, AccessType, RoleId, DateCreate, DateDelete, IsDeleted FROM DepartmentDatabaseContext.dbo.DepartmentAccesses";
+
+ private static readonly string enviromentsettingMigration =
+@"INSERT INTO DepartmentDatabasePortal.dbo.EnviromentSettings(Id, [Key], [Value])
+SELECT NEWID(), [Key], [Value] FROM DepartmentDatabaseContext.dbo.CurrentSettings";
+
+ ///
+ /// Перенос данных по безопасности
+ ///
+ ///
+ public static void RunScript(DbContext context)
+ {
+ context.Database.ExecuteSqlRaw(clearMigration, null);
+
+ context.Database.ExecuteSqlRaw(roleMigration, null);
+ context.Database.ExecuteSqlRaw(userMigration, null);
+ context.Database.ExecuteSqlRaw(userroleMigration, null);
+ context.Database.ExecuteSqlRaw(accessMigration, null);
+ context.Database.ExecuteSqlRaw(enviromentsettingMigration, null);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/DatabaseCore/SecurityManager.cs b/DepartmentPortal/Common/DatabaseCore/SecurityManager.cs
new file mode 100644
index 0000000..2ed76c5
--- /dev/null
+++ b/DepartmentPortal/Common/DatabaseCore/SecurityManager.cs
@@ -0,0 +1,64 @@
+using DatabaseCore.Models.Security;
+using ModelTools.BindingModels;
+using ModelTools.Enums;
+using ModelTools.Interfaces;
+using SecurityBusinessLogic.BusinessLogics;
+using System.Linq;
+
+namespace DatabaseCore
+{
+ public class SecurityManager : ISecurityManager
+ {
+ public string ErrorMessage { get; set; }
+
+ public bool CheckAccess(AccessBindingModel model, AccessOperation operation, AccessType type, string entity)
+ {
+ using var context = DatabaseManager.GetContext;
+ Access access;
+ if (model != null)
+ {
+ // простой просмотр возможен
+ if (model.SkipCheck && type == AccessType.SimpleView)
+ {
+ return true;
+ }
+ // если не указан идентификатор пользователя, то смотрим, может он авторизован
+ if (!model.UserId.HasValue && UserManager.GetInstance.User != null)
+ {
+ model.UserId = UserManager.GetInstance.UserId;
+ }
+
+ var roles = context.UserRoles.Where(x => x.UserId == model.UserId).Select(x => x.Role).OrderByDescending(x => x.RolePriority).ToList();
+ if (roles == null)
+ {
+ ErrorMessage = $"Не верный пользователь";
+ return false;
+ }
+ access = context.Accesses.FirstOrDefault(a => a.Operation == operation && roles.Contains(a.Role));
+ }
+ else
+ {
+ access = context.Accesses.FirstOrDefault(a => a.Operation == operation && UserManager.GetInstance.Roles.Contains(a.RoleId));
+ }
+ if (access != null)
+ {
+ if (access.AccessType >= type) return true;
+ }
+ switch (type)
+ {
+ case AccessType.FullView:
+ ErrorMessage = $"Нет доступа на чтение данных по сущности '{entity}'";
+ return false;
+ case AccessType.Change:
+ ErrorMessage = $"Нет доступа на изменение данных по сущности '{entity}'";
+ return false;
+ case AccessType.Delete:
+ ErrorMessage = $"Нет доступа на удаление данных по сущности '{entity}'";
+ return false;
+ default:
+ ErrorMessage = $"Нет доступа по сущности '{entity}'";
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Attributes/EntityDependencyAttribute.cs b/DepartmentPortal/Common/ModelTools/Attributes/EntityDependencyAttribute.cs
new file mode 100644
index 0000000..8640e72
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Attributes/EntityDependencyAttribute.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace ModelTools.Attributes
+{
+ ///
+ /// Описание зависимости сущности от другой сущности (требуется для сохранения и загрузки данных)
+ ///
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public class EntityDependencyAttribute : Attribute
+ {
+ ///
+ /// Название класса от котрого зависит этот класс
+ ///
+ public string ClassName { get; set; }
+
+ ///
+ /// Название поле в этом классе, которое ссылает на другой класс (идентификатор)
+ ///
+ public string ColumnName { get; set; }
+
+ ///
+ /// Описание зависимости
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// Описание зависимости сущности от другой сущности (требуется для сохранения и загрузки данных)
+ ///
+ /// Название класса от котрого зависит этот класс
+ /// Название поле в этом классе, которое ссылает на другой класс (идентификатор)
+ /// Описание зависимости
+ public EntityDependencyAttribute(string className, string columnName, string description)
+ {
+ ClassName = className;
+ ColumnName = columnName;
+ Description = description;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Attributes/EntityDescriptionAttribute.cs b/DepartmentPortal/Common/ModelTools/Attributes/EntityDescriptionAttribute.cs
new file mode 100644
index 0000000..22111b7
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Attributes/EntityDescriptionAttribute.cs
@@ -0,0 +1,32 @@
+using System;
+
+namespace ModelTools.Attributes
+{
+ ///
+ /// Описание класса из базы данных, его назначение
+ ///
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public class EntityDescriptionAttribute : Attribute
+ {
+ ///
+ /// Название сущности, которую описывает класс
+ ///
+ public string EntityName { get; set; }
+
+ ///
+ /// Описание назначения сущности
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// Описание класса из базы данных, его назначение
+ ///
+ /// Название сущности, которую описывает класс
+ /// Описание назначения сущности
+ public EntityDescriptionAttribute(string entityName, string description)
+ {
+ EntityName = entityName;
+ Description = description;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Attributes/MapConfigurationAttribute.cs b/DepartmentPortal/Common/ModelTools/Attributes/MapConfigurationAttribute.cs
new file mode 100644
index 0000000..850fcd3
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Attributes/MapConfigurationAttribute.cs
@@ -0,0 +1,32 @@
+using System;
+
+namespace ModelTools.Attributes
+{
+ ///
+ /// Настройка для полей сущности правил маппинга
+ ///
+ [AttributeUsage(AttributeTargets.Property)]
+ public class MapConfigurationAttribute : Attribute
+ {
+ ///
+ /// Название свойства с класса, из которого извлекаем данные
+ ///
+ public string PropertyNameFromModel { get; set; }
+
+ ///
+ /// Сложное свойство (свойствое в другом классе-свойстве)
+ ///
+ public bool IsDifficle { get; set; }
+
+ ///
+ /// Настройка для полей сущности правил маппинга
+ ///
+ /// Название свойства с класса, из которого извлекаем данные
+ /// Сложное свойство (свойствое в другом классе-свойстве)
+ public MapConfigurationAttribute(string propertyNameFromMModel, bool isDifficle = false)
+ {
+ PropertyNameFromModel = propertyNameFromMModel;
+ IsDifficle = isDifficle;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Attributes/ViewModelPropertyAttribute.cs b/DepartmentPortal/Common/ModelTools/Attributes/ViewModelPropertyAttribute.cs
new file mode 100644
index 0000000..a8358fb
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Attributes/ViewModelPropertyAttribute.cs
@@ -0,0 +1,68 @@
+using System;
+
+namespace ModelTools.Attributes
+{
+ ///
+ /// Настройка отображения элемента в контролах
+ ///
+ [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
+ public class ViewModelPropertyAttribute : Attribute
+ {
+ ///
+ /// Используется при выводе списка
+ ///
+ public bool UseOnList { get; set; }
+
+ ///
+ /// Используется при выводе элемента
+ ///
+ public bool UseOnElement { get; set; }
+
+ ///
+ /// Название на форме
+ ///
+ public string DisplayName { get; set; }
+
+ ///
+ /// Скрывать или нет при выводе списка
+ ///
+ public bool IsHide { get; set; }
+
+ ///
+ /// Ширина колонки
+ ///
+ public int? ColumnWidth { get; set; }
+
+ ///
+ /// Настройка отображения элемента в контролах
+ ///
+ /// Название на форме
+ /// Используется при выводе списка
+ /// Используется при выводе элемента
+ /// Скрывать или нет
+ public ViewModelPropertyAttribute(string displayName, bool useOnList, bool useOnElement, bool isHide = false)
+ {
+ DisplayName = displayName;
+ UseOnList = useOnList;
+ UseOnElement = useOnElement;
+ ColumnWidth = null;
+ IsHide = isHide;
+ }
+
+ ///
+ /// Конструктор
+ ///
+ /// Название на форме
+ /// Используется при выводе списка
+ /// Используется при выводе элемента
+ /// Ширина колонки
+ public ViewModelPropertyAttribute(string displayName, bool useOnList, bool useOnElement, int columnWidth)
+ {
+ DisplayName = displayName;
+ UseOnList = useOnList;
+ UseOnElement = useOnElement;
+ ColumnWidth = columnWidth;
+ IsHide = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/BindingModels/AccessBindingModel.cs b/DepartmentPortal/Common/ModelTools/BindingModels/AccessBindingModel.cs
new file mode 100644
index 0000000..cda456c
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/BindingModels/AccessBindingModel.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace ModelTools.BindingModels
+{
+ ///
+ /// Информация для доступа к выполнению операций
+ ///
+ public class AccessBindingModel
+ {
+ ///
+ /// Пропускать проверку (работает только для получения данных)
+ ///
+ public bool SkipCheck { get; set; }
+
+ ///
+ /// Идентификатор пользователя, который запрашивает выполнение операции
+ ///
+ public Guid? UserId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/BindingModels/GetBindingModel.cs b/DepartmentPortal/Common/ModelTools/BindingModels/GetBindingModel.cs
new file mode 100644
index 0000000..c13aa05
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/BindingModels/GetBindingModel.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace ModelTools.BindingModels
+{
+ ///
+ /// Получение записи
+ ///
+ public class GetBindingModel : AccessBindingModel
+ {
+ ///
+ /// Идентификатор получаемой записи (для одной записи)
+ ///
+ public Guid? Id { get; set; }
+
+ ///
+ /// Номер страницы, которую получаем (для списка)
+ ///
+ public int? PageNumber { get; set; }
+
+ ///
+ /// Количество записей возвращаемых (для списка)
+ ///
+ public int? PageSize { get; set; }
+
+ ///
+ /// Иной признак, по которму отбираем записи (для списка)
+ ///
+ public string PageName { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/BindingModels/SetBindingModel.cs b/DepartmentPortal/Common/ModelTools/BindingModels/SetBindingModel.cs
new file mode 100644
index 0000000..894357a
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/BindingModels/SetBindingModel.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace ModelTools.BindingModels
+{
+ ///
+ /// Сохранение записи по идентификатору
+ ///
+ public class SetBindingModel : AccessBindingModel
+ {
+ ///
+ /// Идентификатор записи
+ ///
+ public Guid Id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/BusinessLogics/BusinessLogicCore.cs b/DepartmentPortal/Common/ModelTools/BusinessLogics/BusinessLogicCore.cs
new file mode 100644
index 0000000..f6adbd0
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/BusinessLogics/BusinessLogicCore.cs
@@ -0,0 +1,226 @@
+using ModelTools.BindingModels;
+using ModelTools.Enums;
+using ModelTools.Interfaces;
+using ModelTools.OperationResultModels;
+using ModelTools.ViewModels;
+using System;
+using System.Collections.Generic;
+
+namespace ModelTools.BusinessLogics
+{
+ ///
+ /// Базовый класс для логики сущности
+ ///
+ ///
+ ///
+ ///
+ ///
+ public abstract class BusinessLogicCore
+ where G : GetBindingModel
+ where S : SetBindingModel
+ where L : ListViewModel
+ where E : ElementViewModel
+ {
+ ///
+ /// Перечень ошибок при выполнении операции
+ ///
+ public List<(string Title, string Message)> Errors { get; protected set; }
+
+ protected IEntityService Service { get; set; }
+
+ protected ISecurityManager Security { get; set; }
+
+ protected readonly AccessOperation _serviceOperation;
+
+ protected readonly string _entity;
+
+ public BusinessLogicCore(IEntityService service, string entity, AccessOperation serviceOperation)
+ {
+ Service = service;
+ Errors = new List<(string Title, string Message)>();
+ Security = UnityContainerConfigurator.Resolve();
+ _entity = entity;
+ _serviceOperation = serviceOperation;
+ }
+
+ ///
+ /// Проверка доступности операции для пользователя
+ ///
+ ///
+ ///
+ ///
+ protected bool NoAccess(AccessBindingModel model, AccessType type)
+ {
+ if (Security.CheckAccess(model, _serviceOperation, type, _entity))
+ {
+ return false;
+ }
+
+ Errors.Add(("Ошибка безопасности", Security.ErrorMessage));
+ return true;
+ }
+
+ ///
+ /// Получение списка записей
+ ///
+ ///
+ ///
+ public L GetList(G model)
+ {
+ Errors.Clear();
+ try
+ {
+ if (NoAccess(model, AccessType.SimpleView) && NoAccess(model, AccessType.FullView))
+ {
+ return null;
+ }
+ var result = Service.Read(model);
+ if (!result.IsSucceeded)
+ {
+ Errors.AddRange(Errors);
+ return null;
+ }
+
+ return ConvertToL(result);
+ }
+ catch (Exception ex)
+ {
+ Errors.Add(("Ошибка получения", ex.Message));
+ }
+ return null;
+ }
+
+ ///
+ /// Получение записи
+ ///
+ ///
+ ///
+ public E GetElement(G model)
+ {
+ Errors.Clear();
+ try
+ {
+ if (NoAccess(model, AccessType.SimpleView) && NoAccess(model, AccessType.FullView))
+ {
+ return null;
+ }
+ var result = Service.Read(model);
+ if (!result.IsSucceeded)
+ {
+ Errors.AddRange(Errors);
+ return null;
+ }
+ return ConvertToE(result);
+ }
+ catch (Exception ex)
+ {
+ Errors.Add(("Ошибка получения", ex.Message));
+ }
+ return null;
+ }
+
+ ///
+ /// Создание записи
+ ///
+ ///
+ ///
+ public E Create(S model)
+ {
+ Errors.Clear();
+ try
+ {
+ if (NoAccess(model, AccessType.Change))
+ {
+ return null;
+ }
+ var result = Service.Create(model);
+ if (!result.IsSucceeded)
+ {
+ Errors.AddRange(Errors);
+ return null;
+ }
+
+ return ConvertToE(result);
+ }
+ catch (Exception ex)
+ {
+ Errors.Add(("Ошибка создания", ex.Message));
+ }
+ return null;
+ }
+
+ ///
+ /// Изменение записи
+ ///
+ ///
+ ///
+ public E Update(S model)
+ {
+ Errors.Clear();
+ try
+ {
+ if (NoAccess(model, AccessType.Change))
+ {
+ return null;
+ }
+ var result = Service.Update(model);
+ if (!result.IsSucceeded)
+ {
+ Errors.AddRange(Errors);
+ return null;
+ }
+
+ return ConvertToE(result);
+ }
+ catch (Exception ex)
+ {
+ Errors.Add(("Ошибка изменения", ex.Message));
+ }
+ return null;
+ }
+
+ ///
+ /// Удаление записи
+ ///
+ ///
+ ///
+ public bool Delete(G model)
+ {
+ Errors.Clear();
+ try
+ {
+ if (NoAccess(model, AccessType.Delete))
+ {
+ return false;
+ }
+ var result = Service.Delete(model);
+ if (!result.IsSucceeded)
+ {
+ Errors.AddRange(Errors);
+ return false;
+ }
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Errors.Add(("Ошибка удаления", ex.Message));
+ }
+ return false;
+ }
+
+ ///
+ /// Получить список элементов
+ ///
+ ///
+ ///
+ protected abstract L ConvertToL(OperationResultModel model);
+
+ ///
+ /// Получить элемент
+ ///
+ ///
+ ///
+ protected abstract E ConvertToE(OperationResultModel model);
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/BusinessLogics/Mapper.cs b/DepartmentPortal/Common/ModelTools/BusinessLogics/Mapper.cs
new file mode 100644
index 0000000..b576561
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/BusinessLogics/Mapper.cs
@@ -0,0 +1,100 @@
+using ModelTools.Attributes;
+using System;
+using System.Reflection;
+
+namespace ModelTools.BusinessLogics
+{
+ ///
+ /// Маппер сущностей
+ ///
+ public class Mapper
+ {
+ ///
+ /// Преобразование из одного класса в другой
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static To MapToClass(From obj) where To : class => FillObject(obj, (To)Activator.CreateInstance(typeof(To)));
+
+ ///
+ /// Преобразование из одного класса в другой
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static To MapToClass(From obj, To newObject) where To : class => FillObject(obj, newObject);
+
+ ///
+ /// Заполнение объекта
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static To FillObject(From obj, To newObject)
+ where To : class
+ {
+ if (obj == null)
+ {
+ return null;
+ }
+
+ if (newObject == null)
+ {
+ return null;
+ }
+ var typeFrom = typeof(From);
+ var typeTo = typeof(To);
+ var properties = typeTo.GetProperties();
+ foreach (var property in properties)
+ {
+ var customAttribute = property.GetCustomAttribute();
+ if (customAttribute != null)
+ {
+ object value = obj;
+ if (customAttribute.IsDifficle)
+ {
+ var props = customAttribute.PropertyNameFromModel.Split('.');
+ foreach (var prop in props)
+ {
+ var bindingProperty = value.GetType().GetProperty(prop);
+ if (bindingProperty != null)
+ {
+ value = bindingProperty.GetValue(obj);
+ if (value is null)
+ {
+ break;
+ }
+ }
+ else
+ {
+ value = null;
+ break;
+ }
+ }
+ }
+ else
+ {
+ var bindingProperty = typeFrom.GetProperty(customAttribute.PropertyNameFromModel);
+ if (bindingProperty != null)
+ {
+ value = bindingProperty.GetValue(obj);
+ }
+ }
+ if (value is null)
+ {
+ continue;
+ }
+ property.SetValue(newObject, value);
+ }
+ }
+
+ return newObject;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/BusinessLogics/ServiceProviderLoader.cs b/DepartmentPortal/Common/ModelTools/BusinessLogics/ServiceProviderLoader.cs
new file mode 100644
index 0000000..9386353
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/BusinessLogics/ServiceProviderLoader.cs
@@ -0,0 +1,79 @@
+using ModelTools.Extensions;
+using ModelTools.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Xml.XPath;
+
+namespace ModelTools.BusinessLogics
+{
+ ///
+ /// Загрузчик данных
+ ///
+ public static class ServiceProviderLoader
+ {
+ private static readonly string _configFileName = "DepartmentPortal.config";
+
+ private static readonly string _pathToLoaderExt = "..\\..\\..\\..\\Extensions\\";
+
+ ///
+ /// Получение данных с файла настроек
+ ///
+ ///
+ ///
+ public static string GetConfigData(string key)
+ {
+ var fileName = GetFile(_configFileName);
+ if (!File.Exists(fileName))
+ {
+ return string.Empty;
+ }
+
+ var doc = new XPathDocument(fileName);
+ var nav = doc.CreateNavigator();
+ var data = nav.SelectDescendants(key, "", false);
+ data.MoveNext();
+ return data.Current.Value;
+ }
+
+ ///
+ /// Загрузка всех классов-реализаций ILoaderExtensions
+ ///
+ ///
+ public static List GetLoaderExtensions()
+ {
+ var list = new List();
+ if(Directory.Exists(_pathToLoaderExt))
+ {
+ var files = Directory.GetFiles(_pathToLoaderExt, "*.dll", SearchOption.AllDirectories);
+ var loadedFiles = new List();
+ foreach(var file in files.Distinct())
+ {
+ if(loadedFiles.Contains(file.GetFileName()))
+ {
+ continue;
+ }
+ Assembly asm = Assembly.LoadFrom(file);
+ foreach (var t in asm.GetExportedTypes())
+ {
+ if (t.IsClass && typeof(ILoaderExtensions).IsAssignableFrom(t))
+ {
+ list.Add((ILoaderExtensions)Activator.CreateInstance(t));
+ }
+ }
+ loadedFiles.Add(file.GetFileName());
+ }
+ }
+ return list;
+ }
+
+ ///
+ /// Получение имени файла
+ ///
+ ///
+ ///
+ private static string GetFile(string fileName) => Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), fileName);
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/BusinessLogics/UnityContainerConfigurator.cs b/DepartmentPortal/Common/ModelTools/BusinessLogics/UnityContainerConfigurator.cs
new file mode 100644
index 0000000..4c03192
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/BusinessLogics/UnityContainerConfigurator.cs
@@ -0,0 +1,43 @@
+using System;
+using Unity;
+using Unity.Lifetime;
+
+namespace ModelTools.BusinessLogics
+{
+ public class UnityContainerConfigurator
+ {
+ private static IUnityContainer _unityContainer;
+
+ public static IUnityContainer Container
+ {
+ get
+ {
+ if (_unityContainer == null) _unityContainer = new UnityContainer();
+ return _unityContainer;
+ }
+ }
+
+ ///
+ /// Инициализация сервисов
+ ///
+ public static void InitServices()
+ {
+ var ext = ServiceProviderLoader.GetLoaderExtensions();
+ if (ext.Count == 0)
+ {
+ throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям");
+ }
+ // регистрируем в UnityContainaer зависимости
+ foreach (var e in ext)
+ {
+ e.RegisterServices();
+ }
+ }
+
+ public static void PublishService() where U : T => Container.RegisterType(new HierarchicalLifetimeManager());
+
+ public static void PublishService() => Container.RegisterType(new HierarchicalLifetimeManager());
+
+ public static T Resolve() => Container.Resolve();
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Enums/AccessOperation.cs b/DepartmentPortal/Common/ModelTools/Enums/AccessOperation.cs
new file mode 100644
index 0000000..67a70f6
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Enums/AccessOperation.cs
@@ -0,0 +1,100 @@
+namespace ModelTools.Enums
+{
+ ///
+ /// Операции в системе
+ ///
+ public enum AccessOperation
+ {
+ #region Администрирование
+ Администрирование = 0,
+
+ Роли = 1,
+
+ Доступы = 2,
+
+ Пользователи = 3,
+
+ НастройкиСреды = 4,
+ #endregion
+
+ #region База
+ Кафедра = 100,
+
+ Аудитории = 101,
+
+ Направления = 102,
+
+ Преподаватели = 103, // + должности, звания
+
+ Дисциплины = 104, // + Блоки дисциплин
+
+ Группы = 105, //
+
+ Студенты = 106,
+
+ Приказы_студентов = 107,
+ #endregion
+
+ // Меню Учебный процесс
+ Учебный_процесс = 150,
+
+ Учебные_планы = 120,
+
+ Виды_нагрузок = 121,
+
+ Учебные_года = 122,
+
+ Даты_семестра = 126,
+
+ Контингент = 123,
+
+ Нормы_времени = 124,
+
+ Расчет_штатов = 125,
+
+ Расчасовки = 127,
+
+ Преподавательская_ставка = 128,
+
+ Индивидуальный_план = 130,
+
+ // Меню Расписание
+ Расписание = 200,
+
+ Расписание_аудитории = 201,
+
+ Расписание_группы = 202,
+
+ Расписание_преподаватели = 203,
+
+ Расписание_настройки = 204,
+
+ Расписание_интервалы_пар = 205,
+
+ Расписание_дисциплины = 206,
+
+ // Меню Сервис
+ Сервис = 300,
+
+ Генерация_билетов = 301,
+
+ // Меню зав лаб
+ ЗавЛабораторией = 400,
+
+ МатериальноТехническиеЦенности = 401,
+
+ УстановленоеПО = 402,
+
+ // Экзамены - составление билетов и проведение
+ СоставлениеЭкзаменов = 500,
+
+ Ведомости = 501,
+
+ ШаблоныБилетов = 502,
+
+ // Web-портал
+ Новости = 600,
+
+ Комментарии = 601
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Enums/AccessType.cs b/DepartmentPortal/Common/ModelTools/Enums/AccessType.cs
new file mode 100644
index 0000000..d6f0f00
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Enums/AccessType.cs
@@ -0,0 +1,34 @@
+namespace ModelTools.Enums
+{
+ ///
+ /// Тип операции
+ ///
+ public enum AccessType : int
+ {
+ ///
+ /// Простой просомтр
+ ///
+ SimpleView = 0,
+
+ ///
+ /// Полный просомтр
+ ///
+ FullView = 1,
+
+ ///
+ /// Добавление/Изменение
+ ///
+ Change = 2,
+
+ ///
+ /// Удаление
+ ///
+ Delete = 4,
+
+ // TODO убрать
+ ///
+ /// Доступ к админке
+ ///
+ Administrator = 8
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Enums/ResultServiceStatusCode.cs b/DepartmentPortal/Common/ModelTools/Enums/ResultServiceStatusCode.cs
new file mode 100644
index 0000000..d31bf2d
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Enums/ResultServiceStatusCode.cs
@@ -0,0 +1,38 @@
+namespace ModelTools.Enums
+{
+ ///
+ /// Статус результата операции
+ ///
+ public enum ResultServiceStatusCode
+ {
+ ///
+ /// Успешно
+ ///
+ Success = 200,
+
+ ///
+ /// Ошибка общая
+ ///
+ Error = 400,
+
+ ///
+ /// Элемент уже сущствует
+ ///
+ ExsistItem = 401,
+
+ ///
+ /// Запись удалена
+ ///
+ WasDelete = 402,
+
+ ///
+ /// Не найдено
+ ///
+ NotFound = 404,
+
+ ///
+ /// Не найден файл
+ ///
+ FileNotFound = 405
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Extensions/StringExtension.cs b/DepartmentPortal/Common/ModelTools/Extensions/StringExtension.cs
new file mode 100644
index 0000000..b656bfd
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Extensions/StringExtension.cs
@@ -0,0 +1,28 @@
+using System.IO;
+
+namespace ModelTools.Extensions
+{
+ public static class StringExtension
+ {
+ ///
+ /// Проверка, что строка пустая
+ ///
+ ///
+ ///
+ public static bool IsEmpty(this string str) => string.IsNullOrEmpty(str);
+
+ ///
+ /// Проверка, что строка не пустая
+ ///
+ ///
+ ///
+ public static bool IsNotEmpty(this string str) => !string.IsNullOrEmpty(str);
+
+ ///
+ /// Получение имени файла по полному пути
+ ///
+ ///
+ ///
+ public static string GetFileName(this string str) => (new FileInfo(str)).Name;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Interfaces/IEntityService.cs b/DepartmentPortal/Common/ModelTools/Interfaces/IEntityService.cs
new file mode 100644
index 0000000..2ab6242
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Interfaces/IEntityService.cs
@@ -0,0 +1,41 @@
+using ModelTools.BindingModels;
+using ModelTools.OperationResultModels;
+
+namespace ModelTools.Interfaces
+{
+ ///
+ /// Описание логики для хранилища сущности
+ ///
+ public interface IEntityService
+ where G : GetBindingModel
+ where S : SetBindingModel
+ {
+ ///
+ /// Получение списка сущностей
+ ///
+ ///
+ ///
+ OperationResultModel Read(G model);
+
+ ///
+ /// Создание новой сущности
+ ///
+ ///
+ ///
+ OperationResultModel Create(S model);
+
+ ///
+ /// Изменение сущности
+ ///
+ ///
+ ///
+ OperationResultModel Update(S model);
+
+ ///
+ /// Удаление сущности
+ ///
+ ///
+ ///
+ OperationResultModel Delete(G model);
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Interfaces/ILoaderExtensions.cs b/DepartmentPortal/Common/ModelTools/Interfaces/ILoaderExtensions.cs
new file mode 100644
index 0000000..1316e47
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Interfaces/ILoaderExtensions.cs
@@ -0,0 +1,13 @@
+namespace ModelTools.Interfaces
+{
+ ///
+ /// Интерфейс для регистрации зависомстей в модулях
+ ///
+ public interface ILoaderExtensions
+ {
+ ///
+ /// Регистрация сервисов
+ ///
+ public void RegisterServices();
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/Interfaces/ISecurityManager.cs b/DepartmentPortal/Common/ModelTools/Interfaces/ISecurityManager.cs
new file mode 100644
index 0000000..78156d4
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/Interfaces/ISecurityManager.cs
@@ -0,0 +1,23 @@
+using ModelTools.BindingModels;
+using ModelTools.Enums;
+
+namespace ModelTools.Interfaces
+{
+ public interface ISecurityManager
+ {
+ ///
+ /// Сообщение с причиной не получения доступа
+ ///
+ string ErrorMessage { get; set; }
+
+ ///
+ /// Авторизация пользователя к операции
+ ///
+ /// Данные по пользователю
+ /// Операция, которую хотят выполнить
+ /// Тип операции
+ /// Для какой сущности
+ ///
+ bool CheckAccess(AccessBindingModel model, AccessOperation operation, AccessType type, string entity);
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/ModelTools.csproj b/DepartmentPortal/Common/ModelTools/ModelTools.csproj
new file mode 100644
index 0000000..dfb11d9
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/ModelTools.csproj
@@ -0,0 +1,11 @@
+
+
+
+ net5.0
+
+
+
+
+
+
+
diff --git a/DepartmentPortal/Common/ModelTools/OperationResultModels/OperationResultModel.cs b/DepartmentPortal/Common/ModelTools/OperationResultModels/OperationResultModel.cs
new file mode 100644
index 0000000..9036f76
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/OperationResultModels/OperationResultModel.cs
@@ -0,0 +1,114 @@
+using ModelTools.Enums;
+using System;
+using System.Collections.Generic;
+
+namespace ModelTools.OperationResultModels
+{
+ ///
+ /// Результат любой операции
+ ///
+ public class OperationResultModel
+ {
+ ///
+ /// Успешность операции (количество ошибок = 0)
+ ///
+ public bool IsSucceeded => Errors.Count == 0;
+
+ ///
+ /// Статус операции
+ ///
+ public ResultServiceStatusCode StatusCode { get; set; }
+
+ ///
+ /// Спсиок ошибок
+ ///
+ public List<(string Title, string Message)> Errors { get; private set; }
+
+ ///
+ /// Объект, получаемый по результатам операции
+ ///
+ public object Result { get; private set; }
+
+ ///
+ /// Конструктор по умолчанию
+ ///
+ public OperationResultModel()
+ {
+ Errors = new List<(string Title, string Message)>();
+ StatusCode = ResultServiceStatusCode.Success;
+ }
+
+ ///
+ /// Успешно
+ ///
+ ///
+ ///
+ public static OperationResultModel Success(object obj)
+ {
+ return new OperationResultModel
+ {
+ Result = obj,
+ Errors = new List<(string Title, string Message)>(),
+ StatusCode = ResultServiceStatusCode.Success
+ };
+ }
+
+ ///
+ /// Добавление простой ошибки
+ ///
+ ///
+ ///
+ ///
+ public static OperationResultModel Error(string key, string value) => Error(key, value, ResultServiceStatusCode.Error);
+
+ ///
+ /// Добавление простой ошибки со сменой статуса
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static OperationResultModel Error(string key, string error, ResultServiceStatusCode statusCode)
+ {
+ var model = new OperationResultModel();
+ model.Errors.Add((key, error));
+ model.StatusCode = statusCode;
+ return model;
+ }
+
+ ///
+ /// Добавление ошибки
+ ///
+ ///
+ ///
+ public static OperationResultModel Error(Exception error) => Error(error, ResultServiceStatusCode.Error);
+
+ ///
+ /// Добавление ошибки
+ ///
+ ///
+ ///
+ ///
+ public static OperationResultModel Error(Exception error, ResultServiceStatusCode statusCode) => Error("Ошибка", error, statusCode);
+
+ ///
+ /// Добавление ошибки (включая вложеннные)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static OperationResultModel Error(string key, Exception error, ResultServiceStatusCode statusCode)
+ {
+ var model = new OperationResultModel();
+ model.Errors.Add((key, error.Message));
+ while (error.InnerException != null)
+ {
+ error = error.InnerException;
+ model.Errors.Add(("Inner error:", error.Message));
+ }
+ model.StatusCode = statusCode;
+ return model;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/ViewModels/ElementViewModel.cs b/DepartmentPortal/Common/ModelTools/ViewModels/ElementViewModel.cs
new file mode 100644
index 0000000..dfe800e
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/ViewModels/ElementViewModel.cs
@@ -0,0 +1,15 @@
+using ModelTools.Attributes;
+using System;
+
+namespace ModelTools.ViewModels
+{
+ ///
+ /// Возвращаемая запись
+ ///
+ public class ElementViewModel
+ {
+ [ViewModelProperty("Идентификатор", useOnList: true, useOnElement: false, isHide: true)]
+ [MapConfiguration("Id")]
+ public Guid Id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Common/ModelTools/ViewModels/ListViewModel.cs b/DepartmentPortal/Common/ModelTools/ViewModels/ListViewModel.cs
new file mode 100644
index 0000000..f98f307
--- /dev/null
+++ b/DepartmentPortal/Common/ModelTools/ViewModels/ListViewModel.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace ModelTools.ViewModels
+{
+ ///
+ /// Список возвращаемых значений
+ ///
+ ///
+ public class ListViewModel
+ where T : ElementViewModel
+ {
+ public int MaxCount { get; set; }
+
+ public List List { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/DepartmentPortal.sln b/DepartmentPortal/DepartmentPortal.sln
index 822b3d2..3c23c6f 100644
--- a/DepartmentPortal/DepartmentPortal.sln
+++ b/DepartmentPortal/DepartmentPortal.sln
@@ -5,7 +5,17 @@ VisualStudioVersion = 16.0.31112.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{6F154F8D-3437-45EE-9D89-02B96BDF3E8E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonTools", "Common\CommonTools\CommonTools.csproj", "{9E533D43-452A-40D6-852B-01E8391BBFF9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseCore", "Common\DatabaseCore\DatabaseCore.csproj", "{D4DAAEDE-A550-42BB-A50C-AD8FCB23D00A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModelTools", "Common\ModelTools\ModelTools.csproj", "{8BE3C29B-6E9F-4DFC-BAC3-14229D58616F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Security", "Security", "{7DA26C36-778E-4563-9AEC-966E26EA7B2A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecurityBusinessLogic", "Security\SecurityBusinessLogic\SecurityBusinessLogic.csproj", "{D424B54F-AF26-4A39-8D2B-CF874F31DE42}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DepartmentPortalDesctop", "DepartmentPortalDesctop\DepartmentPortalDesctop.csproj", "{B6CE93CB-998F-4F2D-BE9E-6FDF37FDFD0E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecurityImplementation", "Security\SecurityImplementation\SecurityImplementation.csproj", "{24D7BD00-EC45-4B98-92BB-C6FFB01F66ED}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,16 +23,35 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {9E533D43-452A-40D6-852B-01E8391BBFF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9E533D43-452A-40D6-852B-01E8391BBFF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9E533D43-452A-40D6-852B-01E8391BBFF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9E533D43-452A-40D6-852B-01E8391BBFF9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D4DAAEDE-A550-42BB-A50C-AD8FCB23D00A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D4DAAEDE-A550-42BB-A50C-AD8FCB23D00A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D4DAAEDE-A550-42BB-A50C-AD8FCB23D00A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D4DAAEDE-A550-42BB-A50C-AD8FCB23D00A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8BE3C29B-6E9F-4DFC-BAC3-14229D58616F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8BE3C29B-6E9F-4DFC-BAC3-14229D58616F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8BE3C29B-6E9F-4DFC-BAC3-14229D58616F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8BE3C29B-6E9F-4DFC-BAC3-14229D58616F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D424B54F-AF26-4A39-8D2B-CF874F31DE42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D424B54F-AF26-4A39-8D2B-CF874F31DE42}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D424B54F-AF26-4A39-8D2B-CF874F31DE42}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D424B54F-AF26-4A39-8D2B-CF874F31DE42}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6CE93CB-998F-4F2D-BE9E-6FDF37FDFD0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6CE93CB-998F-4F2D-BE9E-6FDF37FDFD0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6CE93CB-998F-4F2D-BE9E-6FDF37FDFD0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6CE93CB-998F-4F2D-BE9E-6FDF37FDFD0E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {24D7BD00-EC45-4B98-92BB-C6FFB01F66ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {24D7BD00-EC45-4B98-92BB-C6FFB01F66ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {24D7BD00-EC45-4B98-92BB-C6FFB01F66ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {24D7BD00-EC45-4B98-92BB-C6FFB01F66ED}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {9E533D43-452A-40D6-852B-01E8391BBFF9} = {6F154F8D-3437-45EE-9D89-02B96BDF3E8E}
+ {D4DAAEDE-A550-42BB-A50C-AD8FCB23D00A} = {6F154F8D-3437-45EE-9D89-02B96BDF3E8E}
+ {8BE3C29B-6E9F-4DFC-BAC3-14229D58616F} = {6F154F8D-3437-45EE-9D89-02B96BDF3E8E}
+ {D424B54F-AF26-4A39-8D2B-CF874F31DE42} = {7DA26C36-778E-4563-9AEC-966E26EA7B2A}
+ {24D7BD00-EC45-4B98-92BB-C6FFB01F66ED} = {7DA26C36-778E-4563-9AEC-966E26EA7B2A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FBA0CB49-EF2D-4538-9D00-FCEDA24879A9}
diff --git a/DepartmentPortal/DepartmentPortalDesctop/DepartmentPortal.config b/DepartmentPortal/DepartmentPortalDesctop/DepartmentPortal.config
new file mode 100644
index 0000000..0151204
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/DepartmentPortal.config
@@ -0,0 +1,4 @@
+
+
+ Data Source=10.3.1.13\SQLEXPRESS;Initial Catalog=DepartmentDatabasePortal;persist security info=True;user id=sa;password=isadmin;MultipleActiveResultSets=True;
+
\ No newline at end of file
diff --git a/DepartmentPortal/DepartmentPortalDesctop/DepartmentPortalDesctop.csproj b/DepartmentPortal/DepartmentPortalDesctop/DepartmentPortalDesctop.csproj
new file mode 100644
index 0000000..9b4d650
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/DepartmentPortalDesctop.csproj
@@ -0,0 +1,27 @@
+
+
+
+ WinExe
+ net5.0-windows
+ true
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
\ No newline at end of file
diff --git a/DepartmentPortal/DepartmentPortalDesctop/FormEnter.Designer.cs b/DepartmentPortal/DepartmentPortalDesctop/FormEnter.Designer.cs
new file mode 100644
index 0000000..3a59812
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/FormEnter.Designer.cs
@@ -0,0 +1,119 @@
+
+namespace DepartmentPortalDesctop
+{
+ partial class FormEnter
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.labelLogin = new System.Windows.Forms.Label();
+ this.textBoxLogin = new System.Windows.Forms.TextBox();
+ this.labelPassword = new System.Windows.Forms.Label();
+ this.textBoxPassword = new System.Windows.Forms.TextBox();
+ this.buttonEnter = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // labelLogin
+ //
+ this.labelLogin.AutoSize = true;
+ this.labelLogin.Location = new System.Drawing.Point(12, 9);
+ this.labelLogin.Name = "labelLogin";
+ this.labelLogin.Size = new System.Drawing.Size(44, 15);
+ this.labelLogin.TabIndex = 0;
+ this.labelLogin.Text = "Логин:";
+ //
+ // textBoxLogin
+ //
+ this.textBoxLogin.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxLogin.Location = new System.Drawing.Point(70, 6);
+ this.textBoxLogin.Name = "textBoxLogin";
+ this.textBoxLogin.Size = new System.Drawing.Size(242, 23);
+ this.textBoxLogin.TabIndex = 1;
+ //
+ // labelPassword
+ //
+ this.labelPassword.AutoSize = true;
+ this.labelPassword.Location = new System.Drawing.Point(12, 49);
+ this.labelPassword.Name = "labelPassword";
+ this.labelPassword.Size = new System.Drawing.Size(52, 15);
+ this.labelPassword.TabIndex = 2;
+ this.labelPassword.Text = "Пароль:";
+ //
+ // textBoxPassword
+ //
+ this.textBoxPassword.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxPassword.Location = new System.Drawing.Point(70, 46);
+ this.textBoxPassword.Name = "textBoxPassword";
+ this.textBoxPassword.Size = new System.Drawing.Size(242, 23);
+ this.textBoxPassword.TabIndex = 3;
+ this.textBoxPassword.UseSystemPasswordChar = true;
+ //
+ // buttonEnter
+ //
+ this.buttonEnter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonEnter.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.buttonEnter.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.buttonEnter.Location = new System.Drawing.Point(88, 88);
+ this.buttonEnter.MinimumSize = new System.Drawing.Size(100, 30);
+ this.buttonEnter.Name = "buttonEnter";
+ this.buttonEnter.Size = new System.Drawing.Size(167, 30);
+ this.buttonEnter.TabIndex = 4;
+ this.buttonEnter.Text = "Вход";
+ this.buttonEnter.UseVisualStyleBackColor = true;
+ this.buttonEnter.Click += new System.EventHandler(this.ButtonEnter_Click);
+ //
+ // FormEnter
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(324, 131);
+ this.Controls.Add(this.buttonEnter);
+ this.Controls.Add(this.textBoxPassword);
+ this.Controls.Add(this.labelPassword);
+ this.Controls.Add(this.textBoxLogin);
+ this.Controls.Add(this.labelLogin);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "FormEnter";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Вход в систему";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label labelLogin;
+ private System.Windows.Forms.TextBox textBoxLogin;
+ private System.Windows.Forms.Label labelPassword;
+ private System.Windows.Forms.TextBox textBoxPassword;
+ private System.Windows.Forms.Button buttonEnter;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/DepartmentPortalDesctop/FormEnter.cs b/DepartmentPortal/DepartmentPortalDesctop/FormEnter.cs
new file mode 100644
index 0000000..acfb1b8
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/FormEnter.cs
@@ -0,0 +1,32 @@
+using SecurityBusinessLogic.BusinessLogics;
+using System;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace DepartmentPortalDesctop
+{
+ ///
+ /// Форма входа в систему
+ ///
+ public partial class FormEnter : Form
+ {
+ public FormEnter()
+ {
+ InitializeComponent();
+ }
+
+ private void ButtonEnter_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ Task.WaitAll(Task.Run(async () => await UserManager.GetInstance.LoginAsync(textBoxLogin.Text, textBoxPassword.Text)));
+ DialogResult = DialogResult.OK;
+ Close();
+ }
+ catch (Exception ex)
+ {
+ //ErrorMessanger.PrintErrorMessage("При аутентфикации возникла ошибка: ", new List> { new KeyValuePair("Аутентфикация", ex.Message) });
+ }
+ }
+ }
+}
diff --git a/DepartmentPortal/DepartmentPortalDesctop/FormEnter.resx b/DepartmentPortal/DepartmentPortalDesctop/FormEnter.resx
new file mode 100644
index 0000000..f298a7b
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/FormEnter.resx
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/DepartmentPortal/DepartmentPortalDesctop/FormMain.Designer.cs b/DepartmentPortal/DepartmentPortalDesctop/FormMain.Designer.cs
new file mode 100644
index 0000000..39fe88e
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/FormMain.Designer.cs
@@ -0,0 +1,125 @@
+
+namespace DepartmentPortalDesctop
+{
+ partial class FormMain
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.menuMain = new System.Windows.Forms.MenuStrip();
+ this.panelControls = new System.Windows.Forms.Panel();
+ this.listBoxControls = new System.Windows.Forms.ListBox();
+ this.splitContainerMain = new System.Windows.Forms.SplitContainer();
+ this.ButtonShowHideControlList = new System.Windows.Forms.Button();
+ this.panelControls.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainerMain)).BeginInit();
+ this.splitContainerMain.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // menuMain
+ //
+ this.menuMain.Location = new System.Drawing.Point(0, 0);
+ this.menuMain.Name = "menuMain";
+ this.menuMain.Size = new System.Drawing.Size(800, 24);
+ this.menuMain.TabIndex = 0;
+ this.menuMain.Text = "Главное меню";
+ //
+ // panelControls
+ //
+ this.panelControls.Controls.Add(this.listBoxControls);
+ this.panelControls.Dock = System.Windows.Forms.DockStyle.Left;
+ this.panelControls.Location = new System.Drawing.Point(0, 24);
+ this.panelControls.Name = "panelControls";
+ this.panelControls.Size = new System.Drawing.Size(191, 426);
+ this.panelControls.TabIndex = 1;
+ //
+ // listBoxControls
+ //
+ this.listBoxControls.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.listBoxControls.FormattingEnabled = true;
+ this.listBoxControls.ItemHeight = 15;
+ this.listBoxControls.Location = new System.Drawing.Point(0, 0);
+ this.listBoxControls.Name = "listBoxControls";
+ this.listBoxControls.Size = new System.Drawing.Size(191, 426);
+ this.listBoxControls.TabIndex = 0;
+ //
+ // splitContainerMain
+ //
+ this.splitContainerMain.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainerMain.Location = new System.Drawing.Point(216, 24);
+ this.splitContainerMain.Name = "splitContainerMain";
+ this.splitContainerMain.Panel1MinSize = 100;
+ //
+ // splitContainerMain.Panel2
+ //
+ this.splitContainerMain.Panel2.AutoScroll = true;
+ this.splitContainerMain.Size = new System.Drawing.Size(584, 426);
+ this.splitContainerMain.SplitterDistance = 295;
+ this.splitContainerMain.TabIndex = 2;
+ //
+ // ButtonShowHideControlList
+ //
+ this.ButtonShowHideControlList.Dock = System.Windows.Forms.DockStyle.Left;
+ this.ButtonShowHideControlList.Location = new System.Drawing.Point(191, 24);
+ this.ButtonShowHideControlList.Name = "ButtonShowHideControlList";
+ this.ButtonShowHideControlList.Size = new System.Drawing.Size(25, 426);
+ this.ButtonShowHideControlList.TabIndex = 3;
+ this.ButtonShowHideControlList.Text = ">";
+ this.ButtonShowHideControlList.UseVisualStyleBackColor = true;
+ this.ButtonShowHideControlList.Click += new System.EventHandler(this.ButtonShowHideControlList_Click);
+ //
+ // FormMain
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(800, 450);
+ this.Controls.Add(this.splitContainerMain);
+ this.Controls.Add(this.ButtonShowHideControlList);
+ this.Controls.Add(this.panelControls);
+ this.Controls.Add(this.menuMain);
+ this.MainMenuStrip = this.menuMain;
+ this.Name = "FormMain";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Кафедральный портал";
+ this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
+ this.panelControls.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainerMain)).EndInit();
+ this.splitContainerMain.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.MenuStrip menuMain;
+ private System.Windows.Forms.Panel panelControls;
+ private System.Windows.Forms.ListBox listBoxControls;
+ private System.Windows.Forms.SplitContainer splitContainerMain;
+ private System.Windows.Forms.Button ButtonShowHideControlList;
+ }
+}
+
diff --git a/DepartmentPortal/DepartmentPortalDesctop/FormMain.cs b/DepartmentPortal/DepartmentPortalDesctop/FormMain.cs
new file mode 100644
index 0000000..86a3111
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/FormMain.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+
+namespace DepartmentPortalDesctop
+{
+ public partial class FormMain : Form
+ {
+ private Dictionary controls;
+ public FormMain()
+ {
+ InitializeComponent();
+ controls = new Dictionary();
+ }
+
+ private void ButtonShowHideControlList_Click(object sender, EventArgs e)
+ {
+ ButtonShowHideControlList.Text = panelControls.Visible ? ">" : "<";
+ panelControls.Visible = !panelControls.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/DepartmentPortalDesctop/FormMain.resx b/DepartmentPortal/DepartmentPortalDesctop/FormMain.resx
new file mode 100644
index 0000000..f298a7b
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/FormMain.resx
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/DepartmentPortal/DepartmentPortalDesctop/Program.cs b/DepartmentPortal/DepartmentPortalDesctop/Program.cs
new file mode 100644
index 0000000..2f29dcd
--- /dev/null
+++ b/DepartmentPortal/DepartmentPortalDesctop/Program.cs
@@ -0,0 +1,33 @@
+using DatabaseCore;
+using ModelTools.BusinessLogics;
+using ModelTools.Interfaces;
+using SecurityBusinessLogic.BusinessLogics;
+using System;
+using System.Windows.Forms;
+
+namespace DepartmentPortalDesctop
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ UnityContainerConfigurator.PublishService();
+ UnityContainerConfigurator.InitServices();
+
+ Application.SetHighDpiMode(HighDpiMode.SystemAware);
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+
+ var form = new FormEnter();
+
+ if (form.ShowDialog() == DialogResult.OK && UserManager.GetInstance.IsAuth)
+ {
+ Application.Run(UnityContainerConfigurator.Resolve());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Extensions/net5.0/DatabaseCore.dll b/DepartmentPortal/Extensions/net5.0/DatabaseCore.dll
new file mode 100644
index 0000000..c57f744
Binary files /dev/null and b/DepartmentPortal/Extensions/net5.0/DatabaseCore.dll differ
diff --git a/DepartmentPortal/Extensions/net5.0/ModelTools.dll b/DepartmentPortal/Extensions/net5.0/ModelTools.dll
new file mode 100644
index 0000000..f6de6c2
Binary files /dev/null and b/DepartmentPortal/Extensions/net5.0/ModelTools.dll differ
diff --git a/DepartmentPortal/Extensions/net5.0/SecurityBusinessLogic.dll b/DepartmentPortal/Extensions/net5.0/SecurityBusinessLogic.dll
new file mode 100644
index 0000000..522d2d8
Binary files /dev/null and b/DepartmentPortal/Extensions/net5.0/SecurityBusinessLogic.dll differ
diff --git a/DepartmentPortal/Extensions/net5.0/SecurityImplementation.deps.json b/DepartmentPortal/Extensions/net5.0/SecurityImplementation.deps.json
new file mode 100644
index 0000000..d56a467
--- /dev/null
+++ b/DepartmentPortal/Extensions/net5.0/SecurityImplementation.deps.json
@@ -0,0 +1,1782 @@
+{
+ "runtimeTarget": {
+ "name": ".NETCoreApp,Version=v5.0",
+ "signature": ""
+ },
+ "compilationOptions": {},
+ "targets": {
+ ".NETCoreApp,Version=v5.0": {
+ "SecurityImplementation/1.0.0": {
+ "dependencies": {
+ "DatabaseCore": "1.0.0",
+ "SecurityBusinessLogic": "1.0.0"
+ },
+ "runtime": {
+ "SecurityImplementation.dll": {}
+ }
+ },
+ "Microsoft.CSharp/4.5.0": {},
+ "Microsoft.Data.SqlClient/2.0.1": {
+ "dependencies": {
+ "Microsoft.Data.SqlClient.SNI.runtime": "2.0.1",
+ "Microsoft.Identity.Client": "4.14.0",
+ "Microsoft.IdentityModel.JsonWebTokens": "5.6.0",
+ "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0",
+ "Microsoft.Win32.Registry": "4.7.0",
+ "System.Configuration.ConfigurationManager": "4.7.0",
+ "System.Diagnostics.DiagnosticSource": "5.0.1",
+ "System.Runtime.Caching": "4.7.0",
+ "System.Security.Principal.Windows": "4.7.0",
+ "System.Text.Encoding.CodePages": "4.7.0"
+ },
+ "runtime": {
+ "lib/netcoreapp3.1/Microsoft.Data.SqlClient.dll": {
+ "assemblyVersion": "2.0.20168.4",
+ "fileVersion": "2.0.20168.4"
+ }
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netcoreapp3.1/Microsoft.Data.SqlClient.dll": {
+ "rid": "unix",
+ "assetType": "runtime",
+ "assemblyVersion": "2.0.20168.4",
+ "fileVersion": "2.0.20168.4"
+ },
+ "runtimes/win/lib/netcoreapp3.1/Microsoft.Data.SqlClient.dll": {
+ "rid": "win",
+ "assetType": "runtime",
+ "assemblyVersion": "2.0.20168.4",
+ "fileVersion": "2.0.20168.4"
+ }
+ }
+ },
+ "Microsoft.Data.SqlClient.SNI.runtime/2.0.1": {
+ "runtimeTargets": {
+ "runtimes/win-arm/native/Microsoft.Data.SqlClient.SNI.dll": {
+ "rid": "win-arm",
+ "assetType": "native",
+ "fileVersion": "2.0.1.0"
+ },
+ "runtimes/win-arm/native/Microsoft.Data.SqlClient.SNI.pdb": {
+ "rid": "win-arm",
+ "assetType": "native",
+ "fileVersion": "0.0.0.0"
+ },
+ "runtimes/win-arm64/native/Microsoft.Data.SqlClient.SNI.dll": {
+ "rid": "win-arm64",
+ "assetType": "native",
+ "fileVersion": "2.0.1.0"
+ },
+ "runtimes/win-arm64/native/Microsoft.Data.SqlClient.SNI.pdb": {
+ "rid": "win-arm64",
+ "assetType": "native",
+ "fileVersion": "0.0.0.0"
+ },
+ "runtimes/win-x64/native/Microsoft.Data.SqlClient.SNI.dll": {
+ "rid": "win-x64",
+ "assetType": "native",
+ "fileVersion": "2.0.1.0"
+ },
+ "runtimes/win-x64/native/Microsoft.Data.SqlClient.SNI.pdb": {
+ "rid": "win-x64",
+ "assetType": "native",
+ "fileVersion": "0.0.0.0"
+ },
+ "runtimes/win-x86/native/Microsoft.Data.SqlClient.SNI.dll": {
+ "rid": "win-x86",
+ "assetType": "native",
+ "fileVersion": "2.0.1.0"
+ },
+ "runtimes/win-x86/native/Microsoft.Data.SqlClient.SNI.pdb": {
+ "rid": "win-x86",
+ "assetType": "native",
+ "fileVersion": "0.0.0.0"
+ }
+ }
+ },
+ "Microsoft.EntityFrameworkCore/5.0.4": {
+ "dependencies": {
+ "Microsoft.EntityFrameworkCore.Abstractions": "5.0.4",
+ "Microsoft.EntityFrameworkCore.Analyzers": "5.0.4",
+ "Microsoft.Extensions.Caching.Memory": "5.0.0",
+ "Microsoft.Extensions.DependencyInjection": "5.0.1",
+ "Microsoft.Extensions.Logging": "5.0.0",
+ "System.Collections.Immutable": "5.0.0",
+ "System.ComponentModel.Annotations": "5.0.0",
+ "System.Diagnostics.DiagnosticSource": "5.0.1"
+ },
+ "runtime": {
+ "lib/netstandard2.1/Microsoft.EntityFrameworkCore.dll": {
+ "assemblyVersion": "5.0.4.0",
+ "fileVersion": "5.0.421.11803"
+ }
+ }
+ },
+ "Microsoft.EntityFrameworkCore.Abstractions/5.0.4": {
+ "runtime": {
+ "lib/netstandard2.1/Microsoft.EntityFrameworkCore.Abstractions.dll": {
+ "assemblyVersion": "5.0.4.0",
+ "fileVersion": "5.0.421.11803"
+ }
+ }
+ },
+ "Microsoft.EntityFrameworkCore.Analyzers/5.0.4": {},
+ "Microsoft.EntityFrameworkCore.Relational/5.0.4": {
+ "dependencies": {
+ "Microsoft.EntityFrameworkCore": "5.0.4",
+ "Microsoft.Extensions.Configuration.Abstractions": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.1/Microsoft.EntityFrameworkCore.Relational.dll": {
+ "assemblyVersion": "5.0.4.0",
+ "fileVersion": "5.0.421.11803"
+ }
+ }
+ },
+ "Microsoft.EntityFrameworkCore.SqlServer/5.0.4": {
+ "dependencies": {
+ "Microsoft.Data.SqlClient": "2.0.1",
+ "Microsoft.EntityFrameworkCore.Relational": "5.0.4"
+ },
+ "runtime": {
+ "lib/netstandard2.1/Microsoft.EntityFrameworkCore.SqlServer.dll": {
+ "assemblyVersion": "5.0.4.0",
+ "fileVersion": "5.0.421.11803"
+ }
+ }
+ },
+ "Microsoft.Extensions.Caching.Abstractions/5.0.0": {
+ "dependencies": {
+ "Microsoft.Extensions.Primitives": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Extensions.Caching.Abstractions.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Extensions.Caching.Memory/5.0.0": {
+ "dependencies": {
+ "Microsoft.Extensions.Caching.Abstractions": "5.0.0",
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "5.0.0",
+ "Microsoft.Extensions.Options": "5.0.0",
+ "Microsoft.Extensions.Primitives": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Extensions.Caching.Memory.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Extensions.Configuration.Abstractions/5.0.0": {
+ "dependencies": {
+ "Microsoft.Extensions.Primitives": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Extensions.DependencyInjection/5.0.1": {
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0"
+ },
+ "runtime": {
+ "lib/net5.0/Microsoft.Extensions.DependencyInjection.dll": {
+ "assemblyVersion": "5.0.0.1",
+ "fileVersion": "5.0.120.57516"
+ }
+ }
+ },
+ "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": {
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Extensions.Logging/5.0.0": {
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection": "5.0.1",
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "5.0.0",
+ "Microsoft.Extensions.Options": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.1/Microsoft.Extensions.Logging.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Extensions.Logging.Abstractions/5.0.0": {
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Extensions.Options/5.0.0": {
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
+ "Microsoft.Extensions.Primitives": "5.0.0"
+ },
+ "runtime": {
+ "lib/net5.0/Microsoft.Extensions.Options.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Extensions.Primitives/5.0.0": {
+ "runtime": {
+ "lib/netcoreapp3.0/Microsoft.Extensions.Primitives.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.Identity.Client/4.14.0": {
+ "dependencies": {
+ "Microsoft.CSharp": "4.5.0",
+ "System.ComponentModel.TypeConverter": "4.3.0",
+ "System.Net.NameResolution": "4.3.0",
+ "System.Private.Uri": "4.3.2",
+ "System.Runtime.Serialization.Formatters": "4.3.0",
+ "System.Runtime.Serialization.Json": "4.3.0",
+ "System.Runtime.Serialization.Primitives": "4.3.0",
+ "System.Security.SecureString": "4.3.0",
+ "System.Xml.XDocument": "4.3.0"
+ },
+ "runtime": {
+ "lib/netcoreapp2.1/Microsoft.Identity.Client.dll": {
+ "assemblyVersion": "4.14.0.0",
+ "fileVersion": "4.14.0.0"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.JsonWebTokens/5.6.0": {
+ "dependencies": {
+ "Microsoft.IdentityModel.Tokens": "5.6.0",
+ "Newtonsoft.Json": "10.0.1"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
+ "assemblyVersion": "5.6.0.0",
+ "fileVersion": "5.6.0.61018"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.Logging/5.6.0": {
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.IdentityModel.Logging.dll": {
+ "assemblyVersion": "5.6.0.0",
+ "fileVersion": "5.6.0.61018"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.Protocols/5.6.0": {
+ "dependencies": {
+ "Microsoft.IdentityModel.Logging": "5.6.0",
+ "Microsoft.IdentityModel.Tokens": "5.6.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.IdentityModel.Protocols.dll": {
+ "assemblyVersion": "5.6.0.0",
+ "fileVersion": "5.6.0.61018"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.Protocols.OpenIdConnect/5.6.0": {
+ "dependencies": {
+ "Microsoft.IdentityModel.Protocols": "5.6.0",
+ "Newtonsoft.Json": "10.0.1",
+ "System.IdentityModel.Tokens.Jwt": "5.6.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": {
+ "assemblyVersion": "5.6.0.0",
+ "fileVersion": "5.6.0.61018"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.Tokens/5.6.0": {
+ "dependencies": {
+ "Microsoft.IdentityModel.Logging": "5.6.0",
+ "Newtonsoft.Json": "10.0.1",
+ "System.Security.Cryptography.Cng": "4.5.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.dll": {
+ "assemblyVersion": "5.6.0.0",
+ "fileVersion": "5.6.0.61018"
+ }
+ }
+ },
+ "Microsoft.NETCore.Platforms/3.1.0": {},
+ "Microsoft.NETCore.Targets/1.1.3": {},
+ "Microsoft.Win32.Registry/4.7.0": {
+ "dependencies": {
+ "System.Security.AccessControl": "4.7.0",
+ "System.Security.Principal.Windows": "4.7.0"
+ }
+ },
+ "Microsoft.Win32.SystemEvents/4.7.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Win32.SystemEvents.dll": {
+ "assemblyVersion": "4.0.2.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ },
+ "runtimeTargets": {
+ "runtimes/win/lib/netcoreapp3.0/Microsoft.Win32.SystemEvents.dll": {
+ "rid": "win",
+ "assetType": "runtime",
+ "assemblyVersion": "4.0.2.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ }
+ },
+ "Newtonsoft.Json/10.0.1": {
+ "dependencies": {
+ "Microsoft.CSharp": "4.5.0",
+ "System.Collections": "4.3.0",
+ "System.ComponentModel.TypeConverter": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Dynamic.Runtime": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Linq": "4.3.0",
+ "System.Linq.Expressions": "4.3.0",
+ "System.ObjectModel": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Extensions": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Numerics": "4.3.0",
+ "System.Runtime.Serialization.Formatters": "4.3.0",
+ "System.Runtime.Serialization.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Text.Encoding.Extensions": "4.3.0",
+ "System.Text.RegularExpressions": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0",
+ "System.Xml.ReaderWriter": "4.3.0",
+ "System.Xml.XDocument": "4.3.0",
+ "System.Xml.XmlDocument": "4.3.0"
+ },
+ "runtime": {
+ "lib/netstandard1.3/Newtonsoft.Json.dll": {
+ "assemblyVersion": "10.0.0.0",
+ "fileVersion": "10.0.1.20720"
+ }
+ }
+ },
+ "runtime.native.System/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3"
+ }
+ },
+ "System.Collections/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Collections.Concurrent/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Diagnostics.Tracing": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Collections.Immutable/5.0.0": {},
+ "System.Collections.NonGeneric/4.3.0": {
+ "dependencies": {
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.Collections.Specialized/4.3.0": {
+ "dependencies": {
+ "System.Collections.NonGeneric": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Globalization.Extensions": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.ComponentModel/4.3.0": {
+ "dependencies": {
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.ComponentModel.Annotations/5.0.0": {},
+ "System.ComponentModel.Primitives/4.3.0": {
+ "dependencies": {
+ "System.ComponentModel": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.ComponentModel.TypeConverter/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Collections.NonGeneric": "4.3.0",
+ "System.Collections.Specialized": "4.3.0",
+ "System.ComponentModel": "4.3.0",
+ "System.ComponentModel.Primitives": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Linq": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Extensions": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Reflection.TypeExtensions": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.Configuration.ConfigurationManager/4.7.0": {
+ "dependencies": {
+ "System.Security.Cryptography.ProtectedData": "4.7.0",
+ "System.Security.Permissions": "4.7.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Configuration.ConfigurationManager.dll": {
+ "assemblyVersion": "4.0.3.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ }
+ },
+ "System.Diagnostics.Debug/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Diagnostics.DiagnosticSource/5.0.1": {
+ "runtime": {
+ "lib/net5.0/System.Diagnostics.DiagnosticSource.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.220.61120"
+ }
+ }
+ },
+ "System.Diagnostics.Tools/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Diagnostics.Tracing/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Drawing.Common/4.7.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.Win32.SystemEvents": "4.7.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Drawing.Common.dll": {
+ "assemblyVersion": "4.0.0.1",
+ "fileVersion": "4.6.26919.2"
+ }
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netcoreapp3.0/System.Drawing.Common.dll": {
+ "rid": "unix",
+ "assetType": "runtime",
+ "assemblyVersion": "4.0.2.0",
+ "fileVersion": "4.700.19.56404"
+ },
+ "runtimes/win/lib/netcoreapp3.0/System.Drawing.Common.dll": {
+ "rid": "win",
+ "assetType": "runtime",
+ "assemblyVersion": "4.0.2.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ }
+ },
+ "System.Dynamic.Runtime/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Linq": "4.3.0",
+ "System.Linq.Expressions": "4.3.0",
+ "System.ObjectModel": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Emit": "4.3.0",
+ "System.Reflection.Emit.ILGeneration": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Reflection.TypeExtensions": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.Globalization/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Globalization.Extensions/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "System.Globalization": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0"
+ }
+ },
+ "System.IdentityModel.Tokens.Jwt/5.6.0": {
+ "dependencies": {
+ "Microsoft.IdentityModel.JsonWebTokens": "5.6.0",
+ "Microsoft.IdentityModel.Tokens": "5.6.0",
+ "Newtonsoft.Json": "10.0.1"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.dll": {
+ "assemblyVersion": "5.6.0.0",
+ "fileVersion": "5.6.0.61018"
+ }
+ }
+ },
+ "System.IO/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.IO.FileSystem/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.IO": "4.3.0",
+ "System.IO.FileSystem.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.IO.FileSystem.Primitives/4.3.0": {
+ "dependencies": {
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Linq/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0"
+ }
+ },
+ "System.Linq.Expressions/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Linq": "4.3.0",
+ "System.ObjectModel": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Emit": "4.3.0",
+ "System.Reflection.Emit.ILGeneration": "4.3.0",
+ "System.Reflection.Emit.Lightweight": "4.3.0",
+ "System.Reflection.Extensions": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Reflection.TypeExtensions": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.Net.NameResolution/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Tracing": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Net.Primitives": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Security.Principal.Windows": "4.7.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0",
+ "runtime.native.System": "4.3.0"
+ }
+ },
+ "System.Net.Primitives/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Handles": "4.3.0"
+ }
+ },
+ "System.ObjectModel/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.Private.DataContractSerialization/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Collections.Concurrent": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Linq": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Emit.ILGeneration": "4.3.0",
+ "System.Reflection.Emit.Lightweight": "4.3.0",
+ "System.Reflection.Extensions": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Reflection.TypeExtensions": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Serialization.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Text.Encoding.Extensions": "4.3.0",
+ "System.Text.RegularExpressions": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0",
+ "System.Xml.ReaderWriter": "4.3.0",
+ "System.Xml.XDocument": "4.3.0",
+ "System.Xml.XmlDocument": "4.3.0",
+ "System.Xml.XmlSerializer": "4.3.0"
+ }
+ },
+ "System.Private.Uri/4.3.2": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3"
+ }
+ },
+ "System.Reflection/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.IO": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Reflection.Emit/4.3.0": {
+ "dependencies": {
+ "System.IO": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Emit.ILGeneration": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Reflection.Emit.ILGeneration/4.3.0": {
+ "dependencies": {
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Reflection.Emit.Lightweight/4.3.0": {
+ "dependencies": {
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Emit.ILGeneration": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Reflection.Extensions/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Reflection": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Reflection.Primitives/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Reflection.TypeExtensions/4.3.0": {
+ "dependencies": {
+ "System.Reflection": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Resources.ResourceManager/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Globalization": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Runtime/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3"
+ }
+ },
+ "System.Runtime.Caching/4.7.0": {
+ "dependencies": {
+ "System.Configuration.ConfigurationManager": "4.7.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Runtime.Caching.dll": {
+ "assemblyVersion": "4.0.1.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ },
+ "runtimeTargets": {
+ "runtimes/win/lib/netstandard2.0/System.Runtime.Caching.dll": {
+ "rid": "win",
+ "assetType": "runtime",
+ "assemblyVersion": "4.0.1.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ }
+ },
+ "System.Runtime.CompilerServices.Unsafe/4.5.2": {},
+ "System.Runtime.Extensions/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Runtime.Handles/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Runtime.InteropServices/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Handles": "4.3.0"
+ }
+ },
+ "System.Runtime.Numerics/4.3.0": {
+ "dependencies": {
+ "System.Globalization": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0"
+ }
+ },
+ "System.Runtime.Serialization.Formatters/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Serialization.Primitives": "4.3.0"
+ }
+ },
+ "System.Runtime.Serialization.Json/4.3.0": {
+ "dependencies": {
+ "System.IO": "4.3.0",
+ "System.Private.DataContractSerialization": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Runtime.Serialization.Primitives/4.3.0": {
+ "dependencies": {
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Security.AccessControl/4.7.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "System.Security.Principal.Windows": "4.7.0"
+ }
+ },
+ "System.Security.Cryptography.Cng/4.5.0": {},
+ "System.Security.Cryptography.Primitives/4.3.0": {
+ "dependencies": {
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Security.Cryptography.ProtectedData/4.7.0": {
+ "runtime": {
+ "lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll": {
+ "assemblyVersion": "4.0.5.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ },
+ "runtimeTargets": {
+ "runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll": {
+ "rid": "win",
+ "assetType": "runtime",
+ "assemblyVersion": "4.0.5.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ }
+ },
+ "System.Security.Permissions/4.7.0": {
+ "dependencies": {
+ "System.Security.AccessControl": "4.7.0",
+ "System.Windows.Extensions": "4.7.0"
+ },
+ "runtime": {
+ "lib/netcoreapp3.0/System.Security.Permissions.dll": {
+ "assemblyVersion": "4.0.3.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ }
+ },
+ "System.Security.Principal.Windows/4.7.0": {},
+ "System.Security.SecureString/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.Text.Encoding/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Text.Encoding.CodePages/4.7.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0"
+ }
+ },
+ "System.Text.Encoding.Extensions/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0",
+ "System.Text.Encoding": "4.3.0"
+ }
+ },
+ "System.Text.RegularExpressions/4.3.0": {
+ "dependencies": {
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Threading/4.3.0": {
+ "dependencies": {
+ "System.Runtime": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Threading.Tasks/4.3.0": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "3.1.0",
+ "Microsoft.NETCore.Targets": "1.1.3",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Threading.Tasks.Extensions/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Windows.Extensions/4.7.0": {
+ "dependencies": {
+ "System.Drawing.Common": "4.7.0"
+ },
+ "runtime": {
+ "lib/netcoreapp3.0/System.Windows.Extensions.dll": {
+ "assemblyVersion": "4.0.1.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ },
+ "runtimeTargets": {
+ "runtimes/win/lib/netcoreapp3.0/System.Windows.Extensions.dll": {
+ "rid": "win",
+ "assetType": "runtime",
+ "assemblyVersion": "4.0.1.0",
+ "fileVersion": "4.700.19.56404"
+ }
+ }
+ },
+ "System.Xml.ReaderWriter/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.IO.FileSystem": "4.3.0",
+ "System.IO.FileSystem.Primitives": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Text.Encoding.Extensions": "4.3.0",
+ "System.Text.RegularExpressions": "4.3.0",
+ "System.Threading.Tasks": "4.3.0",
+ "System.Threading.Tasks.Extensions": "4.3.0"
+ }
+ },
+ "System.Xml.XDocument/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Diagnostics.Tools": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Xml.ReaderWriter": "4.3.0"
+ }
+ },
+ "System.Xml.XmlDocument/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Xml.ReaderWriter": "4.3.0"
+ }
+ },
+ "System.Xml.XmlSerializer/4.3.0": {
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Linq": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Emit": "4.3.0",
+ "System.Reflection.Emit.ILGeneration": "4.3.0",
+ "System.Reflection.Extensions": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Reflection.TypeExtensions": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Text.RegularExpressions": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Xml.ReaderWriter": "4.3.0",
+ "System.Xml.XmlDocument": "4.3.0"
+ }
+ },
+ "Unity/5.11.10": {
+ "dependencies": {
+ "System.Runtime.CompilerServices.Unsafe": "4.5.2"
+ },
+ "runtime": {
+ "lib/netcoreapp3.0/Unity.Abstractions.dll": {
+ "assemblyVersion": "5.11.7.0",
+ "fileVersion": "5.11.7.0"
+ },
+ "lib/netcoreapp3.0/Unity.Container.dll": {
+ "assemblyVersion": "5.11.11.0",
+ "fileVersion": "5.11.11.0"
+ }
+ }
+ },
+ "DatabaseCore/1.0.0": {
+ "dependencies": {
+ "Microsoft.EntityFrameworkCore": "5.0.4",
+ "Microsoft.EntityFrameworkCore.SqlServer": "5.0.4",
+ "ModelTools": "1.0.0",
+ "SecurityBusinessLogic": "1.0.0"
+ },
+ "runtime": {
+ "DatabaseCore.dll": {}
+ }
+ },
+ "ModelTools/1.0.0": {
+ "dependencies": {
+ "Unity": "5.11.10"
+ },
+ "runtime": {
+ "ModelTools.dll": {}
+ }
+ },
+ "SecurityBusinessLogic/1.0.0": {
+ "dependencies": {
+ "ModelTools": "1.0.0"
+ },
+ "runtime": {
+ "SecurityBusinessLogic.dll": {}
+ }
+ }
+ }
+ },
+ "libraries": {
+ "SecurityImplementation/1.0.0": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ },
+ "Microsoft.CSharp/4.5.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-kaj6Wb4qoMuH3HySFJhxwQfe8R/sJsNJnANrvv8WdFPMoNbKY5htfNscv+LHCu5ipz+49m2e+WQXpLXr9XYemQ==",
+ "path": "microsoft.csharp/4.5.0",
+ "hashPath": "microsoft.csharp.4.5.0.nupkg.sha512"
+ },
+ "Microsoft.Data.SqlClient/2.0.1": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-cff+ug/XZnGmX6DFgLY92t7G9W3i8r23w5Qnuby41l9rS+X+f7Y51hV5glvIrmsu3tIcnxbR+Z4CQ2zGhksIJw==",
+ "path": "microsoft.data.sqlclient/2.0.1",
+ "hashPath": "microsoft.data.sqlclient.2.0.1.nupkg.sha512"
+ },
+ "Microsoft.Data.SqlClient.SNI.runtime/2.0.1": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-MalWSIMdwLZoNXxjmFmeRrFgaUXbEADkYNGm6HM33pculFv8gKt53s1Frs+kTfVPWMYjocd4gqwz92KrkcLfXA==",
+ "path": "microsoft.data.sqlclient.sni.runtime/2.0.1",
+ "hashPath": "microsoft.data.sqlclient.sni.runtime.2.0.1.nupkg.sha512"
+ },
+ "Microsoft.EntityFrameworkCore/5.0.4": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-upRpXluUeONMYO+O3RU8G+ZZcrnDrnNVWg4eJmSfertTdw7Hc5tgIeg/O8+oBKqf+OvBrQKW0U3PI9yoTsuPYg==",
+ "path": "microsoft.entityframeworkcore/5.0.4",
+ "hashPath": "microsoft.entityframeworkcore.5.0.4.nupkg.sha512"
+ },
+ "Microsoft.EntityFrameworkCore.Abstractions/5.0.4": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-4y+y28SHjniLIqj7M7YNRO8khBnCBtkM6TJG8oX0wyEZuLum+3e9vqqna1naaV6Hi4BhXBHcD/sjhIfW1u0ZfQ==",
+ "path": "microsoft.entityframeworkcore.abstractions/5.0.4",
+ "hashPath": "microsoft.entityframeworkcore.abstractions.5.0.4.nupkg.sha512"
+ },
+ "Microsoft.EntityFrameworkCore.Analyzers/5.0.4": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-z8OMwlXcUZJCArcDdhR0NRkmS0UyNg08l1LXPZCgYqjBeW8RvNXshH3H5ru/7IOVpyOfKrG5Q3nsgdD18OFG/g==",
+ "path": "microsoft.entityframeworkcore.analyzers/5.0.4",
+ "hashPath": "microsoft.entityframeworkcore.analyzers.5.0.4.nupkg.sha512"
+ },
+ "Microsoft.EntityFrameworkCore.Relational/5.0.4": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-9Qa6SqX+hJZogo99bICsS6kgQ1C5RtEjPrsvQxjInVdY9QSWsXWIYfem0rv3wi+htwkJuMHVHGSaqG1oeAwe+w==",
+ "path": "microsoft.entityframeworkcore.relational/5.0.4",
+ "hashPath": "microsoft.entityframeworkcore.relational.5.0.4.nupkg.sha512"
+ },
+ "Microsoft.EntityFrameworkCore.SqlServer/5.0.4": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-wFn6lYyezhTIWpEB85NYn0TmVs0GiTQBbgKxK4/BmeEXBoLdltOngosey1u9t1+c2xjxuis1V7fP3wcLVSf+jg==",
+ "path": "microsoft.entityframeworkcore.sqlserver/5.0.4",
+ "hashPath": "microsoft.entityframeworkcore.sqlserver.5.0.4.nupkg.sha512"
+ },
+ "Microsoft.Extensions.Caching.Abstractions/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-bu8As90/SBAouMZ6fJ+qRNo1X+KgHGrVueFhhYi+E5WqEhcnp2HoWRFnMzXQ6g4RdZbvPowFerSbKNH4Dtg5yg==",
+ "path": "microsoft.extensions.caching.abstractions/5.0.0",
+ "hashPath": "microsoft.extensions.caching.abstractions.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Extensions.Caching.Memory/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-/1qPCleFOkJe0O+xmFqCNLFYQZTJz965sVw8CUB/BQgsApBwzAUsL2BUkDvQW+geRUVTXUS9zLa0pBjC2VJ1gA==",
+ "path": "microsoft.extensions.caching.memory/5.0.0",
+ "hashPath": "microsoft.extensions.caching.memory.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Extensions.Configuration.Abstractions/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ETjSBHMp3OAZ4HxGQYpwyGsD8Sw5FegQXphi0rpoGMT74S4+I2mm7XJEswwn59XAaKOzC15oDSOWEE8SzDCd6Q==",
+ "path": "microsoft.extensions.configuration.abstractions/5.0.0",
+ "hashPath": "microsoft.extensions.configuration.abstractions.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Extensions.DependencyInjection/5.0.1": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-//mDNrYeiJ0eh/awFhDFJQzkRVra/njU5Y4fyK7X29g5HScrzbUkKOKlyTtygthcGFt4zNC8G5CFCjb/oizomA==",
+ "path": "microsoft.extensions.dependencyinjection/5.0.1",
+ "hashPath": "microsoft.extensions.dependencyinjection.5.0.1.nupkg.sha512"
+ },
+ "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==",
+ "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0",
+ "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Extensions.Logging/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-MgOwK6tPzB6YNH21wssJcw/2MKwee8b2gI7SllYfn6rvTpIrVvVS5HAjSU2vqSku1fwqRvWP0MdIi14qjd93Aw==",
+ "path": "microsoft.extensions.logging/5.0.0",
+ "hashPath": "microsoft.extensions.logging.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Extensions.Logging.Abstractions/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-NxP6ahFcBnnSfwNBi2KH2Oz8Xl5Sm2krjId/jRR3I7teFphwiUoUeZPwTNA21EX+5PtjqmyAvKaOeBXcJjcH/w==",
+ "path": "microsoft.extensions.logging.abstractions/5.0.0",
+ "hashPath": "microsoft.extensions.logging.abstractions.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Extensions.Options/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-CBvR92TCJ5uBIdd9/HzDSrxYak+0W/3+yxrNg8Qm6Bmrkh5L+nu6m3WeazQehcZ5q1/6dDA7J5YdQjim0165zg==",
+ "path": "microsoft.extensions.options/5.0.0",
+ "hashPath": "microsoft.extensions.options.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Extensions.Primitives/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-cI/VWn9G1fghXrNDagX9nYaaB/nokkZn0HYAawGaELQrl8InSezfe9OnfPZLcJq3esXxygh3hkq2c3qoV3SDyQ==",
+ "path": "microsoft.extensions.primitives/5.0.0",
+ "hashPath": "microsoft.extensions.primitives.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.Identity.Client/4.14.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-Etqux6Zuuv1yEN4UwKbAn6EZv0Rooc+vM4N9z7gxmeT7dyoKlXIRN44DQPzD9LV1CW0KsTVqH+2B42p1NKqPlQ==",
+ "path": "microsoft.identity.client/4.14.0",
+ "hashPath": "microsoft.identity.client.4.14.0.nupkg.sha512"
+ },
+ "Microsoft.IdentityModel.JsonWebTokens/5.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-0q0U1W+gX1jmfmv7uU7GXFGB518atmSwucxsVwPGpuaGS3jwd2tUi+Gau+ezxR6oAFEBFKG9lz/fxRZzGMeDXg==",
+ "path": "microsoft.identitymodel.jsonwebtokens/5.6.0",
+ "hashPath": "microsoft.identitymodel.jsonwebtokens.5.6.0.nupkg.sha512"
+ },
+ "Microsoft.IdentityModel.Logging/5.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-zEDrfEVW5x5w2hbTV94WwAcWvtue5hNTXYqoPh3ypF6U8csm09JazEYy+VPp2RtczkyMfcsvWY9Fea17e+isYQ==",
+ "path": "microsoft.identitymodel.logging/5.6.0",
+ "hashPath": "microsoft.identitymodel.logging.5.6.0.nupkg.sha512"
+ },
+ "Microsoft.IdentityModel.Protocols/5.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ei7YqYx0pIFL6JjK8ZnPK0MXZRWUNHtJPUl3KqSvj9+2f5CMa6GRSEC+BMDHr17tP6yujYUg0IQOcKzmC7qN5g==",
+ "path": "microsoft.identitymodel.protocols/5.6.0",
+ "hashPath": "microsoft.identitymodel.protocols.5.6.0.nupkg.sha512"
+ },
+ "Microsoft.IdentityModel.Protocols.OpenIdConnect/5.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-yh3n+uXiwpBy/5+t67tYcmRxb9kwQdaKRyG/DNipRMF37bg5Jr0vENOo1BQz6OySMl5WIK544SzPjtr7/KkucA==",
+ "path": "microsoft.identitymodel.protocols.openidconnect/5.6.0",
+ "hashPath": "microsoft.identitymodel.protocols.openidconnect.5.6.0.nupkg.sha512"
+ },
+ "Microsoft.IdentityModel.Tokens/5.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-C3OqR3QfBQ7wcC7yAsdMQqay87OsV6yWPYG/Ai3n7dvmWIGkouQhXoVxRP0xz3cAFL4hxZBXyw4aLTC421PaMg==",
+ "path": "microsoft.identitymodel.tokens/5.6.0",
+ "hashPath": "microsoft.identitymodel.tokens.5.6.0.nupkg.sha512"
+ },
+ "Microsoft.NETCore.Platforms/3.1.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-z7aeg8oHln2CuNulfhiLYxCVMPEwBl3rzicjvIX+4sUuCwvXw5oXQEtbiU2c0z4qYL5L3Kmx0mMA/+t/SbY67w==",
+ "path": "microsoft.netcore.platforms/3.1.0",
+ "hashPath": "microsoft.netcore.platforms.3.1.0.nupkg.sha512"
+ },
+ "Microsoft.NETCore.Targets/1.1.3": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==",
+ "path": "microsoft.netcore.targets/1.1.3",
+ "hashPath": "microsoft.netcore.targets.1.1.3.nupkg.sha512"
+ },
+ "Microsoft.Win32.Registry/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-KSrRMb5vNi0CWSGG1++id2ZOs/1QhRqROt+qgbEAdQuGjGrFcl4AOl4/exGPUYz2wUnU42nvJqon1T3U0kPXLA==",
+ "path": "microsoft.win32.registry/4.7.0",
+ "hashPath": "microsoft.win32.registry.4.7.0.nupkg.sha512"
+ },
+ "Microsoft.Win32.SystemEvents/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-mtVirZr++rq+XCDITMUdnETD59XoeMxSpLRIII7JRI6Yj0LEDiO1pPn0ktlnIj12Ix8bfvQqQDMMIF9wC98oCA==",
+ "path": "microsoft.win32.systemevents/4.7.0",
+ "hashPath": "microsoft.win32.systemevents.4.7.0.nupkg.sha512"
+ },
+ "Newtonsoft.Json/10.0.1": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ebWzW9j2nwxQeBo59As2TYn7nYr9BHicqqCwHOD1Vdo+50HBtLPuqdiCYJcLdTRknpYis/DSEOQz5KmZxwrIAg==",
+ "path": "newtonsoft.json/10.0.1",
+ "hashPath": "newtonsoft.json.10.0.1.nupkg.sha512"
+ },
+ "runtime.native.System/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
+ "path": "runtime.native.system/4.3.0",
+ "hashPath": "runtime.native.system.4.3.0.nupkg.sha512"
+ },
+ "System.Collections/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==",
+ "path": "system.collections/4.3.0",
+ "hashPath": "system.collections.4.3.0.nupkg.sha512"
+ },
+ "System.Collections.Concurrent/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
+ "path": "system.collections.concurrent/4.3.0",
+ "hashPath": "system.collections.concurrent.4.3.0.nupkg.sha512"
+ },
+ "System.Collections.Immutable/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==",
+ "path": "system.collections.immutable/5.0.0",
+ "hashPath": "system.collections.immutable.5.0.0.nupkg.sha512"
+ },
+ "System.Collections.NonGeneric/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==",
+ "path": "system.collections.nongeneric/4.3.0",
+ "hashPath": "system.collections.nongeneric.4.3.0.nupkg.sha512"
+ },
+ "System.Collections.Specialized/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-Epx8PoVZR0iuOnJJDzp7pWvdfMMOAvpUo95pC4ScH2mJuXkKA2Y4aR3cG9qt2klHgSons1WFh4kcGW7cSXvrxg==",
+ "path": "system.collections.specialized/4.3.0",
+ "hashPath": "system.collections.specialized.4.3.0.nupkg.sha512"
+ },
+ "System.ComponentModel/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-VyGn1jGRZVfxnh8EdvDCi71v3bMXrsu8aYJOwoV7SNDLVhiEqwP86pPMyRGsDsxhXAm2b3o9OIqeETfN5qfezw==",
+ "path": "system.componentmodel/4.3.0",
+ "hashPath": "system.componentmodel.4.3.0.nupkg.sha512"
+ },
+ "System.ComponentModel.Annotations/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==",
+ "path": "system.componentmodel.annotations/5.0.0",
+ "hashPath": "system.componentmodel.annotations.5.0.0.nupkg.sha512"
+ },
+ "System.ComponentModel.Primitives/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-j8GUkCpM8V4d4vhLIIoBLGey2Z5bCkMVNjEZseyAlm4n5arcsJOeI3zkUP+zvZgzsbLTYh4lYeP/ZD/gdIAPrw==",
+ "path": "system.componentmodel.primitives/4.3.0",
+ "hashPath": "system.componentmodel.primitives.4.3.0.nupkg.sha512"
+ },
+ "System.ComponentModel.TypeConverter/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-16pQ6P+EdhcXzPiEK4kbA953Fu0MNG2ovxTZU81/qsCd1zPRsKc3uif5NgvllCY598k6bI0KUyKW8fanlfaDQg==",
+ "path": "system.componentmodel.typeconverter/4.3.0",
+ "hashPath": "system.componentmodel.typeconverter.4.3.0.nupkg.sha512"
+ },
+ "System.Configuration.ConfigurationManager/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-/anOTeSZCNNI2zDilogWrZ8pNqCmYbzGNexUnNhjW8k0sHqEZ2nHJBp147jBV3hGYswu5lINpNg1vxR7bnqvVA==",
+ "path": "system.configuration.configurationmanager/4.7.0",
+ "hashPath": "system.configuration.configurationmanager.4.7.0.nupkg.sha512"
+ },
+ "System.Diagnostics.Debug/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==",
+ "path": "system.diagnostics.debug/4.3.0",
+ "hashPath": "system.diagnostics.debug.4.3.0.nupkg.sha512"
+ },
+ "System.Diagnostics.DiagnosticSource/5.0.1": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-uXQEYqav2V3zP6OwkOKtLv+qIi6z3m1hsGyKwXX7ZA7htT4shoVccGxnJ9kVRFPNAsi1ArZTq2oh7WOto6GbkQ==",
+ "path": "system.diagnostics.diagnosticsource/5.0.1",
+ "hashPath": "system.diagnostics.diagnosticsource.5.0.1.nupkg.sha512"
+ },
+ "System.Diagnostics.Tools/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==",
+ "path": "system.diagnostics.tools/4.3.0",
+ "hashPath": "system.diagnostics.tools.4.3.0.nupkg.sha512"
+ },
+ "System.Diagnostics.Tracing/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
+ "path": "system.diagnostics.tracing/4.3.0",
+ "hashPath": "system.diagnostics.tracing.4.3.0.nupkg.sha512"
+ },
+ "System.Drawing.Common/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-v+XbyYHaZjDfn0ENmJEV1VYLgGgCTx1gnfOBcppowbpOAriglYgGCvFCPr2EEZyBvXlpxbEsTwkOlInl107ahA==",
+ "path": "system.drawing.common/4.7.0",
+ "hashPath": "system.drawing.common.4.7.0.nupkg.sha512"
+ },
+ "System.Dynamic.Runtime/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-SNVi1E/vfWUAs/WYKhE9+qlS6KqK0YVhnlT0HQtr8pMIA8YX3lwy3uPMownDwdYISBdmAF/2holEIldVp85Wag==",
+ "path": "system.dynamic.runtime/4.3.0",
+ "hashPath": "system.dynamic.runtime.4.3.0.nupkg.sha512"
+ },
+ "System.Globalization/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
+ "path": "system.globalization/4.3.0",
+ "hashPath": "system.globalization.4.3.0.nupkg.sha512"
+ },
+ "System.Globalization.Extensions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==",
+ "path": "system.globalization.extensions/4.3.0",
+ "hashPath": "system.globalization.extensions.4.3.0.nupkg.sha512"
+ },
+ "System.IdentityModel.Tokens.Jwt/5.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-KMvPpX4exs2fe7Upq5zHMSR4yupc+jy8WG8yjucZL0XvT+r/T0hRvLIe9fP/SeN8/UVxFYBRAkRI5k1zbRGqmA==",
+ "path": "system.identitymodel.tokens.jwt/5.6.0",
+ "hashPath": "system.identitymodel.tokens.jwt.5.6.0.nupkg.sha512"
+ },
+ "System.IO/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
+ "path": "system.io/4.3.0",
+ "hashPath": "system.io.4.3.0.nupkg.sha512"
+ },
+ "System.IO.FileSystem/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
+ "path": "system.io.filesystem/4.3.0",
+ "hashPath": "system.io.filesystem.4.3.0.nupkg.sha512"
+ },
+ "System.IO.FileSystem.Primitives/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==",
+ "path": "system.io.filesystem.primitives/4.3.0",
+ "hashPath": "system.io.filesystem.primitives.4.3.0.nupkg.sha512"
+ },
+ "System.Linq/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==",
+ "path": "system.linq/4.3.0",
+ "hashPath": "system.linq.4.3.0.nupkg.sha512"
+ },
+ "System.Linq.Expressions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==",
+ "path": "system.linq.expressions/4.3.0",
+ "hashPath": "system.linq.expressions.4.3.0.nupkg.sha512"
+ },
+ "System.Net.NameResolution/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-AFYl08R7MrsrEjqpQWTZWBadqXyTzNDaWpMqyxhb0d6sGhV6xMDKueuBXlLL30gz+DIRY6MpdgnHWlCh5wmq9w==",
+ "path": "system.net.nameresolution/4.3.0",
+ "hashPath": "system.net.nameresolution.4.3.0.nupkg.sha512"
+ },
+ "System.Net.Primitives/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
+ "path": "system.net.primitives/4.3.0",
+ "hashPath": "system.net.primitives.4.3.0.nupkg.sha512"
+ },
+ "System.ObjectModel/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==",
+ "path": "system.objectmodel/4.3.0",
+ "hashPath": "system.objectmodel.4.3.0.nupkg.sha512"
+ },
+ "System.Private.DataContractSerialization/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-yDaJ2x3mMmjdZEDB4IbezSnCsnjQ4BxinKhRAaP6kEgL6Bb6jANWphs5SzyD8imqeC/3FxgsuXT6ykkiH1uUmA==",
+ "path": "system.private.datacontractserialization/4.3.0",
+ "hashPath": "system.private.datacontractserialization.4.3.0.nupkg.sha512"
+ },
+ "System.Private.Uri/4.3.2": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-o1+7RJnu3Ik3PazR7Z7tJhjPdE000Eq2KGLLWhqJJKXj04wrS8lwb1OFtDF9jzXXADhUuZNJZlPc98uwwqmpFA==",
+ "path": "system.private.uri/4.3.2",
+ "hashPath": "system.private.uri.4.3.2.nupkg.sha512"
+ },
+ "System.Reflection/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
+ "path": "system.reflection/4.3.0",
+ "hashPath": "system.reflection.4.3.0.nupkg.sha512"
+ },
+ "System.Reflection.Emit/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==",
+ "path": "system.reflection.emit/4.3.0",
+ "hashPath": "system.reflection.emit.4.3.0.nupkg.sha512"
+ },
+ "System.Reflection.Emit.ILGeneration/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==",
+ "path": "system.reflection.emit.ilgeneration/4.3.0",
+ "hashPath": "system.reflection.emit.ilgeneration.4.3.0.nupkg.sha512"
+ },
+ "System.Reflection.Emit.Lightweight/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==",
+ "path": "system.reflection.emit.lightweight/4.3.0",
+ "hashPath": "system.reflection.emit.lightweight.4.3.0.nupkg.sha512"
+ },
+ "System.Reflection.Extensions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==",
+ "path": "system.reflection.extensions/4.3.0",
+ "hashPath": "system.reflection.extensions.4.3.0.nupkg.sha512"
+ },
+ "System.Reflection.Primitives/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
+ "path": "system.reflection.primitives/4.3.0",
+ "hashPath": "system.reflection.primitives.4.3.0.nupkg.sha512"
+ },
+ "System.Reflection.TypeExtensions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==",
+ "path": "system.reflection.typeextensions/4.3.0",
+ "hashPath": "system.reflection.typeextensions.4.3.0.nupkg.sha512"
+ },
+ "System.Resources.ResourceManager/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
+ "path": "system.resources.resourcemanager/4.3.0",
+ "hashPath": "system.resources.resourcemanager.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
+ "path": "system.runtime/4.3.0",
+ "hashPath": "system.runtime.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime.Caching/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-NdvNRjTPxYvIEhXQszT9L9vJhdQoX6AQ0AlhjTU+5NqFQVuacJTfhPVAvtGWNA2OJCqRiR/okBcZgMwI6MqcZg==",
+ "path": "system.runtime.caching/4.7.0",
+ "hashPath": "system.runtime.caching.4.7.0.nupkg.sha512"
+ },
+ "System.Runtime.CompilerServices.Unsafe/4.5.2": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-wprSFgext8cwqymChhrBLu62LMg/1u92bU+VOwyfBimSPVFXtsNqEWC92Pf9ofzJFlk4IHmJA75EDJn1b2goAQ==",
+ "path": "system.runtime.compilerservices.unsafe/4.5.2",
+ "hashPath": "system.runtime.compilerservices.unsafe.4.5.2.nupkg.sha512"
+ },
+ "System.Runtime.Extensions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
+ "path": "system.runtime.extensions/4.3.0",
+ "hashPath": "system.runtime.extensions.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime.Handles/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==",
+ "path": "system.runtime.handles/4.3.0",
+ "hashPath": "system.runtime.handles.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime.InteropServices/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==",
+ "path": "system.runtime.interopservices/4.3.0",
+ "hashPath": "system.runtime.interopservices.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime.Numerics/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
+ "path": "system.runtime.numerics/4.3.0",
+ "hashPath": "system.runtime.numerics.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime.Serialization.Formatters/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-KT591AkTNFOTbhZlaeMVvfax3RqhH1EJlcwF50Wm7sfnBLuHiOeZRRKrr1ns3NESkM20KPZ5Ol/ueMq5vg4QoQ==",
+ "path": "system.runtime.serialization.formatters/4.3.0",
+ "hashPath": "system.runtime.serialization.formatters.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime.Serialization.Json/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-CpVfOH0M/uZ5PH+M9+Gu56K0j9lJw3M+PKRegTkcrY/stOIvRUeonggxNrfBYLA5WOHL2j15KNJuTuld3x4o9w==",
+ "path": "system.runtime.serialization.json/4.3.0",
+ "hashPath": "system.runtime.serialization.json.4.3.0.nupkg.sha512"
+ },
+ "System.Runtime.Serialization.Primitives/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
+ "path": "system.runtime.serialization.primitives/4.3.0",
+ "hashPath": "system.runtime.serialization.primitives.4.3.0.nupkg.sha512"
+ },
+ "System.Security.AccessControl/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-JECvTt5aFF3WT3gHpfofL2MNNP6v84sxtXxpqhLBCcDRzqsPBmHhQ6shv4DwwN2tRlzsUxtb3G9M3763rbXKDg==",
+ "path": "system.security.accesscontrol/4.7.0",
+ "hashPath": "system.security.accesscontrol.4.7.0.nupkg.sha512"
+ },
+ "System.Security.Cryptography.Cng/4.5.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-WG3r7EyjUe9CMPFSs6bty5doUqT+q9pbI80hlNzo2SkPkZ4VTuZkGWjpp77JB8+uaL4DFPRdBsAY+DX3dBK92A==",
+ "path": "system.security.cryptography.cng/4.5.0",
+ "hashPath": "system.security.cryptography.cng.4.5.0.nupkg.sha512"
+ },
+ "System.Security.Cryptography.Primitives/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
+ "path": "system.security.cryptography.primitives/4.3.0",
+ "hashPath": "system.security.cryptography.primitives.4.3.0.nupkg.sha512"
+ },
+ "System.Security.Cryptography.ProtectedData/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ehYW0m9ptxpGWvE4zgqongBVWpSDU/JCFD4K7krxkQwSz/sFQjEXCUqpvencjy6DYDbn7Ig09R8GFffu8TtneQ==",
+ "path": "system.security.cryptography.protecteddata/4.7.0",
+ "hashPath": "system.security.cryptography.protecteddata.4.7.0.nupkg.sha512"
+ },
+ "System.Security.Permissions/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-dkOV6YYVBnYRa15/yv004eCGRBVADXw8qRbbNiCn/XpdJSUXkkUeIvdvFHkvnko4CdKMqG8yRHC4ox83LSlMsQ==",
+ "path": "system.security.permissions/4.7.0",
+ "hashPath": "system.security.permissions.4.7.0.nupkg.sha512"
+ },
+ "System.Security.Principal.Windows/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ojD0PX0XhneCsUbAZVKdb7h/70vyYMDYs85lwEI+LngEONe/17A0cFaRFqZU+sOEidcVswYWikYOQ9PPfjlbtQ==",
+ "path": "system.security.principal.windows/4.7.0",
+ "hashPath": "system.security.principal.windows.4.7.0.nupkg.sha512"
+ },
+ "System.Security.SecureString/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-PnXp38O9q/2Oe4iZHMH60kinScv6QiiL2XH54Pj2t0Y6c2zKPEiAZsM/M3wBOHLNTBDFP0zfy13WN2M0qFz5jg==",
+ "path": "system.security.securestring/4.3.0",
+ "hashPath": "system.security.securestring.4.3.0.nupkg.sha512"
+ },
+ "System.Text.Encoding/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
+ "path": "system.text.encoding/4.3.0",
+ "hashPath": "system.text.encoding.4.3.0.nupkg.sha512"
+ },
+ "System.Text.Encoding.CodePages/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-aeu4FlaUTemuT1qOd1MyU4T516QR4Fy+9yDbwWMPHOHy7U8FD6SgTzdZFO7gHcfAPHtECqInbwklVvUK4RHcNg==",
+ "path": "system.text.encoding.codepages/4.7.0",
+ "hashPath": "system.text.encoding.codepages.4.7.0.nupkg.sha512"
+ },
+ "System.Text.Encoding.Extensions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==",
+ "path": "system.text.encoding.extensions/4.3.0",
+ "hashPath": "system.text.encoding.extensions.4.3.0.nupkg.sha512"
+ },
+ "System.Text.RegularExpressions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==",
+ "path": "system.text.regularexpressions/4.3.0",
+ "hashPath": "system.text.regularexpressions.4.3.0.nupkg.sha512"
+ },
+ "System.Threading/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==",
+ "path": "system.threading/4.3.0",
+ "hashPath": "system.threading.4.3.0.nupkg.sha512"
+ },
+ "System.Threading.Tasks/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
+ "path": "system.threading.tasks/4.3.0",
+ "hashPath": "system.threading.tasks.4.3.0.nupkg.sha512"
+ },
+ "System.Threading.Tasks.Extensions/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-npvJkVKl5rKXrtl1Kkm6OhOUaYGEiF9wFbppFRWSMoApKzt2PiPHT2Bb8a5sAWxprvdOAtvaARS9QYMznEUtug==",
+ "path": "system.threading.tasks.extensions/4.3.0",
+ "hashPath": "system.threading.tasks.extensions.4.3.0.nupkg.sha512"
+ },
+ "System.Windows.Extensions/4.7.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-CeWTdRNfRaSh0pm2gDTJFwVaXfTq6Xwv/sA887iwPTneW7oMtMlpvDIO+U60+3GWTB7Aom6oQwv5VZVUhQRdPQ==",
+ "path": "system.windows.extensions/4.7.0",
+ "hashPath": "system.windows.extensions.4.7.0.nupkg.sha512"
+ },
+ "System.Xml.ReaderWriter/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==",
+ "path": "system.xml.readerwriter/4.3.0",
+ "hashPath": "system.xml.readerwriter.4.3.0.nupkg.sha512"
+ },
+ "System.Xml.XDocument/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==",
+ "path": "system.xml.xdocument/4.3.0",
+ "hashPath": "system.xml.xdocument.4.3.0.nupkg.sha512"
+ },
+ "System.Xml.XmlDocument/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-lJ8AxvkX7GQxpC6GFCeBj8ThYVyQczx2+f/cWHJU8tjS7YfI6Cv6bon70jVEgs2CiFbmmM8b9j1oZVx0dSI2Ww==",
+ "path": "system.xml.xmldocument/4.3.0",
+ "hashPath": "system.xml.xmldocument.4.3.0.nupkg.sha512"
+ },
+ "System.Xml.XmlSerializer/4.3.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-MYoTCP7EZ98RrANESW05J5ZwskKDoN0AuZ06ZflnowE50LTpbR5yRg3tHckTVm5j/m47stuGgCrCHWePyHS70Q==",
+ "path": "system.xml.xmlserializer/4.3.0",
+ "hashPath": "system.xml.xmlserializer.4.3.0.nupkg.sha512"
+ },
+ "Unity/5.11.10": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-B4+Ps3oqI78hJ+dAFsJhPkJT6qycsNExgLbtw7CEHSzKc2ac3YyUR8SHQ+ZyTwld/y5IbDx/aNOHnKE9Em1zWA==",
+ "path": "unity/5.11.10",
+ "hashPath": "unity.5.11.10.nupkg.sha512"
+ },
+ "DatabaseCore/1.0.0": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ },
+ "ModelTools/1.0.0": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ },
+ "SecurityBusinessLogic/1.0.0": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Extensions/net5.0/SecurityImplementation.dll b/DepartmentPortal/Extensions/net5.0/SecurityImplementation.dll
new file mode 100644
index 0000000..1af8b4b
Binary files /dev/null and b/DepartmentPortal/Extensions/net5.0/SecurityImplementation.dll differ
diff --git a/DepartmentPortal/Extensions/net5.0/ref/SecurityImplementation.dll b/DepartmentPortal/Extensions/net5.0/ref/SecurityImplementation.dll
new file mode 100644
index 0000000..4beadf6
Binary files /dev/null and b/DepartmentPortal/Extensions/net5.0/ref/SecurityImplementation.dll differ
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/AccessBindingModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/AccessBindingModels.cs
new file mode 100644
index 0000000..4a14227
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/AccessBindingModels.cs
@@ -0,0 +1,28 @@
+using ModelTools.BindingModels;
+using ModelTools.Enums;
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace SecurityBusinessLogic.BindingModels
+{
+ ///
+ /// Получение информации по доступу
+ ///
+ public class AccessGetBindingModel : GetBindingModel
+ {
+ public Guid? RoleId { get; set; }
+ }
+
+ ///
+ /// Сохранение информации по доступу
+ ///
+ public class AccessSetBindingModel : SetBindingModel
+ {
+ public Guid RoleId { get; set; }
+
+ [Required(ErrorMessage = "required")]
+ public AccessOperation Operation { get; set; }
+
+ public AccessType AccessType { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/EnviromentSettingBindingModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/EnviromentSettingBindingModels.cs
new file mode 100644
index 0000000..e672f6f
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/EnviromentSettingBindingModels.cs
@@ -0,0 +1,25 @@
+using ModelTools.BindingModels;
+using System.ComponentModel.DataAnnotations;
+
+namespace SecurityBusinessLogic.BindingModels
+{
+ ///
+ /// Получение общих настроек системы
+ ///
+ public class EnviromentSettingGetBindingModel : GetBindingModel
+ {
+ public string Key { get; set; }
+ }
+
+ ///
+ /// Сохранение общих настроек системы
+ ///
+ public class EnviromentSettingSetBindingModel : SetBindingModel
+ {
+ [Required(ErrorMessage = "required")]
+ public string Key { get; set; }
+
+ [Required(ErrorMessage = "required")]
+ public string Value { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/RoleBindingModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/RoleBindingModels.cs
new file mode 100644
index 0000000..2cbbc29
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/RoleBindingModels.cs
@@ -0,0 +1,22 @@
+using ModelTools.BindingModels;
+using System.ComponentModel.DataAnnotations;
+
+namespace SecurityBusinessLogic.BindingModels
+{
+ ///
+ /// Получение роли
+ ///
+ public class RoleGetBindingModel : GetBindingModel { }
+
+ ///
+ /// Сохранение роли
+ ///
+ public class RoleSetBindingModel : SetBindingModel
+ {
+ [Required(ErrorMessage = "required")]
+ public string RoleName { get; set; }
+
+ [Required(ErrorMessage = "required")]
+ public int RolePriority { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/UserBindingModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/UserBindingModels.cs
new file mode 100644
index 0000000..daf0b13
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BindingModels/UserBindingModels.cs
@@ -0,0 +1,49 @@
+using ModelTools.BindingModels;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace SecurityBusinessLogic.BindingModels
+{
+ ///
+ /// Получение пользователя
+ ///
+ public class UserGetBindingModel : GetBindingModel
+ {
+ public bool? IsBanned { get; set; }
+
+ public string Login { get; set; }
+
+ public string Password { get; set; }
+
+ public List LecturerIds { get; set; }
+ }
+
+ ///
+ /// Сохранение пользователя
+ ///
+ public class UserSetBindingModel : SetBindingModel
+ {
+ [Required(ErrorMessage = "required")]
+ public string Login { get; set; }
+
+ [Required(ErrorMessage = "required")]
+ public string Password { get; set; }
+
+ public Guid? StudentId { get; set; }
+
+ public Guid? LecturerId { get; set; }
+
+ public Guid? EmployeeId { get; set; }
+
+ public byte[] Avatar { get; set; }
+
+ public DateTime? DateLastVisit { get; set; }
+
+ public bool IsBanned { get; set; }
+
+ public DateTime? DateBanned { get; set; }
+
+ public int CountAttempt { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/AccessBusinessLogic.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/AccessBusinessLogic.cs
new file mode 100644
index 0000000..0c7cfec
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/AccessBusinessLogic.cs
@@ -0,0 +1,21 @@
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+
+namespace SecurityBusinessLogic.BusinessLogics
+{
+ ///
+ /// Логика работы с доступами
+ ///
+ public class AccessBusinessLogic : BusinessLogicCore
+ {
+ public AccessBusinessLogic(IAccessService service) : base(service, "Доступы", AccessOperation.Доступы) { }
+
+ protected override AccessViewModel ConvertToE(OperationResultModel model) => model.Result as AccessViewModel;
+
+ protected override AccessListViewModel ConvertToL(OperationResultModel model) => model.Result as AccessListViewModel;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/EnviromentSettingBusinessLogic.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/EnviromentSettingBusinessLogic.cs
new file mode 100644
index 0000000..7f54e26
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/EnviromentSettingBusinessLogic.cs
@@ -0,0 +1,22 @@
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+
+namespace SecurityBusinessLogic.BusinessLogics
+{
+ ///
+ /// Логика работы с общими настройками системы
+ ///
+ public class EnviromentSettingBusinessLogic : BusinessLogicCore
+ {
+ public EnviromentSettingBusinessLogic(IEnviromentSettingService service) : base(service, "Настройки Среды", AccessOperation.НастройкиСреды) { }
+
+ protected override EnviromentSettingViewModel ConvertToE(OperationResultModel model) => model.Result as EnviromentSettingViewModel;
+
+ protected override EnviromentSettingListViewModel ConvertToL(OperationResultModel model) => model.Result as EnviromentSettingListViewModel;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/RoleBusinessLogic.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/RoleBusinessLogic.cs
new file mode 100644
index 0000000..26a4e15
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/RoleBusinessLogic.cs
@@ -0,0 +1,21 @@
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+
+namespace SecurityBusinessLogic.BusinessLogics
+{
+ ///
+ /// Логика работы с ролями
+ ///
+ public class RoleBusinessLogic : BusinessLogicCore
+ {
+ public RoleBusinessLogic(IRoleService service) : base(service, "Роли", AccessOperation.Роли) { }
+
+ protected override RoleViewModel ConvertToE(OperationResultModel model) => model.Result as RoleViewModel;
+
+ protected override RoleListViewModel ConvertToL(OperationResultModel model) => model.Result as RoleListViewModel;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/UserBusinessLogic.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/UserBusinessLogic.cs
new file mode 100644
index 0000000..ff84eaf
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/UserBusinessLogic.cs
@@ -0,0 +1,21 @@
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+
+namespace SecurityBusinessLogic.BusinessLogics
+{
+ ///
+ /// Логика работы с пользователями
+ ///
+ public class UserBusinessLogic : BusinessLogicCore
+ {
+ public UserBusinessLogic(IUserService service) : base(service, "Пользователи", AccessOperation.Пользователи) { }
+
+ protected override UserViewModel ConvertToE(OperationResultModel model) => model.Result as UserViewModel;
+
+ protected override UserListViewModel ConvertToL(OperationResultModel model) => model.Result as UserListViewModel;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/UserManager.cs b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/UserManager.cs
new file mode 100644
index 0000000..491c729
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/UserManager.cs
@@ -0,0 +1,223 @@
+using ModelTools.BusinessLogics;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SecurityBusinessLogic.BusinessLogics
+{
+ ///
+ /// Менеджер по работе с пользователем системы
+ ///
+ public class UserManager
+ {
+ private readonly int _countDayToBanned = 3;
+
+ private readonly int _countMaxAttempt = 3;
+
+ private readonly RoleBusinessLogic _roleBusinessLogic;
+
+ private readonly UserBusinessLogic _userBusinessLogic;
+
+ private static UserManager _userManager;
+
+ private static readonly object _lockObject = new();
+
+ private UserManager()
+ {
+ _roleBusinessLogic = UnityContainerConfigurator.Resolve();
+ _userBusinessLogic = UnityContainerConfigurator.Resolve();
+ }
+
+ public static UserManager GetInstance
+ {
+ get
+ {
+ if (_userManager == null)
+ {
+ lock (_lockObject)
+ {
+ _userManager = new UserManager();
+ }
+ }
+
+ return _userManager;
+ }
+ }
+
+ ///
+ /// Аутентифицированный пользователь
+ ///
+ public UserViewModel User { get; private set; }
+
+ ///
+ /// Список ролей аутентифицированного пользователь
+ ///
+ public List Roles { get; private set; }
+
+ ///
+ /// Сообщение об ошибке
+ ///
+ public string ErrorMessage { get; private set; }
+
+ ///
+ /// Идентификатор аутентифицированного пользователь
+ ///
+ public Guid? UserId => User?.Id;
+
+ ///
+ /// Выполнена ли аутентификация
+ ///
+ public bool IsAuth => User != null;
+
+ ///
+ /// Аутентификация пользователя
+ ///
+ ///
+ ///
+ ///
+ public async Task LoginAsync(string login, string password)
+ {
+ await Task.Run(() =>
+ {
+ UserSetBindingModel model;
+ var passwordHash = GetPasswordHash(password);
+ var user = _userBusinessLogic.GetElement(new UserGetBindingModel
+ {
+ Login = login,
+ Password = passwordHash,
+ SkipCheck = true
+ });
+
+ if (user == null)
+ {
+ if(_userBusinessLogic.Errors.Count > 0)
+ {
+ throw new Exception(_userBusinessLogic.Errors[0].Message);
+ }
+
+ user = _userBusinessLogic.GetElement(new UserGetBindingModel
+ {
+ Login = login,
+ IsBanned = true,
+ SkipCheck = true
+ });
+ if (user != null)
+ {
+ user.CountAttempt++;
+ if (user.CountAttempt > _countMaxAttempt)
+ {
+ user.IsBanned = true;
+ user.DateBanned = DateTime.Now;
+ }
+
+ model = GetSetBindingModel(user);
+ model.Password = passwordHash;
+ _userBusinessLogic.Update(model);
+ }
+
+ if (_userBusinessLogic.Errors.Count > 0)
+ {
+ throw new Exception(_userBusinessLogic.Errors[0].Message);
+ }
+
+ throw new Exception("Введен неверный логин/пароль");
+ }
+ if (user.IsBanned)
+ {
+ if (user.DateBanned.Value.AddDays(_countDayToBanned) > DateTime.Now)
+ {
+ user.IsBanned = false;
+ }
+ else
+ {
+ throw new Exception("Пользователь заблокирован");
+ }
+ }
+
+ user.DateLastVisit = DateTime.Now;
+ user.CountAttempt = 0;
+
+ model = GetSetBindingModel(user);
+ model.Password = passwordHash;
+ _userBusinessLogic.Update(model);
+
+ User = user;
+ Roles = _roleBusinessLogic.GetList(new RoleGetBindingModel { UserId = User.Id }).List.Select(x => x.Id).ToList();
+ });
+ }
+
+ ///
+ /// Выход из системы
+ ///
+ ///
+ public async Task LogoutAsync()
+ {
+ await Task.Run(() =>
+ {
+ User = null;
+ Roles = null;
+ });
+ }
+
+ ///
+ /// Смена пароля
+ ///
+ ///
+ ///
+ ///
+ public void ChangePassword(string login, string oldPassword, string newPassword)
+ {
+ var user = _userBusinessLogic.GetElement(new UserGetBindingModel
+ {
+ Login = login,
+ Password = GetPasswordHash(oldPassword),
+ SkipCheck = true
+ });
+ if (user == null)
+ {
+ throw new Exception("Введен неверный логин/пароль");
+ }
+ if (user.IsBanned)
+ {
+ throw new Exception("Пользователь забаннен");
+ }
+ var model = GetSetBindingModel(user);
+ model.Password = GetPasswordHash(newPassword);
+ _userBusinessLogic.Update(model);
+ }
+
+ ///
+ /// Получение хеша пароля
+ ///
+ ///
+ ///
+ public static string GetPasswordHash(string password) => Encoding.ASCII.GetString((new MD5CryptoServiceProvider()).ComputeHash(Encoding.ASCII.GetBytes(password)));
+
+ ///
+ /// Получение модели для сохранения из представления
+ ///
+ ///
+ ///
+ private static UserSetBindingModel GetSetBindingModel(UserViewModel model)
+ {
+ return new UserSetBindingModel
+ {
+ Id = model.Id,
+ Login = model.Login,
+ LecturerId = model.LecturerId,
+ StudentId = model.StudentId,
+ EmployeeId = model.EmployeeId,
+ Avatar = model.Avatar,
+ IsBanned = model.IsBanned,
+ DateBanned = model.DateBanned,
+ CountAttempt = model.CountAttempt,
+ DateLastVisit = model.DateLastVisit
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IAccessService.cs b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IAccessService.cs
new file mode 100644
index 0000000..9d25010
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IAccessService.cs
@@ -0,0 +1,10 @@
+using ModelTools.Interfaces;
+using SecurityBusinessLogic.BindingModels;
+
+namespace SecurityBusinessLogic.Interfaces
+{
+ ///
+ /// Хранение доступов
+ ///
+ public interface IAccessService : IEntityService { }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IEnviromentSettingService.cs b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IEnviromentSettingService.cs
new file mode 100644
index 0000000..1c4fea5
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IEnviromentSettingService.cs
@@ -0,0 +1,10 @@
+using ModelTools.Interfaces;
+using SecurityBusinessLogic.BindingModels;
+
+namespace SecurityBusinessLogic.Interfaces
+{
+ ///
+ /// Хранение общих настроек системы
+ ///
+ public interface IEnviromentSettingService : IEntityService { }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IRoleService.cs b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IRoleService.cs
new file mode 100644
index 0000000..e65ce8c
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IRoleService.cs
@@ -0,0 +1,10 @@
+using ModelTools.Interfaces;
+using SecurityBusinessLogic.BindingModels;
+
+namespace SecurityBusinessLogic.Interfaces
+{
+ ///
+ /// Хранение ролей
+ ///
+ public interface IRoleService : IEntityService { }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IUserService.cs b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IUserService.cs
new file mode 100644
index 0000000..d62fdac
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/Interfaces/IUserService.cs
@@ -0,0 +1,10 @@
+using ModelTools.Interfaces;
+using SecurityBusinessLogic.BindingModels;
+
+namespace SecurityBusinessLogic.Interfaces
+{
+ ///
+ /// Хранение пользователей
+ ///
+ public interface IUserService : IEntityService { }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/SecurityBusinessLogic.csproj b/DepartmentPortal/Security/SecurityBusinessLogic/SecurityBusinessLogic.csproj
new file mode 100644
index 0000000..eea8d8b
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/SecurityBusinessLogic.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/AccessViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/AccessViewModels.cs
new file mode 100644
index 0000000..3ae3438
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/AccessViewModels.cs
@@ -0,0 +1,42 @@
+using ModelTools.Attributes;
+using ModelTools.Enums;
+using ModelTools.ViewModels;
+using System;
+
+namespace SecurityBusinessLogic.ViewModels
+{
+ ///
+ /// Список достпуов
+ ///
+ public class AccessListViewModel : ListViewModel { }
+
+ ///
+ /// Элемент доступа
+ ///
+ public class AccessViewModel : ElementViewModel
+ {
+ [ViewModelProperty("Роль", false, true)]
+ [MapConfiguration("RoleId")]
+ public Guid RoleId { get; set; }
+
+ [ViewModelProperty("Роль", true, false, 100)]
+ [MapConfiguration("Role.RoleName", true)]
+ public string RoleName { get; set; }
+
+ [ViewModelProperty("Операция", false, true)]
+ [MapConfiguration("AccessOperation")]
+ public AccessOperation AccessOperation { get; set; }
+
+ [ViewModelProperty("Операция", true, false)]
+ public string AccessOperationTitle => AccessOperation.ToString("G");
+
+ [ViewModelProperty("Тип", false, true)]
+ [MapConfiguration("AccessType")]
+ public AccessType AccessType { get; set; }
+
+ [ViewModelProperty("Тип", true, false, 50)]
+ public string AccessTypeTitle => AccessType.ToString("G");
+
+ public override string ToString() => $"{RoleName}-{AccessOperationTitle}({AccessTypeTitle})";
+ }
+}
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/EnviromentSettingViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/EnviromentSettingViewModels.cs
new file mode 100644
index 0000000..20d6262
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/EnviromentSettingViewModels.cs
@@ -0,0 +1,26 @@
+using ModelTools.Attributes;
+using ModelTools.ViewModels;
+
+namespace SecurityBusinessLogic.ViewModels
+{
+ ///
+ /// Список общих настроек системы
+ ///
+ public class EnviromentSettingListViewModel : ListViewModel { }
+
+ ///
+ /// Элемент общих настроек системы
+ ///
+ public class EnviromentSettingViewModel : ElementViewModel
+ {
+ [ViewModelProperty("Ключ", true, true)]
+ [MapConfiguration("Key")]
+ public string Key { get; set; }
+
+ [ViewModelProperty("Значение", true, true, 100)]
+ [MapConfiguration("Value")]
+ public int Value { get; set; }
+
+ public override string ToString() => Key;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/RoleViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/RoleViewModels.cs
new file mode 100644
index 0000000..e55dad6
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/RoleViewModels.cs
@@ -0,0 +1,26 @@
+using ModelTools.Attributes;
+using ModelTools.ViewModels;
+
+namespace SecurityBusinessLogic.ViewModels
+{
+ ///
+ /// Список ролей
+ ///
+ public class RoleListViewModel : ListViewModel { }
+
+ ///
+ /// Элемент ролей
+ ///
+ public class RoleViewModel : ElementViewModel
+ {
+ [ViewModelProperty("Название роли", true, true)]
+ [MapConfiguration("RoleName")]
+ public string RoleName { get; set; }
+
+ [ViewModelProperty("Приоритет", true, true, 100)]
+ [MapConfiguration("RolePriority")]
+ public int RolePriority { get; set; }
+
+ public override string ToString() => RoleName;
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserViewModels.cs
new file mode 100644
index 0000000..56c8933
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserViewModels.cs
@@ -0,0 +1,62 @@
+using ModelTools.Attributes;
+using ModelTools.ViewModels;
+using System;
+
+namespace SecurityBusinessLogic.ViewModels
+{
+ ///
+ /// Список пользователей
+ ///
+ public class UserListViewModel : ListViewModel { }
+
+ ///
+ /// Элемент пользователей
+ ///
+ public class UserViewModel : ElementViewModel
+ {
+ [ViewModelProperty("Пользователь", true, true)]
+ [MapConfiguration("UserName")]
+ public string Login { get; set; }
+
+ [ViewModelProperty("Студент", false, true)]
+ [MapConfiguration("StudentId")]
+ public Guid? StudentId { get; set; }
+
+ [ViewModelProperty("Преподаватель", false, true)]
+ [MapConfiguration("LecturerId")]
+ public Guid? LecturerId { get; set; }
+
+ [ViewModelProperty("Сотрудник", false, true)]
+ [MapConfiguration("EmployeeId")]
+ public Guid? EmployeeId { get; set; }
+
+ [ViewModelProperty("Фото", false, true)]
+ [MapConfiguration("Avatar")]
+ public byte[] Avatar { get; set; }
+
+ [ViewModelProperty("Посл. визит", true, false, 100)]
+ [MapConfiguration("DateLastVisit")]
+ public DateTime? DateLastVisit { get; set; }
+
+ [ViewModelProperty("Блокировка", false, true)]
+ [MapConfiguration("IsBanned")]
+ public bool IsBanned { get; set; }
+
+ [ViewModelProperty("Блокир.", true, false, 100)]
+ public string Banned => IsBanned ? "Да" : "Нет";
+
+ [ViewModelProperty("Дата Б.", false, true, 100)]
+ [MapConfiguration("DateBanned")]
+ public DateTime? DateBanned { get; set; }
+
+ [ViewModelProperty("Дата Б.", true, false, 100)]
+ public string DateBannedTitle => DateBanned.HasValue ? DateBanned.Value.ToShortDateString() : string.Empty;
+
+ [ViewModelProperty("Количество попыток входа", false, false)]
+ [MapConfiguration("CountAttempt")]
+ public int CountAttempt { get; set; }
+
+ public override string ToString() => Login;
+
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityImplementation/Implementations/AccessService.cs b/DepartmentPortal/Security/SecurityImplementation/Implementations/AccessService.cs
new file mode 100644
index 0000000..27caa61
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityImplementation/Implementations/AccessService.cs
@@ -0,0 +1,131 @@
+using DatabaseCore;
+using DatabaseCore.Models.Security;
+using Microsoft.EntityFrameworkCore;
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+using System;
+using System.Linq;
+
+namespace SecurityImplementation.Implementations
+{
+ ///
+ /// Реализация IAccessService
+ ///
+ public class AccessService : IAccessService
+ {
+ public OperationResultModel Create(AccessSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var exsistEntity = context.Accesses.FirstOrDefault(x => x.Operation == model.Operation && x.RoleId == model.RoleId && x.AccessType == model.AccessType);
+ if (exsistEntity == null)
+ {
+ var entity = Mapper.MapToClass(model);
+ context.Accesses.Add(entity);
+ context.SaveChanges();
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ else
+ {
+ if (exsistEntity.IsDeleted)
+ {
+ exsistEntity.IsDeleted = false;
+ context.SaveChanges();
+ return OperationResultModel.Success(Mapper.MapToClass(exsistEntity));
+ }
+ else
+ {
+ return OperationResultModel.Error("Error:", "Элемент уже существует", ResultServiceStatusCode.ExsistItem);
+ }
+ }
+ }
+
+ public OperationResultModel Delete(AccessGetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var entity = context.Accesses.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ else if (entity.IsDeleted)
+ {
+ return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
+ }
+ entity.IsDeleted = true;
+ entity.DateDelete = DateTime.Now;
+
+ context.SaveChanges();
+
+ return OperationResultModel.Success(true);
+ }
+
+ public OperationResultModel Read(AccessGetBindingModel model)
+ {
+ int countPages = 0;
+ using var context = DatabaseManager.GetContext;
+
+ // для одной записи
+ if(model.Id.HasValue)
+ {
+ var entity = context.Accesses.FirstOrDefault(x => x.Id == model.Id.Value);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+
+ var query = context.Accesses.Where(x => !x.IsDeleted).AsQueryable();
+ if (model.RoleId.HasValue)
+ {
+ query = query.Where(x => x.RoleId == model.RoleId);
+ }
+
+ query = query.OrderBy(x => x.Role.RoleName).ThenBy(x => x.Operation).ThenBy(x => x.AccessType);
+
+ if (model.PageNumber.HasValue && model.PageSize.HasValue)
+ {
+ countPages = (int)Math.Ceiling((double)query.Count() / model.PageSize.Value);
+ query = query
+ .Skip(model.PageSize.Value * model.PageNumber.Value)
+ .Take(model.PageSize.Value);
+ }
+
+ query = query.Include(x => x.Role);
+
+ var result = new AccessListViewModel
+ {
+ MaxCount = countPages,
+ List = query.Select(Mapper.MapToClass).ToList()
+ };
+
+ return OperationResultModel.Success(result);
+ }
+
+ public OperationResultModel Update(AccessSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var entity = context.Accesses.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ else if (entity.IsDeleted)
+ {
+ return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
+ }
+ entity = Mapper.MapToClass(model, entity);
+
+ context.SaveChanges();
+
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityImplementation/Implementations/EnviromentSettingService.cs b/DepartmentPortal/Security/SecurityImplementation/Implementations/EnviromentSettingService.cs
new file mode 100644
index 0000000..01ea3d0
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityImplementation/Implementations/EnviromentSettingService.cs
@@ -0,0 +1,114 @@
+using DatabaseCore;
+using DatabaseCore.Models.Security;
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.Extensions;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+using System;
+using System.Linq;
+
+namespace SecurityImplementation.Implementations
+{
+ ///
+ /// Реализация IEnviromentSettingService
+ ///
+ public class EnviromentSettingService : IEnviromentSettingService
+ {
+ public OperationResultModel Create(EnviromentSettingSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var exsistEntity = context.EnviromentSettings.FirstOrDefault(x => x.Key == model.Key);
+ if (exsistEntity == null)
+ {
+ var entity = Mapper.MapToClass(model);
+ context.EnviromentSettings.Add(entity);
+ context.SaveChanges();
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ return OperationResultModel.Error("Error:", "Элемент уже существует", ResultServiceStatusCode.ExsistItem);
+ }
+
+ public OperationResultModel Delete(EnviromentSettingGetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var entity = context.EnviromentSettings.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+
+ context.EnviromentSettings.Remove(entity);
+ context.SaveChanges();
+
+ return OperationResultModel.Success(true);
+ }
+
+ public OperationResultModel Read(EnviromentSettingGetBindingModel model)
+ {
+ int countPages = 0;
+ using var context = DatabaseManager.GetContext;
+
+ // для одной записи
+ if (model.Id.HasValue)
+ {
+ var entity = context.EnviromentSettings.FirstOrDefault(x => x.Id == model.Id.Value);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+
+ if (model.Key.IsNotEmpty())
+ {
+ var entity = context.EnviromentSettings.FirstOrDefault(x => x.Key == model.Key);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+
+ var query = context.EnviromentSettings.AsQueryable();
+
+ query = query.OrderBy(x => x.Key);
+
+ if (model.PageNumber.HasValue && model.PageSize.HasValue)
+ {
+ countPages = (int)Math.Ceiling((double)query.Count() / model.PageSize.Value);
+ query = query
+ .Skip(model.PageSize.Value * model.PageNumber.Value)
+ .Take(model.PageSize.Value);
+ }
+
+ var result = new EnviromentSettingListViewModel
+ {
+ MaxCount = countPages,
+ List = query.Select(Mapper.MapToClass).ToList()
+ };
+
+ return OperationResultModel.Success(result);
+ }
+
+ public OperationResultModel Update(EnviromentSettingSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var entity = context.EnviromentSettings.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ entity = Mapper.MapToClass(model, entity);
+
+ context.SaveChanges();
+
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityImplementation/Implementations/RoleService.cs b/DepartmentPortal/Security/SecurityImplementation/Implementations/RoleService.cs
new file mode 100644
index 0000000..80b19b4
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityImplementation/Implementations/RoleService.cs
@@ -0,0 +1,150 @@
+using DatabaseCore;
+using DatabaseCore.Models.Security;
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+using System;
+using System.Linq;
+
+namespace SecurityImplementation.Implementations
+{
+ ///
+ /// Реализация IRoleService
+ ///
+ public class RoleService : IRoleService
+ {
+ public OperationResultModel Create(RoleSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var exsistEntity = context.Roles.FirstOrDefault(x => x.RoleName == model.RoleName);
+ if (exsistEntity == null)
+ {
+ var entity = Mapper.MapToClass(model);
+ context.Roles.Add(entity);
+ context.SaveChanges();
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ else
+ {
+ if (exsistEntity.IsDeleted)
+ {
+ exsistEntity.IsDeleted = false;
+ context.SaveChanges();
+ return OperationResultModel.Success(Mapper.MapToClass(exsistEntity));
+ }
+ else
+ {
+ return OperationResultModel.Error("Error:", "Элемент уже существует", ResultServiceStatusCode.ExsistItem);
+ }
+ }
+ }
+
+ public OperationResultModel Delete(RoleGetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+ using var transaction = context.Database.BeginTransaction();
+ try
+ {
+ var entity = context.Roles.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ else if (entity.IsDeleted)
+ {
+ return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
+ }
+ entity.IsDeleted = true;
+ entity.DateDelete = DateTime.Now;
+
+ context.SaveChanges();
+
+ var access = context.Accesses.Where(x => x.RoleId == model.Id);
+ foreach(var ac in access)
+ {
+ ac.IsDeleted = true;
+ ac.DateDelete = DateTime.Now;
+ }
+ context.SaveChanges();
+
+ var users = context.UserRoles.Where(x => x.RoleId == model.Id);
+ foreach (var u in users)
+ {
+ u.IsDeleted = true;
+ u.DateDelete = DateTime.Now;
+ }
+ context.SaveChanges();
+
+ transaction.Commit();
+ }
+ catch(Exception)
+ {
+ transaction.Rollback();
+ throw;
+ }
+
+ return OperationResultModel.Success(true);
+ }
+
+ public OperationResultModel Read(RoleGetBindingModel model)
+ {
+ int countPages = 0;
+ using var context = DatabaseManager.GetContext;
+
+ // для одной записи
+ if (model.Id.HasValue)
+ {
+ var entity = context.Roles.FirstOrDefault(x => x.Id == model.Id.Value);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+
+ var query = context.Roles.Where(x => !x.IsDeleted).AsQueryable();
+
+ query = query.OrderBy(x => x.RoleName);
+
+ if (model.PageNumber.HasValue && model.PageSize.HasValue)
+ {
+ countPages = (int)Math.Ceiling((double)query.Count() / model.PageSize.Value);
+ query = query
+ .Skip(model.PageSize.Value * model.PageNumber.Value)
+ .Take(model.PageSize.Value);
+ }
+
+ var result = new RoleListViewModel
+ {
+ MaxCount = countPages,
+ List = query.Select(Mapper.MapToClass).ToList()
+ };
+
+ return OperationResultModel.Success(result);
+ }
+
+ public OperationResultModel Update(RoleSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var entity = context.Roles.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ else if (entity.IsDeleted)
+ {
+ return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
+ }
+ entity = Mapper.MapToClass(model, entity);
+
+ context.SaveChanges();
+
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityImplementation/Implementations/UserService.cs b/DepartmentPortal/Security/SecurityImplementation/Implementations/UserService.cs
new file mode 100644
index 0000000..142698c
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityImplementation/Implementations/UserService.cs
@@ -0,0 +1,171 @@
+using DatabaseCore;
+using DatabaseCore.Models.Security;
+using ModelTools.BusinessLogics;
+using ModelTools.Enums;
+using ModelTools.Extensions;
+using ModelTools.OperationResultModels;
+using SecurityBusinessLogic.BindingModels;
+using SecurityBusinessLogic.Interfaces;
+using SecurityBusinessLogic.ViewModels;
+using System;
+using System.Linq;
+
+namespace SecurityImplementation.Implementations
+{
+ ///
+ /// Реализация IUserService
+ ///
+ public class UserService : IUserService
+ {
+ public OperationResultModel Create(UserSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var exsistEntity = context.Users.FirstOrDefault(x => x.UserName == model.Login);
+ if (exsistEntity == null)
+ {
+ var entity = Mapper.MapToClass(model);
+ context.Users.Add(entity);
+ context.SaveChanges();
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ else
+ {
+ if (exsistEntity.IsDeleted)
+ {
+ exsistEntity.IsDeleted = false;
+ context.SaveChanges();
+ return OperationResultModel.Success(Mapper.MapToClass(exsistEntity));
+ }
+ else
+ {
+ return OperationResultModel.Error("Error:", "Элемент уже существует", ResultServiceStatusCode.ExsistItem);
+ }
+ }
+ }
+
+ public OperationResultModel Delete(UserGetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+ using var transaction = context.Database.BeginTransaction();
+ try
+ {
+ var entity = context.Users.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ else if (entity.IsDeleted)
+ {
+ return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
+ }
+ entity.IsDeleted = true;
+ entity.DateDelete = DateTime.Now;
+
+ context.SaveChanges();
+
+ var users = context.UserRoles.Where(x => x.UserId == model.Id);
+ foreach (var u in users)
+ {
+ u.IsDeleted = true;
+ u.DateDelete = DateTime.Now;
+ }
+ context.SaveChanges();
+
+ transaction.Commit();
+ }
+ catch (Exception)
+ {
+ transaction.Rollback();
+ throw;
+ }
+
+ return OperationResultModel.Success(true);
+ }
+
+ public OperationResultModel Read(UserGetBindingModel model)
+ {
+ int countPages = 0;
+ using var context = DatabaseManager.GetContext;
+
+ // для одной записи
+ if (model.Id.HasValue)
+ {
+ var entity = context.Users.FirstOrDefault(x => x.Id == model.Id.Value);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+
+ if (model.Login.IsNotEmpty() && model.Password.IsNotEmpty())
+ {
+ var entity = context.Users.FirstOrDefault(x => x.UserName == model.Login && x.PasswordHash == model.Password);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+
+ if (model.Login.IsNotEmpty() && model.IsBanned.HasValue)
+ {
+ var entity = context.Users.FirstOrDefault(x => x.UserName == model.Login && x.IsBanned == model.IsBanned.Value);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+
+ var query = context.Users.Where(x => !x.IsDeleted).AsQueryable();
+ if (model.IsBanned.HasValue)
+ {
+ query = query.Where(x => x.IsBanned == model.IsBanned.Value);
+ }
+ if (model.LecturerIds != null)
+ {
+ query = query.Where(x => x.LecturerId.HasValue && model.LecturerIds.Contains(x.LecturerId.Value));
+ }
+
+ query = query.OrderBy(x => x.UserName);
+
+ if (model.PageNumber.HasValue && model.PageSize.HasValue)
+ {
+ countPages = (int)Math.Ceiling((double)query.Count() / model.PageSize.Value);
+ query = query
+ .Skip(model.PageSize.Value * model.PageNumber.Value)
+ .Take(model.PageSize.Value);
+ }
+
+ var result = new UserListViewModel
+ {
+ MaxCount = countPages,
+ List = query.Select(Mapper.MapToClass).ToList()
+ };
+
+ return OperationResultModel.Success(result);
+ }
+
+ public OperationResultModel Update(UserSetBindingModel model)
+ {
+ using var context = DatabaseManager.GetContext;
+
+ var entity = context.Users.FirstOrDefault(x => x.Id == model.Id);
+ if (entity == null)
+ {
+ return OperationResultModel.Error("Error:", "Элемент не найден", ResultServiceStatusCode.NotFound);
+ }
+ else if (entity.IsDeleted)
+ {
+ return OperationResultModel.Error("Error:", "Элемент был удален", ResultServiceStatusCode.WasDelete);
+ }
+ entity = Mapper.MapToClass(model, entity);
+
+ context.SaveChanges();
+
+ return OperationResultModel.Success(Mapper.MapToClass(entity));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DepartmentPortal/Security/SecurityImplementation/SecurityImplementation.csproj b/DepartmentPortal/Security/SecurityImplementation/SecurityImplementation.csproj
new file mode 100644
index 0000000..d808588
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityImplementation/SecurityImplementation.csproj
@@ -0,0 +1,16 @@
+
+
+
+ net5.0
+
+
+
+ ..\..\Extensions\
+
+
+
+
+
+
+
+
diff --git a/DepartmentPortal/Security/SecurityImplementation/SecurityLoaderExtensions.cs b/DepartmentPortal/Security/SecurityImplementation/SecurityLoaderExtensions.cs
new file mode 100644
index 0000000..b9767c4
--- /dev/null
+++ b/DepartmentPortal/Security/SecurityImplementation/SecurityLoaderExtensions.cs
@@ -0,0 +1,24 @@
+using ModelTools.BusinessLogics;
+using ModelTools.Interfaces;
+using SecurityBusinessLogic.BusinessLogics;
+using SecurityBusinessLogic.Interfaces;
+using SecurityImplementation.Implementations;
+
+namespace SecurityImplementation
+{
+ public class SecurityLoaderExtensions : ILoaderExtensions
+ {
+ public void RegisterServices()
+ {
+ UnityContainerConfigurator.PublishService();
+ UnityContainerConfigurator.PublishService();
+ UnityContainerConfigurator.PublishService();
+ UnityContainerConfigurator.PublishService();
+
+ UnityContainerConfigurator.PublishService();
+ UnityContainerConfigurator.PublishService();
+ UnityContainerConfigurator.PublishService();
+ UnityContainerConfigurator.PublishService();
+ }
+ }
+}
\ No newline at end of file