WebFileServer20

Details

diff --git a/Src/Tools.Identity.EF/Entities/BaseUser.cs b/Src/Tools.Identity.EF/Entities/BaseUser.cs
index 38048a4..10dfdfe 100644
--- a/Src/Tools.Identity.EF/Entities/BaseUser.cs
+++ b/Src/Tools.Identity.EF/Entities/BaseUser.cs
@@ -17,6 +17,7 @@ namespace Tools.Identity.EF.Entities
         where TRole : BaseRole<TKey, TUser, TRole>
     {
         public virtual List<BaseUserRole<TKey, TUser, TRole>> Roles { set; get; }
+            = new List<BaseUserRole<TKey, TUser, TRole>>();
 
 
         [NotMapped]
diff --git a/Src/WebFileServ.Model.DAL/DataBase/EF/ApplicationDbContext.cs b/Src/WebFileServ.Model.DAL/DataBase/EF/ApplicationDbContext.cs
index 20b9958..240fce8 100644
--- a/Src/WebFileServ.Model.DAL/DataBase/EF/ApplicationDbContext.cs
+++ b/Src/WebFileServ.Model.DAL/DataBase/EF/ApplicationDbContext.cs
@@ -13,6 +13,7 @@ using IdentityServer4.EntityFramework.Options;
 using Tools.Identity.EF;
 
 using WebFileServ.Model.Entities.Identity;
+using WebFileServ.Model.Entities.FS;
 
 namespace WebFileServ.Model.DAL.DataBase.EF
 {
@@ -24,6 +25,15 @@ namespace WebFileServ.Model.DAL.DataBase.EF
             ApplicationUserRole
             >
     {
+        public DbSet<FsItem> FsItems { set; get; }
+        public DbSet<Fs_File> FsFiles { set; get; }
+        public DbSet<Fs_Directory> FsDirectories { set; get; }
+        public DbSet<Fs_RootDirectory> FsRootDirectories { set; get; }
+
+
+        public DbSet<FsItemGroupPermission> FsItemGroupPermissions { set; get; }
+
+
 
         public ApplicationDbContext(
             DbContextOptions<ApplicationDbContext> options,
@@ -46,7 +56,36 @@ namespace WebFileServ.Model.DAL.DataBase.EF
 
             base.OnConfiguring(optionsBuilder);
         }
-        
+
+
+        protected override void OnModelCreating(ModelBuilder builder)
+        {
+            base.OnModelCreating(builder);
+
+
+            builder.Entity<FsItemGroupPermission>()
+                .HasKey(t => new { t.RoleId, t.RootDirectoryId });
+
+            builder.Entity<FsItemGroupPermission>()
+                .HasOne(sc => sc.Role)
+                .WithMany(s => s.RootDirectoryPermission)
+                .HasForeignKey(sc => sc.RoleId);
+
+            builder.Entity<FsItemGroupPermission>()
+                .HasOne(sc => sc.RootDirectory)
+                .WithMany(c => c.GroupPermission)
+                .HasForeignKey(sc => sc.RootDirectoryId);
+
+
+            builder.Entity<Fs_RootDirectory>()
+                .HasIndex(u => u.OwnerUserId);
+            builder
+                .Entity<Fs_RootDirectory>()
+                .HasOne(u => u.OwnerUser)
+                .WithOne(p => p.PersonalDirectory)
+                .HasForeignKey<ApplicationUser>(p => p.PersonalDirectoryId);
+        }
+
     }
 
 }
diff --git a/Src/WebFileServ.Model.DAL/DataInit/DataInitializer.cs b/Src/WebFileServ.Model.DAL/DataInit/DataInitializer.cs
index df782ca..7b0f582 100644
--- a/Src/WebFileServ.Model.DAL/DataInit/DataInitializer.cs
+++ b/Src/WebFileServ.Model.DAL/DataInit/DataInitializer.cs
@@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore;
 using Microsoft.AspNetCore.Identity;
 
 using WebFileServ.Model.Entities.Identity;
+using WebFileServ.Model.Entities.FS;
 
 using WebFileServ.Model.DAL.DataBase.EF;
 
@@ -64,6 +65,7 @@ namespace WebFileServ.Model.DAL.DataInit
             if (DataInitializerConfig.FillData)
             {
                 await CreateAdminUserIfNotExsist();
+                await CreateTestFsItem();
             }            
         }
 
@@ -158,6 +160,68 @@ namespace WebFileServ.Model.DAL.DataInit
         }
 
 
+        private async Task CreateTestFsItem() 
+        {
+            var adminUser = Context.Users
+                .FirstOrDefault();
+
+            var rootDirectory = Context.FsRootDirectories
+                .Add(
+                    new Fs_RootDirectory() 
+                    {
+                        //OwnerUser = adminUser
+                    }
+                    )
+                .Entity;
+
+            await Context
+                .SaveChangesAsync();
+
+            var roleName = "AdminRole";
+            var role = await Context.Roles
+                .FirstOrDefaultAsync(e => e.Name == roleName);
+
+            if (role == null)
+            {
+                throw new Exception("Role not found");
+            }
+
+
+            Context.FsItemGroupPermissions.Add(
+                new FsItemGroupPermission() 
+                {
+                    Role = role,
+                    RootDirectory = rootDirectory,
+                    Permission = EnumPermission.Read
+                }
+                );
+
+            //rootDirectory.GroupPermission = new List<FsItemGroupPermission>() 
+            //{
+            //    new FsItemGroupPermission()
+            //    {
+            //        Role = role,
+            //        RootDirectory = rootDirectory,
+            //        Permission = EnumPermission.Read
+            //    }
+            //};
+            await Context
+                .SaveChangesAsync();
+
+            var permission = rootDirectory
+                .GroupPermission
+                .FirstOrDefault(e => e.RoleId == role.Id);
+
+            if (permission == null)
+            {
+                throw new Exception("Нет доступа");
+            }
+
+            Console.WriteLine($"Ваш доступ:{permission.Permission}");
+        }
+
+
+
         #region Dispose
 
         private bool disposed = false;
diff --git a/Src/WebFileServ.Model.DAL/Migrations/20201124202358_AddFs.cs b/Src/WebFileServ.Model.DAL/Migrations/20201124202358_AddFs.cs
new file mode 100644
index 0000000..b5c62c3
--- /dev/null
+++ b/Src/WebFileServ.Model.DAL/Migrations/20201124202358_AddFs.cs
@@ -0,0 +1,63 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace WebFileServ.Model.DAL.Migrations
+{
+    public partial class AddFs : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "FsItems",
+                columns: table => new
+                {
+                    Id = table.Column<long>(nullable: false)
+                        .Annotation("SqlServer:Identity", "1, 1"),
+                    Discriminator = table.Column<string>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_FsItems", x => x.Id);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "FsItemGroupPermissions",
+                columns: table => new
+                {
+                    RootDirectoryId = table.Column<long>(nullable: false),
+                    RoleId = table.Column<Guid>(nullable: false),
+                    Permission = table.Column<int>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_FsItemGroupPermissions", x => new { x.RoleId, x.RootDirectoryId });
+                    table.ForeignKey(
+                        name: "FK_FsItemGroupPermissions_AspNetRoles_RoleId",
+                        column: x => x.RoleId,
+                        principalTable: "AspNetRoles",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                    table.ForeignKey(
+                        name: "FK_FsItemGroupPermissions_FsItems_RootDirectoryId",
+                        column: x => x.RootDirectoryId,
+                        principalTable: "FsItems",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateIndex(
+                name: "IX_FsItemGroupPermissions_RootDirectoryId",
+                table: "FsItemGroupPermissions",
+                column: "RootDirectoryId");
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "FsItemGroupPermissions");
+
+            migrationBuilder.DropTable(
+                name: "FsItems");
+        }
+    }
+}
diff --git a/Src/WebFileServ.Model.DAL/Migrations/20201124202358_AddFs.Designer.cs b/Src/WebFileServ.Model.DAL/Migrations/20201124202358_AddFs.Designer.cs
new file mode 100644
index 0000000..16b93db
--- /dev/null
+++ b/Src/WebFileServ.Model.DAL/Migrations/20201124202358_AddFs.Designer.cs
@@ -0,0 +1,430 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using WebFileServ.Model.DAL.DataBase.EF;
+
+namespace WebFileServ.Model.DAL.Migrations
+{
+    [DbContext(typeof(ApplicationDbContext))]
+    [Migration("20201124202358_AddFs")]
+    partial class AddFs
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "3.1.9")
+                .HasAnnotation("Relational:MaxIdentifierLength", 128)
+                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+            modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
+                {
+                    b.Property<string>("UserCode")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<string>("ClientId")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<DateTime>("CreationTime")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("Data")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)")
+                        .HasMaxLength(50000);
+
+                    b.Property<string>("DeviceCode")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<DateTime?>("Expiration")
+                        .IsRequired()
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("SubjectId")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.HasKey("UserCode");
+
+                    b.HasIndex("DeviceCode")
+                        .IsUnique();
+
+                    b.HasIndex("Expiration");
+
+                    b.ToTable("DeviceCodes");
+                });
+
+            modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
+                {
+                    b.Property<string>("Key")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<string>("ClientId")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<DateTime>("CreationTime")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("Data")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)")
+                        .HasMaxLength(50000);
+
+                    b.Property<DateTime?>("Expiration")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("SubjectId")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<string>("Type")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(50)")
+                        .HasMaxLength(50);
+
+                    b.HasKey("Key");
+
+                    b.HasIndex("Expiration");
+
+                    b.HasIndex("SubjectId", "ClientId", "Type");
+
+                    b.ToTable("PersistedGrants");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<Guid>("RoleId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetRoleClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("ProviderKey")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("LoginProvider", "ProviderKey");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserLogins");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+                {
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<string>("LoginProvider")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("Name")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("Value")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.HasKey("UserId", "LoginProvider", "Name");
+
+                    b.ToTable("AspNetUserTokens");
+                });
+
+            modelBuilder.Entity("Tools.Identity.EF.Entities.BaseUserRole<System.Guid, WebFileServ.Model.Entities.Identity.ApplicationUser, WebFileServ.Model.Entities.Identity.ApplicationRole>", b =>
+                {
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<Guid>("RoleId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("UserId", "RoleId");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetUserRoles");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItem", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("Discriminator")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FsItems");
+
+                    b.HasDiscriminator<string>("Discriminator").HasValue("FsItem");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItemGroupPermission", b =>
+                {
+                    b.Property<Guid>("RoleId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<long>("RootDirectoryId")
+                        .HasColumnType("bigint");
+
+                    b.Property<int>("Permission")
+                        .HasColumnType("int");
+
+                    b.HasKey("RoleId", "RootDirectoryId");
+
+                    b.HasIndex("RootDirectoryId");
+
+                    b.ToTable("FsItemGroupPermissions");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.Identity.ApplicationRole", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("Name")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("NormalizedName")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasName("RoleNameIndex")
+                        .HasFilter("[NormalizedName] IS NOT NULL");
+
+                    b.ToTable("AspNetRoles");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.Identity.ApplicationUser", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("int");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("Email")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("bit");
+
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("bit");
+
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("datetimeoffset");
+
+                    b.Property<string>("NormalizedEmail")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("NormalizedUserName")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("bit");
+
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("bit");
+
+                    b.Property<string>("UserName")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedEmail")
+                        .HasName("EmailIndex");
+
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasName("UserNameIndex")
+                        .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+                    b.ToTable("AspNetUsers");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_Directory", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.FsItem");
+
+                    b.HasDiscriminator().HasValue("Fs_Directory");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_File", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.FsItem");
+
+                    b.HasDiscriminator().HasValue("Fs_File");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_RootDirectory", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.Fs_Directory");
+
+                    b.HasDiscriminator().HasValue("Fs_RootDirectory");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tools.Identity.EF.Entities.BaseUserRole<System.Guid, WebFileServ.Model.Entities.Identity.ApplicationUser, WebFileServ.Model.Entities.Identity.ApplicationRole>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", "Role")
+                        .WithMany("Users")
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", "User")
+                        .WithMany("Roles")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItemGroupPermission", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", "Role")
+                        .WithMany("RootDirectoryPermission")
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("WebFileServ.Model.Entities.FS.Fs_RootDirectory", "RootDirectory")
+                        .WithMany("GroupPermission")
+                        .HasForeignKey("RootDirectoryId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/Src/WebFileServ.Model.DAL/Migrations/20201124211656_AddPersonalFolder.cs b/Src/WebFileServ.Model.DAL/Migrations/20201124211656_AddPersonalFolder.cs
new file mode 100644
index 0000000..870dd69
--- /dev/null
+++ b/Src/WebFileServ.Model.DAL/Migrations/20201124211656_AddPersonalFolder.cs
@@ -0,0 +1,64 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace WebFileServ.Model.DAL.Migrations
+{
+    public partial class AddPersonalFolder : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<Guid>(
+                name: "OwnerUserId",
+                table: "FsItems",
+                nullable: true);
+
+            migrationBuilder.AddColumn<long>(
+                name: "PersonalDirectoryId",
+                table: "AspNetUsers",
+                nullable: true);
+
+            migrationBuilder.CreateIndex(
+                name: "IX_FsItems_OwnerUserId",
+                table: "FsItems",
+                column: "OwnerUserId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUsers_PersonalDirectoryId",
+                table: "AspNetUsers",
+                column: "PersonalDirectoryId",
+                unique: true,
+                filter: "[PersonalDirectoryId] IS NOT NULL");
+
+            migrationBuilder.AddForeignKey(
+                name: "FK_AspNetUsers_FsItems_PersonalDirectoryId",
+                table: "AspNetUsers",
+                column: "PersonalDirectoryId",
+                principalTable: "FsItems",
+                principalColumn: "Id",
+                onDelete: ReferentialAction.Restrict);
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropForeignKey(
+                name: "FK_AspNetUsers_FsItems_PersonalDirectoryId",
+                table: "AspNetUsers");
+
+            migrationBuilder.DropIndex(
+                name: "IX_FsItems_OwnerUserId",
+                table: "FsItems");
+
+            migrationBuilder.DropIndex(
+                name: "IX_AspNetUsers_PersonalDirectoryId",
+                table: "AspNetUsers");
+
+            migrationBuilder.DropColumn(
+                name: "OwnerUserId",
+                table: "FsItems");
+
+            migrationBuilder.DropColumn(
+                name: "PersonalDirectoryId",
+                table: "AspNetUsers");
+        }
+    }
+}
diff --git a/Src/WebFileServ.Model.DAL/Migrations/20201124211656_AddPersonalFolder.Designer.cs b/Src/WebFileServ.Model.DAL/Migrations/20201124211656_AddPersonalFolder.Designer.cs
new file mode 100644
index 0000000..e81efe5
--- /dev/null
+++ b/Src/WebFileServ.Model.DAL/Migrations/20201124211656_AddPersonalFolder.Designer.cs
@@ -0,0 +1,449 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using WebFileServ.Model.DAL.DataBase.EF;
+
+namespace WebFileServ.Model.DAL.Migrations
+{
+    [DbContext(typeof(ApplicationDbContext))]
+    [Migration("20201124211656_AddPersonalFolder")]
+    partial class AddPersonalFolder
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "3.1.9")
+                .HasAnnotation("Relational:MaxIdentifierLength", 128)
+                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+            modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
+                {
+                    b.Property<string>("UserCode")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<string>("ClientId")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<DateTime>("CreationTime")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("Data")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)")
+                        .HasMaxLength(50000);
+
+                    b.Property<string>("DeviceCode")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<DateTime?>("Expiration")
+                        .IsRequired()
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("SubjectId")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.HasKey("UserCode");
+
+                    b.HasIndex("DeviceCode")
+                        .IsUnique();
+
+                    b.HasIndex("Expiration");
+
+                    b.ToTable("DeviceCodes");
+                });
+
+            modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
+                {
+                    b.Property<string>("Key")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<string>("ClientId")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<DateTime>("CreationTime")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("Data")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)")
+                        .HasMaxLength(50000);
+
+                    b.Property<DateTime?>("Expiration")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("SubjectId")
+                        .HasColumnType("nvarchar(200)")
+                        .HasMaxLength(200);
+
+                    b.Property<string>("Type")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(50)")
+                        .HasMaxLength(50);
+
+                    b.HasKey("Key");
+
+                    b.HasIndex("Expiration");
+
+                    b.HasIndex("SubjectId", "ClientId", "Type");
+
+                    b.ToTable("PersistedGrants");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<Guid>("RoleId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetRoleClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("ProviderKey")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("LoginProvider", "ProviderKey");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserLogins");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+                {
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<string>("LoginProvider")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("Name")
+                        .HasColumnType("nvarchar(128)")
+                        .HasMaxLength(128);
+
+                    b.Property<string>("Value")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.HasKey("UserId", "LoginProvider", "Name");
+
+                    b.ToTable("AspNetUserTokens");
+                });
+
+            modelBuilder.Entity("Tools.Identity.EF.Entities.BaseUserRole<System.Guid, WebFileServ.Model.Entities.Identity.ApplicationUser, WebFileServ.Model.Entities.Identity.ApplicationRole>", b =>
+                {
+                    b.Property<Guid>("UserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<Guid>("RoleId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasKey("UserId", "RoleId");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetUserRoles");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItem", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("Discriminator")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FsItems");
+
+                    b.HasDiscriminator<string>("Discriminator").HasValue("FsItem");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItemGroupPermission", b =>
+                {
+                    b.Property<Guid>("RoleId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<long>("RootDirectoryId")
+                        .HasColumnType("bigint");
+
+                    b.Property<int>("Permission")
+                        .HasColumnType("int");
+
+                    b.HasKey("RoleId", "RootDirectoryId");
+
+                    b.HasIndex("RootDirectoryId");
+
+                    b.ToTable("FsItemGroupPermissions");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.Identity.ApplicationRole", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("Name")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("NormalizedName")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasName("RoleNameIndex")
+                        .HasFilter("[NormalizedName] IS NOT NULL");
+
+                    b.ToTable("AspNetRoles");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.Identity.ApplicationUser", b =>
+                {
+                    b.Property<Guid>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("int");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("Email")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("bit");
+
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("bit");
+
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("datetimeoffset");
+
+                    b.Property<string>("NormalizedEmail")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("NormalizedUserName")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<long?>("PersonalDirectoryId")
+                        .HasColumnType("bigint");
+
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("bit");
+
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("bit");
+
+                    b.Property<string>("UserName")
+                        .HasColumnType("nvarchar(256)")
+                        .HasMaxLength(256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedEmail")
+                        .HasName("EmailIndex");
+
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasName("UserNameIndex")
+                        .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+                    b.HasIndex("PersonalDirectoryId")
+                        .IsUnique()
+                        .HasFilter("[PersonalDirectoryId] IS NOT NULL");
+
+                    b.ToTable("AspNetUsers");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_Directory", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.FsItem");
+
+                    b.HasDiscriminator().HasValue("Fs_Directory");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_File", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.FsItem");
+
+                    b.HasDiscriminator().HasValue("Fs_File");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_RootDirectory", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.Fs_Directory");
+
+                    b.Property<Guid?>("OwnerUserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasIndex("OwnerUserId");
+
+                    b.HasDiscriminator().HasValue("Fs_RootDirectory");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("Tools.Identity.EF.Entities.BaseUserRole<System.Guid, WebFileServ.Model.Entities.Identity.ApplicationUser, WebFileServ.Model.Entities.Identity.ApplicationRole>", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", "Role")
+                        .WithMany("Users")
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationUser", "User")
+                        .WithMany("Roles")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItemGroupPermission", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", "Role")
+                        .WithMany("RootDirectoryPermission")
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("WebFileServ.Model.Entities.FS.Fs_RootDirectory", "RootDirectory")
+                        .WithMany("GroupPermission")
+                        .HasForeignKey("RootDirectoryId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.Identity.ApplicationUser", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.FS.Fs_RootDirectory", "PersonalDirectory")
+                        .WithOne("OwnerUser")
+                        .HasForeignKey("WebFileServ.Model.Entities.Identity.ApplicationUser", "PersonalDirectoryId");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/Src/WebFileServ.Model.DAL/Migrations/ApplicationDbContextModelSnapshot.cs b/Src/WebFileServ.Model.DAL/Migrations/ApplicationDbContextModelSnapshot.cs
index 89353d1..d24caf3 100644
--- a/Src/WebFileServ.Model.DAL/Migrations/ApplicationDbContextModelSnapshot.cs
+++ b/Src/WebFileServ.Model.DAL/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -206,6 +206,42 @@ namespace WebFileServ.Model.DAL.Migrations
                     b.ToTable("AspNetUserRoles");
                 });
 
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItem", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("Discriminator")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FsItems");
+
+                    b.HasDiscriminator<string>("Discriminator").HasValue("FsItem");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItemGroupPermission", b =>
+                {
+                    b.Property<Guid>("RoleId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.Property<long>("RootDirectoryId")
+                        .HasColumnType("bigint");
+
+                    b.Property<int>("Permission")
+                        .HasColumnType("int");
+
+                    b.HasKey("RoleId", "RootDirectoryId");
+
+                    b.HasIndex("RootDirectoryId");
+
+                    b.ToTable("FsItemGroupPermissions");
+                });
+
             modelBuilder.Entity("WebFileServ.Model.Entities.Identity.ApplicationRole", b =>
                 {
                     b.Property<Guid>("Id")
@@ -271,6 +307,9 @@ namespace WebFileServ.Model.DAL.Migrations
                     b.Property<string>("PasswordHash")
                         .HasColumnType("nvarchar(max)");
 
+                    b.Property<long?>("PersonalDirectoryId")
+                        .HasColumnType("bigint");
+
                     b.Property<string>("PhoneNumber")
                         .HasColumnType("nvarchar(max)");
 
@@ -297,9 +336,39 @@ namespace WebFileServ.Model.DAL.Migrations
                         .HasName("UserNameIndex")
                         .HasFilter("[NormalizedUserName] IS NOT NULL");
 
+                    b.HasIndex("PersonalDirectoryId")
+                        .IsUnique()
+                        .HasFilter("[PersonalDirectoryId] IS NOT NULL");
+
                     b.ToTable("AspNetUsers");
                 });
 
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_Directory", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.FsItem");
+
+                    b.HasDiscriminator().HasValue("Fs_Directory");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_File", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.FsItem");
+
+                    b.HasDiscriminator().HasValue("Fs_File");
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.Fs_RootDirectory", b =>
+                {
+                    b.HasBaseType("WebFileServ.Model.Entities.FS.Fs_Directory");
+
+                    b.Property<Guid?>("OwnerUserId")
+                        .HasColumnType("uniqueidentifier");
+
+                    b.HasIndex("OwnerUserId");
+
+                    b.HasDiscriminator().HasValue("Fs_RootDirectory");
+                });
+
             modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
                 {
                     b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", null)
@@ -350,6 +419,28 @@ namespace WebFileServ.Model.DAL.Migrations
                         .OnDelete(DeleteBehavior.Cascade)
                         .IsRequired();
                 });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.FS.FsItemGroupPermission", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.Identity.ApplicationRole", "Role")
+                        .WithMany("RootDirectoryPermission")
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("WebFileServ.Model.Entities.FS.Fs_RootDirectory", "RootDirectory")
+                        .WithMany("GroupPermission")
+                        .HasForeignKey("RootDirectoryId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("WebFileServ.Model.Entities.Identity.ApplicationUser", b =>
+                {
+                    b.HasOne("WebFileServ.Model.Entities.FS.Fs_RootDirectory", "PersonalDirectory")
+                        .WithOne("OwnerUser")
+                        .HasForeignKey("WebFileServ.Model.Entities.Identity.ApplicationUser", "PersonalDirectoryId");
+                });
 #pragma warning restore 612, 618
         }
     }
diff --git a/Src/WebFileServ.Model.DAL/WebFileServ.Model.DAL.csproj b/Src/WebFileServ.Model.DAL/WebFileServ.Model.DAL.csproj
index 7e248e8..00b2b6b 100644
--- a/Src/WebFileServ.Model.DAL/WebFileServ.Model.DAL.csproj
+++ b/Src/WebFileServ.Model.DAL/WebFileServ.Model.DAL.csproj
@@ -5,6 +5,17 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <Compile Remove="Migrations\20201124202202_AddFs.cs" />
+    <Compile Remove="Migrations\20201124202202_AddFs.Designer.cs" />
+    <Compile Remove="Migrations\20201124211244_AddPersonalFolder.cs" />
+    <Compile Remove="Migrations\20201124211244_AddPersonalFolder.Designer.cs" />
+    <Compile Remove="Migrations\20201124211352_AddPersonalFolder.cs" />
+    <Compile Remove="Migrations\20201124211352_AddPersonalFolder.Designer.cs" />
+    <Compile Remove="Migrations\20201124211553_AddPersonalFolder.cs" />
+    <Compile Remove="Migrations\20201124211553_AddPersonalFolder.Designer.cs" />
+  </ItemGroup>
+
+  <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
     <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.9" />
     <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.9" />
@@ -20,8 +31,4 @@
     <ProjectReference Include="..\WebFileServ.Model.Entities\WebFileServ.Model.Entities.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="Migrations\" />
-  </ItemGroup>
-
 </Project>
diff --git a/Src/WebFileServ.Model.Entities/FS/FsItem.cs b/Src/WebFileServ.Model.Entities/FS/FsItem.cs
new file mode 100644
index 0000000..e9cc9af
--- /dev/null
+++ b/Src/WebFileServ.Model.Entities/FS/FsItem.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using System.ComponentModel.DataAnnotations.Schema;
+
+using WebFileServ.Model.Entities.Identity;
+
+namespace WebFileServ.Model.Entities.FS
+{
+    public class FsItem
+    {
+        public long Id { set; get; }    
+    }
+
+
+    public class Fs_File
+        : FsItem
+    {
+    }
+
+
+    public class Fs_RootDirectory 
+        : Fs_Directory
+    {
+
+        [NotMapped]
+        public bool IsPersonalDirectory 
+            => OwnerUserId.HasValue;
+
+        public Guid? OwnerUserId { set; get; }
+        public virtual ApplicationUser OwnerUser { set; get; }
+
+
+        public virtual List<FsItemGroupPermission> GroupPermission { set; get; }
+            = new List<FsItemGroupPermission>();
+    }
+
+    public class Fs_Directory
+        : FsItem
+    { 
+    
+    }
+
+}
diff --git a/Src/WebFileServ.Model.Entities/FS/FsItemGroupPermission.cs b/Src/WebFileServ.Model.Entities/FS/FsItemGroupPermission.cs
new file mode 100644
index 0000000..de5aaea
--- /dev/null
+++ b/Src/WebFileServ.Model.Entities/FS/FsItemGroupPermission.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using WebFileServ.Model.Entities.Identity;
+
+namespace WebFileServ.Model.Entities.FS
+{
+    public enum EnumPermission 
+    {
+        No = 1,
+        Read = 2,
+        ReadWrite = 3
+    }
+
+    public class FsItemGroupPermission
+    {
+
+        public long RootDirectoryId { set; get; }
+        public virtual Fs_RootDirectory RootDirectory { set; get; }
+
+
+        public Guid RoleId { set; get; }
+        public virtual ApplicationRole Role { set; get; }
+
+
+        public EnumPermission Permission { set; get; }
+            = EnumPermission.No;
+
+    }
+}
diff --git a/Src/WebFileServ.Model.Entities/Identity/ApplicationRole.cs b/Src/WebFileServ.Model.Entities/Identity/ApplicationRole.cs
index 0bcf276..18d95fb 100644
--- a/Src/WebFileServ.Model.Entities/Identity/ApplicationRole.cs
+++ b/Src/WebFileServ.Model.Entities/Identity/ApplicationRole.cs
@@ -5,6 +5,8 @@ using System.Threading.Tasks;
 
 using Tools.Identity.EF.Entities;
 
+using WebFileServ.Model.Entities.FS;
+
 namespace WebFileServ.Model.Entities.Identity
 {
     public class ApplicationRole
@@ -14,6 +16,9 @@ namespace WebFileServ.Model.Entities.Identity
             ApplicationRole
             >
     {
+        public virtual List<FsItemGroupPermission> RootDirectoryPermission { set; get; }
+            = new List<FsItemGroupPermission>();
+
 
         public ApplicationRole() 
         { }
diff --git a/Src/WebFileServ.Model.Entities/Identity/ApplicationUser.cs b/Src/WebFileServ.Model.Entities/Identity/ApplicationUser.cs
index 719216f..990e5e5 100644
--- a/Src/WebFileServ.Model.Entities/Identity/ApplicationUser.cs
+++ b/Src/WebFileServ.Model.Entities/Identity/ApplicationUser.cs
@@ -5,6 +5,8 @@ using System.Threading.Tasks;
 
 using Tools.Identity.EF.Entities;
 
+using WebFileServ.Model.Entities.FS;
+
 namespace WebFileServ.Model.Entities.Identity
 {
     public class ApplicationUser 
@@ -13,7 +15,10 @@ namespace WebFileServ.Model.Entities.Identity
             ApplicationUser, 
             ApplicationRole
             >
-    {        
+    {
+
+        public long? PersonalDirectoryId { set; get; }
+        public virtual Fs_RootDirectory PersonalDirectory { set; get; }
     }
 
 }