From 30da20a456e9915df56b888b5a469eaa645008d3 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 8 Mar 2020 23:11:52 +0100 Subject: [PATCH] A basic account system exists now --- Kyoo.Common/Models/Account.cs | 9 + Kyoo/Models/DatabaseContext.cs | 6 +- ...r.cs => 20200307160105_Intial.Designer.cs} | 152 ++++++------- ...47_Initial.cs => 20200307160105_Intial.cs} | 206 +++++++++--------- .../Internal/DatabaseContextModelSnapshot.cs | 148 ++++++------- Kyoo/Models/IdentityContext.cs | 10 +- Kyoo/Models/{Account.cs => User.cs} | 2 +- Kyoo/Startup.cs | 23 +- Kyoo/Views/API/AccountAPI.cs | 44 +++- Kyoo/Views/WebClient | 2 +- 10 files changed, 322 insertions(+), 280 deletions(-) create mode 100644 Kyoo.Common/Models/Account.cs rename Kyoo/Models/DatabaseMigrations/Internal/{20200307014347_Initial.Designer.cs => 20200307160105_Intial.Designer.cs} (98%) rename Kyoo/Models/DatabaseMigrations/Internal/{20200307014347_Initial.cs => 20200307160105_Intial.cs} (97%) rename Kyoo/Models/{Account.cs => User.cs} (92%) diff --git a/Kyoo.Common/Models/Account.cs b/Kyoo.Common/Models/Account.cs new file mode 100644 index 00000000..a3f51c61 --- /dev/null +++ b/Kyoo.Common/Models/Account.cs @@ -0,0 +1,9 @@ +namespace Kyoo.Models +{ + public class Account + { + public string Username { get; set; } + public string Email { get; set; } + public string Picture { get; set; } + } +} \ No newline at end of file diff --git a/Kyoo/Models/DatabaseContext.cs b/Kyoo/Models/DatabaseContext.cs index 3330c04e..f5842102 100644 --- a/Kyoo/Models/DatabaseContext.cs +++ b/Kyoo/Models/DatabaseContext.cs @@ -9,11 +9,11 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Kyoo { - public class DatabaseContext : IdentityDbContext + public class DatabaseContext : IdentityDbContext { public DatabaseContext(DbContextOptions options) : base(options) { } - public DbSet Accounts { get; set; } + public DbSet Accounts { get; set; } public DbSet Libraries { get; set; } public DbSet Collections { get; set; } @@ -66,7 +66,7 @@ namespace Kyoo modelBuilder.Entity() .Ignore(x => x.Genres); - modelBuilder.Entity().ToTable("Account"); + modelBuilder.Entity().ToTable("User"); modelBuilder.Entity>().ToTable("UserRole"); modelBuilder.Entity>().ToTable("UserLogin"); modelBuilder.Entity>().ToTable("UserClaim"); diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200307160105_Intial.Designer.cs similarity index 98% rename from Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.Designer.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20200307160105_Intial.Designer.cs index d78f0deb..2edbf076 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.Designer.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200307160105_Intial.Designer.cs @@ -9,8 +9,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Kyoo.Models.DatabaseMigrations.Internal { [DbContext(typeof(DatabaseContext))] - [Migration("20200307014347_Initial")] - partial class Initial + [Migration("20200307160105_Intial")] + partial class Intial { protected override void BuildTargetModel(ModelBuilder modelBuilder) { @@ -18,76 +18,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder .HasAnnotation("ProductVersion", "3.1.2"); - modelBuilder.Entity("Kyoo.Models.Account", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("AccessFailedCount") - .HasColumnType("INTEGER"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Email") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("EmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnabled") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnd") - .HasColumnType("TEXT"); - - b.Property("NormalizedEmail") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("NormalizedUserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("OTAC") - .HasColumnType("TEXT"); - - b.Property("OTACExpires") - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("INTEGER"); - - b.Property("SecurityStamp") - .HasColumnType("TEXT"); - - b.Property("TwoFactorEnabled") - .HasColumnType("INTEGER"); - - b.Property("UserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasName("UserNameIndex"); - - b.ToTable("Account"); - }); - modelBuilder.Entity("Kyoo.Models.Collection", b => { b.Property("ID") @@ -465,6 +395,76 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("Tracks"); }); + modelBuilder.Entity("Kyoo.Models.User", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("OTAC") + .HasColumnType("TEXT"); + + b.Property("OTACExpires") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("User"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") @@ -700,7 +700,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -709,7 +709,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -724,7 +724,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -733,7 +733,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200307160105_Intial.cs similarity index 97% rename from Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.cs rename to Kyoo/Models/DatabaseMigrations/Internal/20200307160105_Intial.cs index 9e4b2f5c..e662a5dd 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200307160105_Intial.cs @@ -3,37 +3,10 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace Kyoo.Models.DatabaseMigrations.Internal { - public partial class Initial : Migration + public partial class Intial : Migration { protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.CreateTable( - name: "Account", - columns: table => new - { - Id = table.Column(nullable: false), - UserName = table.Column(maxLength: 256, nullable: true), - NormalizedUserName = table.Column(maxLength: 256, nullable: true), - Email = table.Column(maxLength: 256, nullable: true), - NormalizedEmail = table.Column(maxLength: 256, nullable: true), - EmailConfirmed = table.Column(nullable: false), - PasswordHash = table.Column(nullable: true), - SecurityStamp = table.Column(nullable: true), - ConcurrencyStamp = table.Column(nullable: true), - PhoneNumber = table.Column(nullable: true), - PhoneNumberConfirmed = table.Column(nullable: false), - TwoFactorEnabled = table.Column(nullable: false), - LockoutEnd = table.Column(nullable: true), - LockoutEnabled = table.Column(nullable: false), - AccessFailedCount = table.Column(nullable: false), - OTAC = table.Column(nullable: true), - OTACExpires = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Account", x => x.Id); - }); - migrationBuilder.CreateTable( name: "Collections", columns: table => new @@ -109,6 +82,33 @@ namespace Kyoo.Models.DatabaseMigrations.Internal table.PrimaryKey("PK_Studios", x => x.ID); }); + migrationBuilder.CreateTable( + name: "User", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false), + OTAC = table.Column(nullable: true), + OTACExpires = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_User", x => x.Id); + }); + migrationBuilder.CreateTable( name: "UserRoles", columns: table => new @@ -123,67 +123,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal table.PrimaryKey("PK_UserRoles", x => x.Id); }); - migrationBuilder.CreateTable( - name: "UserClaim", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Sqlite:Autoincrement", true), - UserId = table.Column(nullable: false), - ClaimType = table.Column(nullable: true), - ClaimValue = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_UserClaim", x => x.Id); - table.ForeignKey( - name: "FK_UserClaim_Account_UserId", - column: x => x.UserId, - principalTable: "Account", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "UserLogin", - columns: table => new - { - LoginProvider = table.Column(nullable: false), - ProviderKey = table.Column(nullable: false), - ProviderDisplayName = table.Column(nullable: true), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_UserLogin", x => new { x.LoginProvider, x.ProviderKey }); - table.ForeignKey( - name: "FK_UserLogin_Account_UserId", - column: x => x.UserId, - principalTable: "Account", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "UserToken", - columns: table => new - { - UserId = table.Column(nullable: false), - LoginProvider = table.Column(nullable: false), - Name = table.Column(nullable: false), - Value = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_UserToken", x => new { x.UserId, x.LoginProvider, x.Name }); - table.ForeignKey( - name: "FK_UserToken_Account_UserId", - column: x => x.UserId, - principalTable: "Account", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - migrationBuilder.CreateTable( name: "Shows", columns: table => new @@ -218,6 +157,67 @@ namespace Kyoo.Models.DatabaseMigrations.Internal onDelete: ReferentialAction.Restrict); }); + migrationBuilder.CreateTable( + name: "UserClaim", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaim", x => x.Id); + table.ForeignKey( + name: "FK_UserClaim_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogin", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogin", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogin_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserToken", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserToken", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserToken_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "UserRole", columns: table => new @@ -235,9 +235,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal principalColumn: "Id", onDelete: ReferentialAction.Cascade); table.ForeignKey( - name: "FK_UserRole_Account_UserId", + name: "FK_UserRole_User_UserId", column: x => x.UserId, - principalTable: "Account", + principalTable: "User", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); @@ -462,17 +462,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal onDelete: ReferentialAction.Cascade); }); - migrationBuilder.CreateIndex( - name: "EmailIndex", - table: "Account", - column: "NormalizedEmail"); - - migrationBuilder.CreateIndex( - name: "UserNameIndex", - table: "Account", - column: "NormalizedUserName", - unique: true); - migrationBuilder.CreateIndex( name: "IX_CollectionLinks_CollectionID", table: "CollectionLinks", @@ -538,6 +527,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal table: "Tracks", column: "EpisodeID"); + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "User", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "User", + column: "NormalizedUserName", + unique: true); + migrationBuilder.CreateIndex( name: "IX_UserClaim_UserId", table: "UserClaim", @@ -616,7 +616,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal name: "UserRoles"); migrationBuilder.DropTable( - name: "Account"); + name: "User"); migrationBuilder.DropTable( name: "Seasons"); diff --git a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs index eb976610..10d770c7 100644 --- a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs +++ b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs @@ -16,76 +16,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder .HasAnnotation("ProductVersion", "3.1.2"); - modelBuilder.Entity("Kyoo.Models.Account", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("AccessFailedCount") - .HasColumnType("INTEGER"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Email") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("EmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnabled") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnd") - .HasColumnType("TEXT"); - - b.Property("NormalizedEmail") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("NormalizedUserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("OTAC") - .HasColumnType("TEXT"); - - b.Property("OTACExpires") - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("INTEGER"); - - b.Property("SecurityStamp") - .HasColumnType("TEXT"); - - b.Property("TwoFactorEnabled") - .HasColumnType("INTEGER"); - - b.Property("UserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasName("UserNameIndex"); - - b.ToTable("Account"); - }); - modelBuilder.Entity("Kyoo.Models.Collection", b => { b.Property("ID") @@ -463,6 +393,76 @@ namespace Kyoo.Models.DatabaseMigrations.Internal b.ToTable("Tracks"); }); + modelBuilder.Entity("Kyoo.Models.User", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("OTAC") + .HasColumnType("TEXT"); + + b.Property("OTACExpires") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("User"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") @@ -698,7 +698,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -707,7 +707,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -722,7 +722,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -731,7 +731,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.HasOne("Kyoo.Models.Account", null) + b.HasOne("Kyoo.Models.User", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) diff --git a/Kyoo/Models/IdentityContext.cs b/Kyoo/Models/IdentityContext.cs index 0728b102..ba3700a2 100644 --- a/Kyoo/Models/IdentityContext.cs +++ b/Kyoo/Models/IdentityContext.cs @@ -22,11 +22,13 @@ namespace Kyoo new Client { ClientId = "kyoo.webapp", - ClientSecrets = { new Secret("secret".Sha256()) }, - AllowedGrantTypes = GrantTypes.Implicit, + AllowedGrantTypes = GrantTypes.Code, + AllowOfflineAccess = true, + RequireClientSecret = false, + RequireConsent = false, AllowedScopes = { "kyoo.admin", "kyoo.write", "kyoo.read", "openid", "profile" }, - AllowAccessTokensViaBrowser = true, - RequireConsent = false + RedirectUris = { "/logged", "/silent" }, + PostLogoutRedirectUris = { "/logout" } } }; } diff --git a/Kyoo/Models/Account.cs b/Kyoo/Models/User.cs similarity index 92% rename from Kyoo/Models/Account.cs rename to Kyoo/Models/User.cs index b0424ee1..2a65d409 100644 --- a/Kyoo/Models/Account.cs +++ b/Kyoo/Models/User.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Identity; namespace Kyoo.Models { - public class Account : IdentityUser + public class User : IdentityUser { public string OTAC { get; set; } public DateTime? OTACExpires { get; set; } diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index 724a2f86..4a0a4a10 100644 --- a/Kyoo/Startup.cs +++ b/Kyoo/Startup.cs @@ -39,28 +39,34 @@ namespace Kyoo services.AddDbContext(options => options.UseLazyLoadingProxies() .UseSqlite(Configuration.GetConnectionString("Database"))); - services.AddIdentity() + services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); - + services.AddIdentityServer(options => { - options.UserInteraction.LoginUrl = publicUrl + "/login"; - options.UserInteraction.ErrorUrl = publicUrl + "/error"; - options.UserInteraction.LogoutUrl = publicUrl + "/logout"; + options.UserInteraction.LoginUrl = publicUrl + "login"; + options.UserInteraction.ErrorUrl = publicUrl + "error"; + options.UserInteraction.LogoutUrl = publicUrl + "logout"; }) .AddConfigurationStore(options => { - options.ConfigureDbContext = builder => builder.UseSqlite(Configuration.GetConnectionString("Database"), sql => sql.MigrationsAssembly(assemblyName)); + options.ConfigureDbContext = builder => + builder.UseSqlite(Configuration.GetConnectionString("Database"), + sql => sql.MigrationsAssembly(assemblyName)); }) .AddOperationalStore(options => { - options.ConfigureDbContext = builder => builder.UseSqlite(Configuration.GetConnectionString("Database"), sql => sql.MigrationsAssembly(assemblyName)); + options.ConfigureDbContext = builder => + builder.UseSqlite(Configuration.GetConnectionString("Database"), + sql => sql.MigrationsAssembly(assemblyName)); options.EnableTokenCleanup = true; }) .AddInMemoryIdentityResources(IdentityContext.GetIdentityResources()) .AddInMemoryApiResources(IdentityContext.GetApis()) - .AddAspNetIdentity(); + .AddAspNetIdentity() + .AddDeveloperSigningCredential(); + services.AddScoped(); services.AddScoped(); @@ -105,6 +111,7 @@ namespace Kyoo app.UseRouting(); app.UseIdentityServer(); + app.UseAuthorization(); app.UseEndpoints(endpoints => { diff --git a/Kyoo/Views/API/AccountAPI.cs b/Kyoo/Views/API/AccountAPI.cs index 616f14dd..8ed91d92 100644 --- a/Kyoo/Views/API/AccountAPI.cs +++ b/Kyoo/Views/API/AccountAPI.cs @@ -1,6 +1,9 @@ using System; using System.Threading.Tasks; +using IdentityServer4.Services; using Kyoo.Models; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using SignInResult = Microsoft.AspNetCore.Identity.SignInResult; @@ -25,12 +28,12 @@ namespace Kyoo.Api [ApiController] public class AccountController : Controller { - private readonly UserManager _accountManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; - public AccountController(UserManager accountManager, SignInManager siginInManager) + public AccountController(UserManager userManager, SignInManager siginInManager) { - _accountManager = accountManager; + _userManager = userManager; _signInManager = siginInManager; } @@ -39,12 +42,12 @@ namespace Kyoo.Api { if (!ModelState.IsValid) return BadRequest(user); - Account account = new Account {UserName = user.Username, Email = user.Email}; - IdentityResult result = await _accountManager.CreateAsync(account, user.Password); + User account = new User {UserName = user.Username, Email = user.Email}; + IdentityResult result = await _userManager.CreateAsync(account, user.Password); if (!result.Succeeded) return BadRequest(result.Errors); string otac = account.GenerateOTAC(TimeSpan.FromMinutes(1)); - await _accountManager.UpdateAsync(account); + await _userManager.UpdateAsync(account); return Ok(otac); } @@ -54,9 +57,30 @@ namespace Kyoo.Api if (!ModelState.IsValid) return BadRequest(login); SignInResult result = await _signInManager.PasswordSignInAsync(login.Username, login.Password, login.StayLoggedIn, false); - if (result.Succeeded) - return Ok(); - return BadRequest("Invalid username/password"); + if (!result.Succeeded) + return BadRequest("Invalid username/password"); + return Ok(); + } + + [HttpGet] + [Authorize] + public async Task> Index() + { + User account = await _userManager.GetUserAsync(HttpContext.User); + return new Account{ + Username = account.UserName, + Email = account.Email, + Picture = "api/account/picture/" + account.UserName + }; + } + + [HttpGet("picture/{username}")] + public IActionResult Picture(string username) + { + string path = $"account/{username}.png"; + if (System.IO.File.Exists(path)) + return new PhysicalFileResult(path, "image"); + return NotFound(); } } } \ No newline at end of file diff --git a/Kyoo/Views/WebClient b/Kyoo/Views/WebClient index 6240bbce..34f828af 160000 --- a/Kyoo/Views/WebClient +++ b/Kyoo/Views/WebClient @@ -1 +1 @@ -Subproject commit 6240bbce05be87f576fd4326ce26e8bfa8335c73 +Subproject commit 34f828af246b0c86c53f612bd7999a4c2b3e266d