A basic account system exists now

This commit is contained in:
Zoe Roux 2020-03-08 23:11:52 +01:00
parent bd12c35073
commit 30da20a456
10 changed files with 322 additions and 280 deletions

View File

@ -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; }
}
}

View File

@ -9,11 +9,11 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo namespace Kyoo
{ {
public class DatabaseContext : IdentityDbContext<Account> public class DatabaseContext : IdentityDbContext<User>
{ {
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { } public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
public DbSet<Account> Accounts { get; set; } public DbSet<User> Accounts { get; set; }
public DbSet<Library> Libraries { get; set; } public DbSet<Library> Libraries { get; set; }
public DbSet<Collection> Collections { get; set; } public DbSet<Collection> Collections { get; set; }
@ -66,7 +66,7 @@ namespace Kyoo
modelBuilder.Entity<Show>() modelBuilder.Entity<Show>()
.Ignore(x => x.Genres); .Ignore(x => x.Genres);
modelBuilder.Entity<Account>().ToTable("Account"); modelBuilder.Entity<User>().ToTable("User");
modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRole"); modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRole");
modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogin"); modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogin");
modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim"); modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim");

View File

@ -9,8 +9,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations.Internal namespace Kyoo.Models.DatabaseMigrations.Internal
{ {
[DbContext(typeof(DatabaseContext))] [DbContext(typeof(DatabaseContext))]
[Migration("20200307014347_Initial")] [Migration("20200307160105_Intial")]
partial class Initial partial class Intial
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
{ {
@ -18,76 +18,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.2"); .HasAnnotation("ProductVersion", "3.1.2");
modelBuilder.Entity("Kyoo.Models.Account", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("OTAC")
.HasColumnType("TEXT");
b.Property<DateTime?>("OTACExpires")
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("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 => modelBuilder.Entity("Kyoo.Models.Collection", b =>
{ {
b.Property<long>("ID") b.Property<long>("ID")
@ -465,6 +395,76 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.ToTable("Tracks"); b.ToTable("Tracks");
}); });
modelBuilder.Entity("Kyoo.Models.User", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("OTAC")
.HasColumnType("TEXT");
b.Property<DateTime?>("OTACExpires")
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("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 => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{ {
b.Property<string>("Id") b.Property<string>("Id")
@ -700,7 +700,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{ {
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
@ -709,7 +709,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{ {
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
@ -724,7 +724,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
@ -733,7 +733,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{ {
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)

View File

@ -3,37 +3,10 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace Kyoo.Models.DatabaseMigrations.Internal namespace Kyoo.Models.DatabaseMigrations.Internal
{ {
public partial class Initial : Migration public partial class Intial : Migration
{ {
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.CreateTable(
name: "Account",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false),
OTAC = table.Column<string>(nullable: true),
OTACExpires = table.Column<DateTime>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Account", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Collections", name: "Collections",
columns: table => new columns: table => new
@ -109,6 +82,33 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
table.PrimaryKey("PK_Studios", x => x.ID); table.PrimaryKey("PK_Studios", x => x.ID);
}); });
migrationBuilder.CreateTable(
name: "User",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false),
OTAC = table.Column<string>(nullable: true),
OTACExpires = table.Column<DateTime>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_User", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "UserRoles", name: "UserRoles",
columns: table => new columns: table => new
@ -123,67 +123,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
table.PrimaryKey("PK_UserRoles", x => x.Id); table.PrimaryKey("PK_UserRoles", x => x.Id);
}); });
migrationBuilder.CreateTable(
name: "UserClaim",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(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<string>(nullable: false),
ProviderKey = table.Column<string>(nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(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<string>(nullable: false),
LoginProvider = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: false),
Value = table.Column<string>(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( migrationBuilder.CreateTable(
name: "Shows", name: "Shows",
columns: table => new columns: table => new
@ -218,6 +157,67 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
onDelete: ReferentialAction.Restrict); onDelete: ReferentialAction.Restrict);
}); });
migrationBuilder.CreateTable(
name: "UserClaim",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(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<string>(nullable: false),
ProviderKey = table.Column<string>(nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(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<string>(nullable: false),
LoginProvider = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: false),
Value = table.Column<string>(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( migrationBuilder.CreateTable(
name: "UserRole", name: "UserRole",
columns: table => new columns: table => new
@ -235,9 +235,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_UserRole_Account_UserId", name: "FK_UserRole_User_UserId",
column: x => x.UserId, column: x => x.UserId,
principalTable: "Account", principalTable: "User",
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
@ -462,17 +462,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "Account",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "Account",
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_CollectionLinks_CollectionID", name: "IX_CollectionLinks_CollectionID",
table: "CollectionLinks", table: "CollectionLinks",
@ -538,6 +527,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
table: "Tracks", table: "Tracks",
column: "EpisodeID"); column: "EpisodeID");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "User",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "User",
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_UserClaim_UserId", name: "IX_UserClaim_UserId",
table: "UserClaim", table: "UserClaim",
@ -616,7 +616,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
name: "UserRoles"); name: "UserRoles");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Account"); name: "User");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Seasons"); name: "Seasons");

View File

@ -16,76 +16,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.2"); .HasAnnotation("ProductVersion", "3.1.2");
modelBuilder.Entity("Kyoo.Models.Account", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("OTAC")
.HasColumnType("TEXT");
b.Property<DateTime?>("OTACExpires")
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("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 => modelBuilder.Entity("Kyoo.Models.Collection", b =>
{ {
b.Property<long>("ID") b.Property<long>("ID")
@ -463,6 +393,76 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.ToTable("Tracks"); b.ToTable("Tracks");
}); });
modelBuilder.Entity("Kyoo.Models.User", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("OTAC")
.HasColumnType("TEXT");
b.Property<DateTime?>("OTACExpires")
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("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 => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{ {
b.Property<string>("Id") b.Property<string>("Id")
@ -698,7 +698,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{ {
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
@ -707,7 +707,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{ {
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
@ -722,7 +722,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
@ -731,7 +731,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{ {
b.HasOne("Kyoo.Models.Account", null) b.HasOne("Kyoo.Models.User", null)
.WithMany() .WithMany()
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)

View File

@ -22,11 +22,13 @@ namespace Kyoo
new Client new Client
{ {
ClientId = "kyoo.webapp", ClientId = "kyoo.webapp",
ClientSecrets = { new Secret("secret".Sha256()) }, AllowedGrantTypes = GrantTypes.Code,
AllowedGrantTypes = GrantTypes.Implicit, AllowOfflineAccess = true,
RequireClientSecret = false,
RequireConsent = false,
AllowedScopes = { "kyoo.admin", "kyoo.write", "kyoo.read", "openid", "profile" }, AllowedScopes = { "kyoo.admin", "kyoo.write", "kyoo.read", "openid", "profile" },
AllowAccessTokensViaBrowser = true, RedirectUris = { "/logged", "/silent" },
RequireConsent = false PostLogoutRedirectUris = { "/logout" }
} }
}; };
} }

View File

@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Identity;
namespace Kyoo.Models namespace Kyoo.Models
{ {
public class Account : IdentityUser public class User : IdentityUser
{ {
public string OTAC { get; set; } public string OTAC { get; set; }
public DateTime? OTACExpires { get; set; } public DateTime? OTACExpires { get; set; }

View File

@ -39,28 +39,34 @@ namespace Kyoo
services.AddDbContext<DatabaseContext>(options => options.UseLazyLoadingProxies() services.AddDbContext<DatabaseContext>(options => options.UseLazyLoadingProxies()
.UseSqlite(Configuration.GetConnectionString("Database"))); .UseSqlite(Configuration.GetConnectionString("Database")));
services.AddIdentity<Account, IdentityRole>() services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<DatabaseContext>() .AddEntityFrameworkStores<DatabaseContext>()
.AddDefaultTokenProviders(); .AddDefaultTokenProviders();
services.AddIdentityServer(options => services.AddIdentityServer(options =>
{ {
options.UserInteraction.LoginUrl = publicUrl + "/login"; options.UserInteraction.LoginUrl = publicUrl + "login";
options.UserInteraction.ErrorUrl = publicUrl + "/error"; options.UserInteraction.ErrorUrl = publicUrl + "error";
options.UserInteraction.LogoutUrl = publicUrl + "/logout"; options.UserInteraction.LogoutUrl = publicUrl + "logout";
}) })
.AddConfigurationStore(options => .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 => .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; options.EnableTokenCleanup = true;
}) })
.AddInMemoryIdentityResources(IdentityContext.GetIdentityResources()) .AddInMemoryIdentityResources(IdentityContext.GetIdentityResources())
.AddInMemoryApiResources(IdentityContext.GetApis()) .AddInMemoryApiResources(IdentityContext.GetApis())
.AddAspNetIdentity<Account>(); .AddAspNetIdentity<User>()
.AddDeveloperSigningCredential();
services.AddScoped<ILibraryManager, LibraryManager>(); services.AddScoped<ILibraryManager, LibraryManager>();
services.AddScoped<ICrawler, Crawler>(); services.AddScoped<ICrawler, Crawler>();
@ -105,6 +111,7 @@ namespace Kyoo
app.UseRouting(); app.UseRouting();
app.UseIdentityServer(); app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints =>
{ {

View File

@ -1,6 +1,9 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using IdentityServer4.Services;
using Kyoo.Models; using Kyoo.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult; using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
@ -25,12 +28,12 @@ namespace Kyoo.Api
[ApiController] [ApiController]
public class AccountController : Controller public class AccountController : Controller
{ {
private readonly UserManager<Account> _accountManager; private readonly UserManager<User> _userManager;
private readonly SignInManager<Account> _signInManager; private readonly SignInManager<User> _signInManager;
public AccountController(UserManager<Account> accountManager, SignInManager<Account> siginInManager) public AccountController(UserManager<User> userManager, SignInManager<User> siginInManager)
{ {
_accountManager = accountManager; _userManager = userManager;
_signInManager = siginInManager; _signInManager = siginInManager;
} }
@ -39,12 +42,12 @@ namespace Kyoo.Api
{ {
if (!ModelState.IsValid) if (!ModelState.IsValid)
return BadRequest(user); return BadRequest(user);
Account account = new Account {UserName = user.Username, Email = user.Email}; User account = new User {UserName = user.Username, Email = user.Email};
IdentityResult result = await _accountManager.CreateAsync(account, user.Password); IdentityResult result = await _userManager.CreateAsync(account, user.Password);
if (!result.Succeeded) if (!result.Succeeded)
return BadRequest(result.Errors); return BadRequest(result.Errors);
string otac = account.GenerateOTAC(TimeSpan.FromMinutes(1)); string otac = account.GenerateOTAC(TimeSpan.FromMinutes(1));
await _accountManager.UpdateAsync(account); await _userManager.UpdateAsync(account);
return Ok(otac); return Ok(otac);
} }
@ -54,9 +57,30 @@ namespace Kyoo.Api
if (!ModelState.IsValid) if (!ModelState.IsValid)
return BadRequest(login); return BadRequest(login);
SignInResult result = await _signInManager.PasswordSignInAsync(login.Username, login.Password, login.StayLoggedIn, false); SignInResult result = await _signInManager.PasswordSignInAsync(login.Username, login.Password, login.StayLoggedIn, false);
if (result.Succeeded) if (!result.Succeeded)
return Ok();
return BadRequest("Invalid username/password"); return BadRequest("Invalid username/password");
return Ok();
}
[HttpGet]
[Authorize]
public async Task<ActionResult<Account>> 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();
} }
} }
} }

@ -1 +1 @@
Subproject commit 6240bbce05be87f576fd4326ce26e8bfa8335c73 Subproject commit 34f828af246b0c86c53f612bd7999a4c2b3e266d