diff --git a/src/Ombi.Api.Plex/IPlexApi.cs b/src/Ombi.Api.Plex/IPlexApi.cs index 0c7bbe11f..50026bcb5 100644 --- a/src/Ombi.Api.Plex/IPlexApi.cs +++ b/src/Ombi.Api.Plex/IPlexApi.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Ombi.Api.Plex.Models; +using Ombi.Api.Plex.Models.Friends; using Ombi.Api.Plex.Models.Server; using Ombi.Api.Plex.Models.Status; @@ -16,5 +17,6 @@ namespace Ombi.Api.Plex Task GetMetadata(string authToken, string plexFullHost, int itemId); Task GetSeasons(string authToken, string plexFullHost, int ratingKey); Task GetAllEpisodes(string authToken, string host, string section, int start, int retCount); + Task GetUsers(string authToken); } } \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/Friends/PlexFriends.cs b/src/Ombi.Api.Plex/Models/Friends/PlexFriends.cs new file mode 100644 index 000000000..e38eca6f6 --- /dev/null +++ b/src/Ombi.Api.Plex/Models/Friends/PlexFriends.cs @@ -0,0 +1,59 @@ +using System.Xml.Serialization; + +namespace Ombi.Api.Plex.Models.Friends +{ + [XmlRoot(ElementName = "Server")] + public class Server + { + [XmlAttribute(AttributeName = "id")] + public string Id { get; set; } + [XmlAttribute(AttributeName = "serverId")] + public string ServerId { get; set; } + [XmlAttribute(AttributeName = "machineIdentifier")] + public string MachineIdentifier { get; set; } + [XmlAttribute(AttributeName = "name")] + public string Name { get; set; } + [XmlAttribute(AttributeName = "lastSeenAt")] + public string LastSeenAt { get; set; } + [XmlAttribute(AttributeName = "numLibraries")] + public string NumLibraries { get; set; } + [XmlAttribute(AttributeName = "owned")] + public string Owned { get; set; } + } + + [XmlRoot(ElementName = "User")] + public class UserFriends + { + [XmlElement(ElementName = "Server")] + public Server Server { get; set; } + [XmlAttribute(AttributeName = "id")] + public string Id { get; set; } + [XmlAttribute(AttributeName = "title")] + public string Title { get; set; } + [XmlAttribute(AttributeName = "username")] + public string Username { get; set; } + [XmlAttribute(AttributeName = "email")] + public string Email { get; set; } + [XmlAttribute(AttributeName = "recommendationsPlaylistId")] + public string RecommendationsPlaylistId { get; set; } + [XmlAttribute(AttributeName = "thumb")] + public string Thumb { get; set; } + } + + [XmlRoot(ElementName = "MediaContainer")] + public class PlexFriends + { + [XmlElement(ElementName = "User")] + public UserFriends[] User { get; set; } + [XmlAttribute(AttributeName = "friendlyName")] + public string FriendlyName { get; set; } + [XmlAttribute(AttributeName = "identifier")] + public string Identifier { get; set; } + [XmlAttribute(AttributeName = "machineIdentifier")] + public string MachineIdentifier { get; set; } + [XmlAttribute(AttributeName = "totalSize")] + public string TotalSize { get; set; } + [XmlAttribute(AttributeName = "size")] + public string Size { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Plex/PlexApi.cs b/src/Ombi.Api.Plex/PlexApi.cs index 2609a51f7..86dc31329 100644 --- a/src/Ombi.Api.Plex/PlexApi.cs +++ b/src/Ombi.Api.Plex/PlexApi.cs @@ -1,6 +1,7 @@ using System.Net.Http; using System.Threading.Tasks; using Ombi.Api.Plex.Models; +using Ombi.Api.Plex.Models.Friends; using Ombi.Api.Plex.Models.Server; using Ombi.Api.Plex.Models.Status; @@ -126,6 +127,20 @@ namespace Ombi.Api.Plex return await Api.Request(request); } + /// + /// Retuns all the Plex users for this account + /// NOTE: For HOME USERS. There is no username or email, the user's home name is under the title property + /// + /// + /// + public async Task GetUsers(string authToken) + { + var request = new Request(string.Empty,FriendsUri, HttpMethod.Get, ContentType.Xml); + AddHeaders(request, authToken); + + return await Api.Request(request); + } + /// /// Adds the required headers and also the authorization header /// diff --git a/src/Ombi.Helpers/LoggingEvents.cs b/src/Ombi.Helpers/LoggingEvents.cs index 657ac1a37..5a3947b3a 100644 --- a/src/Ombi.Helpers/LoggingEvents.cs +++ b/src/Ombi.Helpers/LoggingEvents.cs @@ -13,6 +13,7 @@ namespace Ombi.Helpers public static EventId RadarrCacher => new EventId(2001); public static EventId PlexEpisodeCacher => new EventId(2001); public static EventId EmbyContentCacher => new EventId(2002); + public static EventId PlexUserImporter => new EventId(2003); public static EventId MovieSender => new EventId(3000); diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs new file mode 100644 index 000000000..0dfaf58a1 --- /dev/null +++ b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs @@ -0,0 +1,85 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Ombi.Api.Plex; +using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; +using Ombi.Helpers; +using Ombi.Store.Entities; + +namespace Ombi.Schedule.Jobs.Plex +{ + public class PlexUserImporter + { + public PlexUserImporter(IPlexApi api, UserManager um, ILogger log, + ISettingsService plexSettings) + { + _api = api; + _userManager = um; + _log = log; + _plexSettings = plexSettings; + } + + private readonly IPlexApi _api; + private readonly UserManager _userManager; + private readonly ILogger _log; + private readonly ISettingsService _plexSettings; + + + public async Task Start() + { + var settings = await _plexSettings.GetSettingsAsync(); + if (!settings.Enable) + { + return; + } + var allUsers = await _userManager.Users.Where(x => x.UserType == UserType.PlexUser).ToListAsync(); + foreach (var server in settings.Servers) + { + if (string.IsNullOrEmpty(server.PlexAuthToken)) + { + continue; + } + + var users = await _api.GetUsers(server.PlexAuthToken); + + foreach (var plexUsers in users.User) + { + // Check if this Plex User already exists + // We are using the Plex USERNAME and Not the TITLE, the Title is for HOME USERS + var existingPlexUser = allUsers.FirstOrDefault(x => x.ProviderUserId == plexUsers.Id); + if (existingPlexUser == null) + { + // Create this users + // We do not store a password against the user since they will authenticate via Plex + var newUser = new OmbiUser + { + UserType = UserType.PlexUser, + UserName = plexUsers.Username, + ProviderUserId = plexUsers.Id, + Email = plexUsers.Email, + Alias = string.Empty + }; + var result = await _userManager.CreateAsync(newUser); + if (!result.Succeeded) + { + foreach (var identityError in result.Errors) + { + _log.LogError(LoggingEvents.PlexUserImporter, identityError.Description); + } + continue; + } + // TODO Set default permissions/roles + + } + else + { + // Do we need to update this user? + } + } + } + } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Entities/OmbiUser.cs b/src/Ombi.Store/Entities/OmbiUser.cs index 668e04bcf..24353ecfc 100644 --- a/src/Ombi.Store/Entities/OmbiUser.cs +++ b/src/Ombi.Store/Entities/OmbiUser.cs @@ -7,6 +7,10 @@ namespace Ombi.Store.Entities { public string Alias { get; set; } public UserType UserType { get; set; } + /// + /// This will be the unique Plex/Emby user id reference + /// + public string ProviderUserId { get; set; } [NotMapped] public string UserAlias => string.IsNullOrEmpty(Alias) ? UserName : Alias; diff --git a/src/Ombi.Store/Migrations/20170901230032_Inital.Designer.cs b/src/Ombi.Store/Migrations/20170914122422_Inital.Designer.cs similarity index 86% rename from src/Ombi.Store/Migrations/20170901230032_Inital.Designer.cs rename to src/Ombi.Store/Migrations/20170914122422_Inital.Designer.cs index 4e85bd89b..2d3dcf123 100644 --- a/src/Ombi.Store/Migrations/20170901230032_Inital.Designer.cs +++ b/src/Ombi.Store/Migrations/20170914122422_Inital.Designer.cs @@ -1,24 +1,28 @@ -using System; +// using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Entities; -using Ombi.Helpers; +using System; namespace Ombi.Store.Migrations { [DbContext(typeof(OmbiContext))] - [Migration("20170901230032_Inital")] + [Migration("20170914122422_Inital")] partial class Inital { protected override void BuildTargetModel(ModelBuilder modelBuilder) { +#pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "1.1.2"); + .HasAnnotation("ProductVersion", "2.0.0-rtm-26452"); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") .ValueGeneratedOnAdd(); @@ -41,7 +45,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetRoles"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.Property("Id") .ValueGeneratedOnAdd(); @@ -60,7 +64,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetRoleClaims"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") .ValueGeneratedOnAdd(); @@ -79,7 +83,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetUserClaims"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider"); @@ -97,7 +101,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetUserLogins"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.Property("UserId"); @@ -110,7 +114,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetUserRoles"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.Property("UserId"); @@ -166,7 +170,8 @@ namespace Ombi.Store.Migrations b.Property("AddedAt"); - b.Property("EmbyId"); + b.Property("EmbyId") + .IsRequired(); b.Property("ProviderId"); @@ -179,6 +184,32 @@ namespace Ombi.Store.Migrations b.ToTable("EmbyContent"); }); + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId"); + + b.Property("EpisodeNumber"); + + b.Property("ParentId"); + + b.Property("ProviderId"); + + b.Property("SeasonNumber"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b => { b.Property("Id") @@ -246,6 +277,8 @@ namespace Ombi.Store.Migrations b.Property("PhoneNumberConfirmed"); + b.Property("ProviderUserId"); + b.Property("SecurityStamp"); b.Property("TwoFactorEnabled"); @@ -555,43 +588,59 @@ namespace Ombi.Store.Migrations b.ToTable("SeasonRequests"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { - b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") - .WithMany("Claims") + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() .HasForeignKey("RoleId") .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("Ombi.Store.Entities.OmbiUser") - .WithMany("Claims") + .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.HasOne("Ombi.Store.Entities.OmbiUser") - .WithMany("Logins") + .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { - b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") - .WithMany("Users") + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() .HasForeignKey("RoleId") .OnDelete(DeleteBehavior.Cascade); b.HasOne("Ombi.Store.Entities.OmbiUser") - .WithMany("Roles") + .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade); }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + }); + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => { b.HasOne("Ombi.Store.Entities.PlexContent", "Series") @@ -674,6 +723,7 @@ namespace Ombi.Store.Migrations .HasForeignKey("ChildRequestId") .OnDelete(DeleteBehavior.Cascade); }); +#pragma warning restore 612, 618 } } } diff --git a/src/Ombi.Store/Migrations/20170901230032_Inital.cs b/src/Ombi.Store/Migrations/20170914122422_Inital.cs similarity index 57% rename from src/Ombi.Store/Migrations/20170901230032_Inital.cs rename to src/Ombi.Store/Migrations/20170914122422_Inital.cs index f71430088..e8d1b0968 100644 --- a/src/Ombi.Store/Migrations/20170901230032_Inital.cs +++ b/src/Ombi.Store/Migrations/20170914122422_Inital.cs @@ -1,6 +1,6 @@ -using System; +using Microsoft.EntityFrameworkCore.Migrations; +using System; using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; namespace Ombi.Store.Migrations { @@ -8,59 +8,73 @@ namespace Ombi.Store.Migrations { protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.CreateTable( - name: "AspNetRoles", - columns: table => new - { - Id = table.Column(nullable: false), - ConcurrencyStamp = table.Column(nullable: true), - Name = table.Column(maxLength: 256, nullable: true), - NormalizedName = table.Column(maxLength: 256, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserTokens", - 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_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); - }); - migrationBuilder.CreateTable( name: "ApplicationConfiguration", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Type = table.Column(nullable: false), - Value = table.Column(nullable: true) + Type = table.Column(type: "INTEGER", nullable: false), + Value = table.Column(type: "TEXT", nullable: true) }, constraints: table => { table.PrimaryKey("PK_ApplicationConfiguration", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + ConcurrencyStamp = table.Column(type: "TEXT", nullable: true), + Name = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "TEXT", maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + AccessFailedCount = table.Column(type: "INTEGER", nullable: false), + Alias = table.Column(type: "TEXT", nullable: true), + ConcurrencyStamp = table.Column(type: "TEXT", nullable: true), + Email = table.Column(type: "TEXT", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "INTEGER", nullable: false), + LockoutEnabled = table.Column(type: "INTEGER", nullable: false), + LockoutEnd = table.Column(type: "TEXT", nullable: true), + NormalizedEmail = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + PasswordHash = table.Column(type: "TEXT", nullable: true), + PhoneNumber = table.Column(type: "TEXT", nullable: true), + PhoneNumberConfirmed = table.Column(type: "INTEGER", nullable: false), + ProviderUserId = table.Column(type: "TEXT", nullable: true), + SecurityStamp = table.Column(type: "TEXT", nullable: true), + TwoFactorEnabled = table.Column(type: "INTEGER", nullable: false), + UserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + UserType = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Audit", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - AuditArea = table.Column(nullable: false), - AuditType = table.Column(nullable: false), - DateTime = table.Column(nullable: false), - Description = table.Column(nullable: true), - User = table.Column(nullable: true) + AuditArea = table.Column(type: "INTEGER", nullable: false), + AuditType = table.Column(type: "INTEGER", nullable: false), + DateTime = table.Column(type: "TEXT", nullable: false), + Description = table.Column(type: "TEXT", nullable: true), + User = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -71,27 +85,28 @@ namespace Ombi.Store.Migrations name: "EmbyContent", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - AddedAt = table.Column(nullable: false), - EmbyId = table.Column(nullable: true), - ProviderId = table.Column(nullable: true), - Title = table.Column(nullable: true), - Type = table.Column(nullable: false) + AddedAt = table.Column(type: "TEXT", nullable: false), + EmbyId = table.Column(type: "TEXT", nullable: false), + ProviderId = table.Column(type: "TEXT", nullable: true), + Title = table.Column(type: "TEXT", nullable: true), + Type = table.Column(type: "INTEGER", nullable: false) }, constraints: table => { table.PrimaryKey("PK_EmbyContent", x => x.Id); + table.UniqueConstraint("AK_EmbyContent_EmbyId", x => x.EmbyId); }); migrationBuilder.CreateTable( name: "GlobalSettings", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Content = table.Column(nullable: true), - SettingsName = table.Column(nullable: true) + Content = table.Column(type: "TEXT", nullable: true), + SettingsName = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -102,60 +117,33 @@ namespace Ombi.Store.Migrations name: "NotificationTemplates", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Agent = table.Column(nullable: false), - Enabled = table.Column(nullable: false), - Message = table.Column(nullable: true), - NotificationType = table.Column(nullable: false), - Subject = table.Column(nullable: true) + Agent = table.Column(type: "INTEGER", nullable: false), + Enabled = table.Column(type: "INTEGER", nullable: false), + Message = table.Column(type: "TEXT", nullable: true), + NotificationType = table.Column(type: "INTEGER", nullable: false), + Subject = table.Column(type: "TEXT", nullable: true) }, constraints: table => { table.PrimaryKey("PK_NotificationTemplates", x => x.Id); }); - migrationBuilder.CreateTable( - name: "AspNetUsers", - columns: table => new - { - Id = table.Column(nullable: false), - AccessFailedCount = table.Column(nullable: false), - Alias = table.Column(nullable: true), - ConcurrencyStamp = table.Column(nullable: true), - Email = table.Column(maxLength: 256, nullable: true), - EmailConfirmed = table.Column(nullable: false), - LockoutEnabled = table.Column(nullable: false), - LockoutEnd = table.Column(nullable: true), - NormalizedEmail = table.Column(maxLength: 256, nullable: true), - NormalizedUserName = table.Column(maxLength: 256, nullable: true), - PasswordHash = table.Column(nullable: true), - PhoneNumber = table.Column(nullable: true), - PhoneNumberConfirmed = table.Column(nullable: false), - SecurityStamp = table.Column(nullable: true), - TwoFactorEnabled = table.Column(nullable: false), - UserName = table.Column(maxLength: 256, nullable: true), - UserType = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUsers", x => x.Id); - }); - migrationBuilder.CreateTable( name: "PlexContent", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - AddedAt = table.Column(nullable: false), - Key = table.Column(nullable: false), - ProviderId = table.Column(nullable: true), - Quality = table.Column(nullable: true), - ReleaseYear = table.Column(nullable: true), - Title = table.Column(nullable: true), - Type = table.Column(nullable: false), - Url = table.Column(nullable: true) + AddedAt = table.Column(type: "TEXT", nullable: false), + Key = table.Column(type: "INTEGER", nullable: false), + ProviderId = table.Column(type: "TEXT", nullable: true), + Quality = table.Column(type: "TEXT", nullable: true), + ReleaseYear = table.Column(type: "TEXT", nullable: true), + Title = table.Column(type: "TEXT", nullable: true), + Type = table.Column(type: "INTEGER", nullable: false), + Url = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -167,9 +155,9 @@ namespace Ombi.Store.Migrations name: "RadarrCache", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - TheMovieDbId = table.Column(nullable: false) + TheMovieDbId = table.Column(type: "INTEGER", nullable: false) }, constraints: table => { @@ -180,16 +168,16 @@ namespace Ombi.Store.Migrations name: "TvRequests", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - ImdbId = table.Column(nullable: true), - Overview = table.Column(nullable: true), - PosterPath = table.Column(nullable: true), - ReleaseDate = table.Column(nullable: false), - RootFolder = table.Column(nullable: true), - Status = table.Column(nullable: true), - Title = table.Column(nullable: true), - TvDbId = table.Column(nullable: false) + ImdbId = table.Column(type: "TEXT", nullable: true), + Overview = table.Column(type: "TEXT", nullable: true), + PosterPath = table.Column(type: "TEXT", nullable: true), + ReleaseDate = table.Column(type: "TEXT", nullable: false), + RootFolder = table.Column(type: "INTEGER", nullable: true), + Status = table.Column(type: "TEXT", nullable: true), + Title = table.Column(type: "TEXT", nullable: true), + TvDbId = table.Column(type: "INTEGER", nullable: false) }, constraints: table => { @@ -200,11 +188,11 @@ namespace Ombi.Store.Migrations name: "AspNetRoleClaims", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - ClaimType = table.Column(nullable: true), - ClaimValue = table.Column(nullable: true), - RoleId = table.Column(nullable: false) + ClaimType = table.Column(type: "TEXT", nullable: true), + ClaimValue = table.Column(type: "TEXT", nullable: true), + RoleId = table.Column(type: "TEXT", nullable: false) }, constraints: table => { @@ -221,11 +209,11 @@ namespace Ombi.Store.Migrations name: "AspNetUserClaims", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - ClaimType = table.Column(nullable: true), - ClaimValue = table.Column(nullable: true), - UserId = table.Column(nullable: false) + ClaimType = table.Column(type: "TEXT", nullable: true), + ClaimValue = table.Column(type: "TEXT", nullable: true), + UserId = table.Column(type: "TEXT", nullable: false) }, constraints: table => { @@ -242,10 +230,10 @@ namespace Ombi.Store.Migrations name: "AspNetUserLogins", columns: table => new { - LoginProvider = table.Column(nullable: false), - ProviderKey = table.Column(nullable: false), - ProviderDisplayName = table.Column(nullable: true), - UserId = table.Column(nullable: false) + LoginProvider = table.Column(type: "TEXT", nullable: false), + ProviderKey = table.Column(type: "TEXT", nullable: false), + ProviderDisplayName = table.Column(type: "TEXT", nullable: true), + UserId = table.Column(type: "TEXT", nullable: false) }, constraints: table => { @@ -262,8 +250,8 @@ namespace Ombi.Store.Migrations name: "AspNetUserRoles", columns: table => new { - UserId = table.Column(nullable: false), - RoleId = table.Column(nullable: false) + UserId = table.Column(type: "TEXT", nullable: false), + RoleId = table.Column(type: "TEXT", nullable: false) }, constraints: table => { @@ -282,27 +270,47 @@ namespace Ombi.Store.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "TEXT", nullable: false), + LoginProvider = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: false), + Value = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "MovieRequests", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Approved = table.Column(nullable: false), - Available = table.Column(nullable: false), - Denied = table.Column(nullable: true), - DeniedReason = table.Column(nullable: true), - ImdbId = table.Column(nullable: true), - IssueId = table.Column(nullable: true), - Overview = table.Column(nullable: true), - PosterPath = table.Column(nullable: true), - ReleaseDate = table.Column(nullable: false), - RequestType = table.Column(nullable: false), - RequestedDate = table.Column(nullable: false), - RequestedUserId = table.Column(nullable: true), - Status = table.Column(nullable: true), - TheMovieDbId = table.Column(nullable: false), - Title = table.Column(nullable: true) + Approved = table.Column(type: "INTEGER", nullable: false), + Available = table.Column(type: "INTEGER", nullable: false), + Denied = table.Column(type: "INTEGER", nullable: true), + DeniedReason = table.Column(type: "TEXT", nullable: true), + ImdbId = table.Column(type: "TEXT", nullable: true), + IssueId = table.Column(type: "INTEGER", nullable: true), + Overview = table.Column(type: "TEXT", nullable: true), + PosterPath = table.Column(type: "TEXT", nullable: true), + ReleaseDate = table.Column(type: "TEXT", nullable: false), + RequestType = table.Column(type: "INTEGER", nullable: false), + RequestedDate = table.Column(type: "TEXT", nullable: false), + RequestedUserId = table.Column(type: "TEXT", nullable: true), + Status = table.Column(type: "TEXT", nullable: true), + TheMovieDbId = table.Column(type: "INTEGER", nullable: false), + Title = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -319,10 +327,10 @@ namespace Ombi.Store.Migrations name: "Tokens", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Token = table.Column(nullable: true), - UserId = table.Column(nullable: true) + Token = table.Column(type: "TEXT", nullable: true), + UserId = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -335,18 +343,43 @@ namespace Ombi.Store.Migrations onDelete: ReferentialAction.Restrict); }); + migrationBuilder.CreateTable( + name: "EmbyEpisode", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + AddedAt = table.Column(type: "TEXT", nullable: false), + EmbyId = table.Column(type: "TEXT", nullable: true), + EpisodeNumber = table.Column(type: "INTEGER", nullable: false), + ParentId = table.Column(type: "TEXT", nullable: true), + ProviderId = table.Column(type: "TEXT", nullable: true), + SeasonNumber = table.Column(type: "INTEGER", nullable: false), + Title = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EmbyEpisode", x => x.Id); + table.ForeignKey( + name: "FK_EmbyEpisode_EmbyContent_ParentId", + column: x => x.ParentId, + principalTable: "EmbyContent", + principalColumn: "EmbyId", + onDelete: ReferentialAction.Restrict); + }); + migrationBuilder.CreateTable( name: "PlexEpisode", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - EpisodeNumber = table.Column(nullable: false), - GrandparentKey = table.Column(nullable: false), - Key = table.Column(nullable: false), - ParentKey = table.Column(nullable: false), - SeasonNumber = table.Column(nullable: false), - Title = table.Column(nullable: true) + EpisodeNumber = table.Column(type: "INTEGER", nullable: false), + GrandparentKey = table.Column(type: "INTEGER", nullable: false), + Key = table.Column(type: "INTEGER", nullable: false), + ParentKey = table.Column(type: "INTEGER", nullable: false), + SeasonNumber = table.Column(type: "INTEGER", nullable: false), + Title = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -363,12 +396,12 @@ namespace Ombi.Store.Migrations name: "PlexSeasonsContent", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - ParentKey = table.Column(nullable: false), - PlexContentId = table.Column(nullable: false), - SeasonKey = table.Column(nullable: false), - SeasonNumber = table.Column(nullable: false) + ParentKey = table.Column(type: "INTEGER", nullable: false), + PlexContentId = table.Column(type: "INTEGER", nullable: false), + SeasonKey = table.Column(type: "INTEGER", nullable: false), + SeasonNumber = table.Column(type: "INTEGER", nullable: false) }, constraints: table => { @@ -385,18 +418,18 @@ namespace Ombi.Store.Migrations name: "ChildRequests", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Approved = table.Column(nullable: false), - Available = table.Column(nullable: false), - Denied = table.Column(nullable: true), - DeniedReason = table.Column(nullable: true), - IssueId = table.Column(nullable: true), - ParentRequestId = table.Column(nullable: false), - RequestType = table.Column(nullable: false), - RequestedDate = table.Column(nullable: false), - RequestedUserId = table.Column(nullable: true), - Title = table.Column(nullable: true) + Approved = table.Column(type: "INTEGER", nullable: false), + Available = table.Column(type: "INTEGER", nullable: false), + Denied = table.Column(type: "INTEGER", nullable: true), + DeniedReason = table.Column(type: "TEXT", nullable: true), + IssueId = table.Column(type: "INTEGER", nullable: true), + ParentRequestId = table.Column(type: "INTEGER", nullable: false), + RequestType = table.Column(type: "INTEGER", nullable: false), + RequestedDate = table.Column(type: "TEXT", nullable: false), + RequestedUserId = table.Column(type: "TEXT", nullable: true), + Title = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -419,12 +452,12 @@ namespace Ombi.Store.Migrations name: "MovieIssues", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Description = table.Column(nullable: true), - IssueId = table.Column(nullable: true), - MovieId = table.Column(nullable: false), - Subect = table.Column(nullable: true) + Description = table.Column(type: "TEXT", nullable: true), + IssueId = table.Column(type: "INTEGER", nullable: true), + MovieId = table.Column(type: "INTEGER", nullable: false), + Subect = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -443,16 +476,36 @@ namespace Ombi.Store.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "SeasonRequests", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ChildRequestId = table.Column(type: "INTEGER", nullable: false), + SeasonNumber = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SeasonRequests", x => x.Id); + table.ForeignKey( + name: "FK_SeasonRequests_ChildRequests_ChildRequestId", + column: x => x.ChildRequestId, + principalTable: "ChildRequests", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "TvIssues", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - Description = table.Column(nullable: true), - IssueId = table.Column(nullable: true), - Subect = table.Column(nullable: true), - TvId = table.Column(nullable: false) + Description = table.Column(type: "TEXT", nullable: true), + IssueId = table.Column(type: "INTEGER", nullable: true), + Subect = table.Column(type: "TEXT", nullable: true), + TvId = table.Column(type: "INTEGER", nullable: false) }, constraints: table => { @@ -471,40 +524,20 @@ namespace Ombi.Store.Migrations onDelete: ReferentialAction.Cascade); }); - migrationBuilder.CreateTable( - name: "SeasonRequests", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Sqlite:Autoincrement", true), - ChildRequestId = table.Column(nullable: false), - SeasonNumber = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_SeasonRequests", x => x.Id); - table.ForeignKey( - name: "FK_SeasonRequests_ChildRequests_ChildRequestId", - column: x => x.ChildRequestId, - principalTable: "ChildRequests", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - migrationBuilder.CreateTable( name: "EpisodeRequests", columns: table => new { - Id = table.Column(nullable: false) + Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), - AirDate = table.Column(nullable: false), - Approved = table.Column(nullable: false), - Available = table.Column(nullable: false), - EpisodeNumber = table.Column(nullable: false), - Requested = table.Column(nullable: false), - SeasonId = table.Column(nullable: false), - Title = table.Column(nullable: true), - Url = table.Column(nullable: true) + AirDate = table.Column(type: "TEXT", nullable: false), + Approved = table.Column(type: "INTEGER", nullable: false), + Available = table.Column(type: "INTEGER", nullable: false), + EpisodeNumber = table.Column(type: "INTEGER", nullable: false), + Requested = table.Column(type: "INTEGER", nullable: false), + SeasonId = table.Column(type: "INTEGER", nullable: false), + Title = table.Column(type: "TEXT", nullable: true), + Url = table.Column(type: "TEXT", nullable: true) }, constraints: table => { @@ -517,17 +550,17 @@ namespace Ombi.Store.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + migrationBuilder.CreateIndex( name: "RoleNameIndex", table: "AspNetRoles", column: "NormalizedName", unique: true); - migrationBuilder.CreateIndex( - name: "IX_AspNetRoleClaims_RoleId", - table: "AspNetRoleClaims", - column: "RoleId"); - migrationBuilder.CreateIndex( name: "IX_AspNetUserClaims_UserId", table: "AspNetUserClaims", @@ -554,16 +587,6 @@ namespace Ombi.Store.Migrations column: "NormalizedUserName", unique: true); - migrationBuilder.CreateIndex( - name: "IX_PlexEpisode_GrandparentKey", - table: "PlexEpisode", - column: "GrandparentKey"); - - migrationBuilder.CreateIndex( - name: "IX_PlexSeasonsContent_PlexContentId", - table: "PlexSeasonsContent", - column: "PlexContentId"); - migrationBuilder.CreateIndex( name: "IX_ChildRequests_ParentRequestId", table: "ChildRequests", @@ -574,6 +597,16 @@ namespace Ombi.Store.Migrations table: "ChildRequests", column: "RequestedUserId"); + migrationBuilder.CreateIndex( + name: "IX_EmbyEpisode_ParentId", + table: "EmbyEpisode", + column: "ParentId"); + + migrationBuilder.CreateIndex( + name: "IX_EpisodeRequests_SeasonId", + table: "EpisodeRequests", + column: "SeasonId"); + migrationBuilder.CreateIndex( name: "IX_MovieIssues_IssueId", table: "MovieIssues", @@ -589,6 +622,26 @@ namespace Ombi.Store.Migrations table: "MovieRequests", column: "RequestedUserId"); + migrationBuilder.CreateIndex( + name: "IX_PlexEpisode_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey"); + + migrationBuilder.CreateIndex( + name: "IX_PlexSeasonsContent_PlexContentId", + table: "PlexSeasonsContent", + column: "PlexContentId"); + + migrationBuilder.CreateIndex( + name: "IX_SeasonRequests_ChildRequestId", + table: "SeasonRequests", + column: "ChildRequestId"); + + migrationBuilder.CreateIndex( + name: "IX_Tokens_UserId", + table: "Tokens", + column: "UserId"); + migrationBuilder.CreateIndex( name: "IX_TvIssues_IssueId", table: "TvIssues", @@ -598,25 +651,13 @@ namespace Ombi.Store.Migrations name: "IX_TvIssues_TvId", table: "TvIssues", column: "TvId"); - - migrationBuilder.CreateIndex( - name: "IX_Tokens_UserId", - table: "Tokens", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_EpisodeRequests_SeasonId", - table: "EpisodeRequests", - column: "SeasonId"); - - migrationBuilder.CreateIndex( - name: "IX_SeasonRequests_ChildRequestId", - table: "SeasonRequests", - column: "ChildRequestId"); } protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "ApplicationConfiguration"); + migrationBuilder.DropTable( name: "AspNetRoleClaims"); @@ -632,18 +673,21 @@ namespace Ombi.Store.Migrations migrationBuilder.DropTable( name: "AspNetUserTokens"); - migrationBuilder.DropTable( - name: "ApplicationConfiguration"); - migrationBuilder.DropTable( name: "Audit"); migrationBuilder.DropTable( - name: "EmbyContent"); + name: "EmbyEpisode"); + + migrationBuilder.DropTable( + name: "EpisodeRequests"); migrationBuilder.DropTable( name: "GlobalSettings"); + migrationBuilder.DropTable( + name: "MovieIssues"); + migrationBuilder.DropTable( name: "NotificationTemplates"); @@ -657,28 +701,25 @@ namespace Ombi.Store.Migrations name: "RadarrCache"); migrationBuilder.DropTable( - name: "MovieIssues"); + name: "Tokens"); migrationBuilder.DropTable( name: "TvIssues"); - migrationBuilder.DropTable( - name: "Tokens"); - - migrationBuilder.DropTable( - name: "EpisodeRequests"); - migrationBuilder.DropTable( name: "AspNetRoles"); migrationBuilder.DropTable( - name: "PlexContent"); + name: "EmbyContent"); + + migrationBuilder.DropTable( + name: "SeasonRequests"); migrationBuilder.DropTable( name: "MovieRequests"); migrationBuilder.DropTable( - name: "SeasonRequests"); + name: "PlexContent"); migrationBuilder.DropTable( name: "ChildRequests"); diff --git a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs index 31386ec62..9c913fa59 100644 --- a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs @@ -1,11 +1,14 @@ -using System; +// using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Entities; -using Ombi.Helpers; +using System; namespace Ombi.Store.Migrations { @@ -14,10 +17,11 @@ namespace Ombi.Store.Migrations { protected override void BuildModel(ModelBuilder modelBuilder) { +#pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "1.1.2"); + .HasAnnotation("ProductVersion", "2.0.0-rtm-26452"); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") .ValueGeneratedOnAdd(); @@ -40,7 +44,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetRoles"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.Property("Id") .ValueGeneratedOnAdd(); @@ -59,7 +63,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetRoleClaims"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") .ValueGeneratedOnAdd(); @@ -78,7 +82,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetUserClaims"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider"); @@ -96,7 +100,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetUserLogins"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.Property("UserId"); @@ -109,7 +113,7 @@ namespace Ombi.Store.Migrations b.ToTable("AspNetUserRoles"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.Property("UserId"); @@ -165,7 +169,8 @@ namespace Ombi.Store.Migrations b.Property("AddedAt"); - b.Property("EmbyId"); + b.Property("EmbyId") + .IsRequired(); b.Property("ProviderId"); @@ -178,6 +183,32 @@ namespace Ombi.Store.Migrations b.ToTable("EmbyContent"); }); + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId"); + + b.Property("EpisodeNumber"); + + b.Property("ParentId"); + + b.Property("ProviderId"); + + b.Property("SeasonNumber"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b => { b.Property("Id") @@ -245,6 +276,8 @@ namespace Ombi.Store.Migrations b.Property("PhoneNumberConfirmed"); + b.Property("ProviderUserId"); + b.Property("SecurityStamp"); b.Property("TwoFactorEnabled"); @@ -554,43 +587,59 @@ namespace Ombi.Store.Migrations b.ToTable("SeasonRequests"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { - b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") - .WithMany("Claims") + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() .HasForeignKey("RoleId") .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("Ombi.Store.Entities.OmbiUser") - .WithMany("Claims") + .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.HasOne("Ombi.Store.Entities.OmbiUser") - .WithMany("Logins") + .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { - b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole") - .WithMany("Users") + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() .HasForeignKey("RoleId") .OnDelete(DeleteBehavior.Cascade); b.HasOne("Ombi.Store.Entities.OmbiUser") - .WithMany("Roles") + .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade); }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + }); + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => { b.HasOne("Ombi.Store.Entities.PlexContent", "Series") @@ -673,6 +722,7 @@ namespace Ombi.Store.Migrations .HasForeignKey("ChildRequestId") .OnDelete(DeleteBehavior.Cascade); }); +#pragma warning restore 612, 618 } } } diff --git a/src/Ombi.Store/Migrations/OmbiMigrations.bat b/src/Ombi.Store/Migrations/OmbiMigrations.bat deleted file mode 100644 index 47da72ea4..000000000 --- a/src/Ombi.Store/Migrations/OmbiMigrations.bat +++ /dev/null @@ -1 +0,0 @@ -dotnet ef migrations add Inital --context OmbiContext --startup-project ../Ombi/Ombi.csproj \ No newline at end of file diff --git a/src/Ombi.Store/Migrations/OmbiMigrations.ps1 b/src/Ombi.Store/Migrations/OmbiMigrations.ps1 new file mode 100644 index 000000000..9914917a4 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMigrations.ps1 @@ -0,0 +1,2 @@ +cd .. +dotnet ef migrations add Inital --context OmbiContext --startup-project ../Ombi/Ombi.csproj \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/login/login.component.html b/src/Ombi/ClientApp/app/login/login.component.html index 736331a87..38500883d 100644 --- a/src/Ombi/ClientApp/app/login/login.component.html +++ b/src/Ombi/ClientApp/app/login/login.component.html @@ -17,6 +17,11 @@ include the remember me checkbox +
+
+ Remember Me +
+
diff --git a/src/Ombi/ClientApp/app/login/login.component.ts b/src/Ombi/ClientApp/app/login/login.component.ts index ef703a0b0..cae2e18b7 100644 --- a/src/Ombi/ClientApp/app/login/login.component.ts +++ b/src/Ombi/ClientApp/app/login/login.component.ts @@ -24,7 +24,8 @@ export class LoginComponent implements OnInit { private route: ActivatedRoute) { this.form = this.fb.group({ username: ["", [Validators.required]], - password: ["", [Validators.required]] + password: ["", [Validators.required]], + rememberMe: [false] }); this.status.getWizardStatus().subscribe(x => { diff --git a/src/Ombi/ClientApp/app/settings/settings.module.ts b/src/Ombi/ClientApp/app/settings/settings.module.ts index 1320bc6c3..d03822c9b 100644 --- a/src/Ombi/ClientApp/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/app/settings/settings.module.ts @@ -19,6 +19,7 @@ import { SonarrComponent } from './sonarr/sonarr.component'; import { RadarrComponent } from './radarr/radarr.component'; import { LandingPageComponent } from './landingpage/landingpage.component'; import { CustomizationComponent } from './customization/customization.component'; +import { UserManagementComponent } from './usermanagement/usermanagement.component'; import { EmailNotificationComponent } from './notifications/emailnotification.component'; import { DiscordComponent } from './notifications/discord.component'; import { SlackComponent } from './notifications/slack.component'; @@ -46,6 +47,7 @@ const routes: Routes = [ { path: 'Settings/Pushover', component: PushoverComponent, canActivate: [AuthGuard] }, { path: 'Settings/Pushbullet', component: PushbulletComponent, canActivate: [AuthGuard] }, { path: 'Settings/Mattermost', component: MattermostComponent, canActivate: [AuthGuard] }, + { path: 'Settings/UserManagement', component: UserManagementComponent, canActivate: [AuthGuard] }, ]; @NgModule({ @@ -80,7 +82,8 @@ const routes: Routes = [ NotificationTemplate, PushoverComponent, MattermostComponent, - PushbulletComponent + PushbulletComponent, + UserManagementComponent, ], exports: [ RouterModule diff --git a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html index 34e3d52fd..644688c43 100644 --- a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html @@ -1,11 +1,20 @@