diff --git a/API/Controllers/LibraryController.cs b/API/Controllers/LibraryController.cs index 45d51894f..5ceaf1690 100644 --- a/API/Controllers/LibraryController.cs +++ b/API/Controllers/LibraryController.cs @@ -9,11 +9,13 @@ using API.Entities; using API.Extensions; using API.Interfaces; using AutoMapper; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; namespace API.Controllers { + [Authorize] public class LibraryController : BaseApiController { private readonly DataContext _context; diff --git a/API/Controllers/UsersController.cs b/API/Controllers/UsersController.cs index 71f1677d7..b0ac10ff2 100644 --- a/API/Controllers/UsersController.cs +++ b/API/Controllers/UsersController.cs @@ -7,11 +7,13 @@ using API.DTOs; using API.Entities; using API.Extensions; using API.Interfaces; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; namespace API.Controllers { + [Authorize] public class UsersController : BaseApiController { private readonly DataContext _context; @@ -36,6 +38,8 @@ namespace API.Controllers { //_logger.Log(LogLevel.Debug, "Creating a new " + createLibraryDto.Type + " library"); var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername()); + + if (user == null) return BadRequest("Could not validate user"); if (await _libraryRepository.LibraryExists(createLibraryDto.Name)) @@ -44,26 +48,24 @@ namespace API.Controllers } // TODO: We probably need to clean the folders before we insert - var library = new Library() + var library = new Library { Name = createLibraryDto.Name, Type = createLibraryDto.Type, //Folders = createLibraryDto.Folders + AppUsers = new List() { user } }; - + user.Libraries ??= new List(); // If user is null, then set it + user.Libraries.Add(library); - _userRepository.Update(user); + //_userRepository.Update(user); if (await _userRepository.SaveAllAsync()) { return Ok(); } - - - - return BadRequest("Not implemented"); } } diff --git a/API/DTOs/MemberDto.cs b/API/DTOs/MemberDto.cs index 7c42553a0..26e299a7d 100644 --- a/API/DTOs/MemberDto.cs +++ b/API/DTOs/MemberDto.cs @@ -15,6 +15,6 @@ namespace API.DTOs public DateTime Created { get; set; } public DateTime LastActive { get; set; } public bool IsAdmin { get; set; } - //public IEnumerable Libraries { get; set; } + public IEnumerable Libraries { get; set; } } } \ No newline at end of file diff --git a/API/Data/DataContext.cs b/API/Data/DataContext.cs index f5ed3afbe..92ce19955 100644 --- a/API/Data/DataContext.cs +++ b/API/Data/DataContext.cs @@ -1,4 +1,5 @@ -using API.Entities; +using System; +using API.Entities; using Microsoft.EntityFrameworkCore; namespace API.Data diff --git a/API/Data/Migrations/20201218173135_ManyToManyLibraries.Designer.cs b/API/Data/Migrations/20201218173135_ManyToManyLibraries.Designer.cs new file mode 100644 index 000000000..98af0c730 --- /dev/null +++ b/API/Data/Migrations/20201218173135_ManyToManyLibraries.Designer.cs @@ -0,0 +1,141 @@ +// +using System; +using API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace API.Data.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20201218173135_ManyToManyLibraries")] + partial class ManyToManyLibraries + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.1"); + + modelBuilder.Entity("API.Entities.AppUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("IsAdmin") + .HasColumnType("INTEGER"); + + b.Property("LastActive") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("BLOB"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("API.Entities.FolderPath", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LibraryId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LibraryId"); + + b.ToTable("FolderPath"); + }); + + modelBuilder.Entity("API.Entities.Library", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CoverImage") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Library"); + }); + + modelBuilder.Entity("AppUserLibrary", b => + { + b.Property("AppUsersId") + .HasColumnType("INTEGER"); + + b.Property("LibrariesId") + .HasColumnType("INTEGER"); + + b.HasKey("AppUsersId", "LibrariesId"); + + b.HasIndex("LibrariesId"); + + b.ToTable("AppUserLibrary"); + }); + + modelBuilder.Entity("API.Entities.FolderPath", b => + { + b.HasOne("API.Entities.Library", "Library") + .WithMany("Folders") + .HasForeignKey("LibraryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Library"); + }); + + modelBuilder.Entity("AppUserLibrary", b => + { + b.HasOne("API.Entities.AppUser", null) + .WithMany() + .HasForeignKey("AppUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("API.Entities.Library", null) + .WithMany() + .HasForeignKey("LibrariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("API.Entities.Library", b => + { + b.Navigation("Folders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/API/Data/Migrations/20201218173135_ManyToManyLibraries.cs b/API/Data/Migrations/20201218173135_ManyToManyLibraries.cs new file mode 100644 index 000000000..e7d2cb39b --- /dev/null +++ b/API/Data/Migrations/20201218173135_ManyToManyLibraries.cs @@ -0,0 +1,119 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace API.Data.Migrations +{ + public partial class ManyToManyLibraries : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_FolderPath_Library_LibraryId", + table: "FolderPath"); + + migrationBuilder.DropForeignKey( + name: "FK_Library_Users_AppUserId", + table: "Library"); + + migrationBuilder.DropIndex( + name: "IX_Library_AppUserId", + table: "Library"); + + migrationBuilder.DropColumn( + name: "AppUserId", + table: "Library"); + + migrationBuilder.AlterColumn( + name: "LibraryId", + table: "FolderPath", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.CreateTable( + name: "AppUserLibrary", + columns: table => new + { + AppUsersId = table.Column(type: "INTEGER", nullable: false), + LibrariesId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AppUserLibrary", x => new { x.AppUsersId, x.LibrariesId }); + table.ForeignKey( + name: "FK_AppUserLibrary_Library_LibrariesId", + column: x => x.LibrariesId, + principalTable: "Library", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AppUserLibrary_Users_AppUsersId", + column: x => x.AppUsersId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AppUserLibrary_LibrariesId", + table: "AppUserLibrary", + column: "LibrariesId"); + + migrationBuilder.AddForeignKey( + name: "FK_FolderPath_Library_LibraryId", + table: "FolderPath", + column: "LibraryId", + principalTable: "Library", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_FolderPath_Library_LibraryId", + table: "FolderPath"); + + migrationBuilder.DropTable( + name: "AppUserLibrary"); + + migrationBuilder.AddColumn( + name: "AppUserId", + table: "Library", + type: "INTEGER", + nullable: false, + defaultValue: 0); + + migrationBuilder.AlterColumn( + name: "LibraryId", + table: "FolderPath", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.CreateIndex( + name: "IX_Library_AppUserId", + table: "Library", + column: "AppUserId"); + + migrationBuilder.AddForeignKey( + name: "FK_FolderPath_Library_LibraryId", + table: "FolderPath", + column: "LibraryId", + principalTable: "Library", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Library_Users_AppUserId", + table: "Library", + column: "AppUserId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/API/Data/Migrations/DataContextModelSnapshot.cs b/API/Data/Migrations/DataContextModelSnapshot.cs index b341bb481..c19ace39f 100644 --- a/API/Data/Migrations/DataContextModelSnapshot.cs +++ b/API/Data/Migrations/DataContextModelSnapshot.cs @@ -55,7 +55,7 @@ namespace API.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("LibraryId") + b.Property("LibraryId") .HasColumnType("INTEGER"); b.Property("Path") @@ -74,9 +74,6 @@ namespace API.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("AppUserId") - .HasColumnType("INTEGER"); - b.Property("CoverImage") .HasColumnType("TEXT"); @@ -88,32 +85,48 @@ namespace API.Data.Migrations b.HasKey("Id"); - b.HasIndex("AppUserId"); - b.ToTable("Library"); }); + modelBuilder.Entity("AppUserLibrary", b => + { + b.Property("AppUsersId") + .HasColumnType("INTEGER"); + + b.Property("LibrariesId") + .HasColumnType("INTEGER"); + + b.HasKey("AppUsersId", "LibrariesId"); + + b.HasIndex("LibrariesId"); + + b.ToTable("AppUserLibrary"); + }); + modelBuilder.Entity("API.Entities.FolderPath", b => { - b.HasOne("API.Entities.Library", null) + b.HasOne("API.Entities.Library", "Library") .WithMany("Folders") - .HasForeignKey("LibraryId"); - }); - - modelBuilder.Entity("API.Entities.Library", b => - { - b.HasOne("API.Entities.AppUser", "AppUser") - .WithMany("Libraries") - .HasForeignKey("AppUserId") + .HasForeignKey("LibraryId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("AppUser"); + b.Navigation("Library"); }); - modelBuilder.Entity("API.Entities.AppUser", b => + modelBuilder.Entity("AppUserLibrary", b => { - b.Navigation("Libraries"); + b.HasOne("API.Entities.AppUser", null) + .WithMany() + .HasForeignKey("AppUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("API.Entities.Library", null) + .WithMany() + .HasForeignKey("LibrariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); }); modelBuilder.Entity("API.Entities.Library", b => diff --git a/API/Data/UserRepository.cs b/API/Data/UserRepository.cs index bb69ccaa8..1a8692c97 100644 --- a/API/Data/UserRepository.cs +++ b/API/Data/UserRepository.cs @@ -43,7 +43,8 @@ namespace API.Data public async Task GetUserByUsernameAsync(string username) { - return await _context.Users.SingleOrDefaultAsync(x => x.UserName == username); + return await _context.Users + .SingleOrDefaultAsync(x => x.UserName == username); } public async Task> GetMembersAsync() diff --git a/API/Entities/Library.cs b/API/Entities/Library.cs index 06291ede0..279498210 100644 --- a/API/Entities/Library.cs +++ b/API/Entities/Library.cs @@ -9,8 +9,6 @@ namespace API.Entities public string CoverImage { get; set; } public LibraryType Type { get; set; } public ICollection Folders { get; set; } - - public AppUser AppUser { get; set; } - public int AppUserId { get; set; } + public ICollection AppUsers { get; set; } } } \ No newline at end of file