diff --git a/src/Ombi.Api.Plex/IPlexApi.cs b/src/Ombi.Api.Plex/IPlexApi.cs index 50026bcb5..e11d6d914 100644 --- a/src/Ombi.Api.Plex/IPlexApi.cs +++ b/src/Ombi.Api.Plex/IPlexApi.cs @@ -18,5 +18,6 @@ namespace Ombi.Api.Plex Task GetSeasons(string authToken, string plexFullHost, int ratingKey); Task GetAllEpisodes(string authToken, string host, string section, int start, int retCount); Task GetUsers(string authToken); + Task GetAccount(string authToken); } } \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/User.cs b/src/Ombi.Api.Plex/Models/User.cs index af2025ba9..bf27161f7 100644 --- a/src/Ombi.Api.Plex/Models/User.cs +++ b/src/Ombi.Api.Plex/Models/User.cs @@ -2,13 +2,21 @@ namespace Ombi.Api.Plex.Models { + public class PlexAccount + { + public User user { get; set; } + } + public class User { + public string id { get; set; } public string email { get; set; } public string uuid { get; set; } public string joined_at { get; set; } public string username { get; set; } public string title { get; set; } + public string thumb { get; set; } + public string hasPassword { get; set; } public string authentication_token { get; set; } public Subscription subscription { get; set; } public Roles roles { get; set; } diff --git a/src/Ombi.Api.Plex/PlexApi.cs b/src/Ombi.Api.Plex/PlexApi.cs index 86dc31329..f06a7e465 100644 --- a/src/Ombi.Api.Plex/PlexApi.cs +++ b/src/Ombi.Api.Plex/PlexApi.cs @@ -18,7 +18,7 @@ namespace Ombi.Api.Plex private const string SignInUri = "https://plex.tv/users/sign_in.json"; private const string FriendsUri = "https://plex.tv/pms/friends/all"; - private const string GetAccountUri = "https://plex.tv/users/account"; + private const string GetAccountUri = "https://plex.tv/users/account.json"; private const string ServerUri = "https://plex.tv/pms/servers.xml"; /// @@ -52,6 +52,13 @@ namespace Ombi.Api.Plex return await Api.Request(request); } + public async Task GetAccount(string authToken) + { + var request = new Request(GetAccountUri, string.Empty, HttpMethod.Get); + AddHeaders(request, authToken); + return await Api.Request(request); + } + public async Task GetServer(string authToken) { var request = new Request(ServerUri, string.Empty, HttpMethod.Get, ContentType.Xml); diff --git a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs index 35f1bc892..7ff8283da 100644 --- a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs @@ -1,10 +1,10 @@ using System.Security.Principal; using System.Threading.Tasks; using Moq; -using Ombi.Core.Claims; using Ombi.Core.Rule.Rules.Request; using Ombi.Store.Entities.Requests; using NUnit.Framework; +using Ombi.Helpers; namespace Ombi.Core.Tests.Rule.Request { diff --git a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs index 2a6a85ab9..c9db5875a 100644 --- a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs @@ -2,8 +2,8 @@ using System.Security.Principal; using System.Threading.Tasks; using Moq; using NUnit.Framework; -using Ombi.Core.Claims; using Ombi.Core.Rule.Rules; +using Ombi.Helpers; using Ombi.Store.Entities.Requests; namespace Ombi.Core.Tests.Rule.Request diff --git a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs index f1a14acdd..7eecd62f2 100644 --- a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs @@ -1,8 +1,8 @@ using System.Security.Principal; using System.Threading.Tasks; -using Ombi.Core.Claims; using Ombi.Core.Models.Requests; using Ombi.Core.Rule.Interfaces; +using Ombi.Helpers; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; diff --git a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs index fcbf75806..e9729ec35 100644 --- a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs @@ -1,8 +1,8 @@ -using Ombi.Core.Claims; -using Ombi.Store.Entities; +using Ombi.Store.Entities; using System.Security.Principal; using System.Threading.Tasks; using Ombi.Core.Rule.Interfaces; +using Ombi.Helpers; using Ombi.Store.Entities.Requests; namespace Ombi.Core.Rule.Rules diff --git a/src/Ombi.Core/Rule/Rules/Specific/CanRequestRule.cs b/src/Ombi.Core/Rule/Rules/Specific/CanRequestRule.cs index 36f4492af..524f4126a 100644 --- a/src/Ombi.Core/Rule/Rules/Specific/CanRequestRule.cs +++ b/src/Ombi.Core/Rule/Rules/Specific/CanRequestRule.cs @@ -1,7 +1,7 @@ using System.Security.Principal; using System.Threading.Tasks; -using Ombi.Core.Claims; using Ombi.Core.Rule.Interfaces; +using Ombi.Helpers; using Ombi.Store.Entities.Requests; namespace Ombi.Core.Rule.Rules.Specific diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index a4acd24fa..d23ee7c49 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -108,7 +108,7 @@ namespace Ombi.Core.Senders // Get the root path from the rootfolder selected. // For some reason, if we haven't got one use the first root folder in Sonarr // TODO make this overrideable via the UI - var rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? 0, s); + var rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s); try { // Does the series actually exist? diff --git a/src/Ombi.Core/Claims/OmbiRoles.cs b/src/Ombi.Helpers/OmbiRoles.cs similarity index 93% rename from src/Ombi.Core/Claims/OmbiRoles.cs rename to src/Ombi.Helpers/OmbiRoles.cs index 5d809e405..1b88b5d67 100644 --- a/src/Ombi.Core/Claims/OmbiRoles.cs +++ b/src/Ombi.Helpers/OmbiRoles.cs @@ -1,4 +1,4 @@ -namespace Ombi.Core.Claims +namespace Ombi.Helpers { public static class OmbiRoles { diff --git a/src/Ombi.Notifications/Interfaces/BaseNotification.cs b/src/Ombi.Notifications/Interfaces/BaseNotification.cs index 14f2242f9..f14947105 100644 --- a/src/Ombi.Notifications/Interfaces/BaseNotification.cs +++ b/src/Ombi.Notifications/Interfaces/BaseNotification.cs @@ -39,7 +39,7 @@ namespace Ombi.Notifications.Interfaces public async Task NotifyAsync(NotificationOptions model) { - var configuration = GetConfiguration(); + var configuration = await GetConfiguration(); await NotifyAsync(model, configuration); } @@ -100,6 +100,12 @@ namespace Ombi.Notifications.Interfaces } } + /// + /// Loads the TV or Movie Request + /// + /// + /// + /// protected virtual async Task LoadRequest(int requestId, RequestType type) { if (type == RequestType.Movie) @@ -112,12 +118,19 @@ namespace Ombi.Notifications.Interfaces } } - private T GetConfiguration() + private async Task GetConfiguration() { - var settings = Settings.GetSettings(); + var settings = await Settings.GetSettingsAsync(); return settings; } + /// + /// Loads the correct template from the DB + /// + /// + /// + /// + /// protected virtual async Task LoadTemplate(NotificationAgent agent, NotificationType type, NotificationOptions model) { var template = await TemplateRepository.GetTemplate(agent, type); diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs index ef94e4ad3..35509b675 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; @@ -44,6 +45,8 @@ namespace Ombi.Schedule.Jobs.Plex { return; } + + var allUsers = await _userManager.Users.Where(x => x.UserType == UserType.PlexUser).ToListAsync(); foreach (var server in settings.Servers) { @@ -52,6 +55,8 @@ namespace Ombi.Schedule.Jobs.Plex continue; } + await ImportAdmin(userManagementSettings, server, allUsers); + var users = await _api.GetUsers(server.PlexAuthToken); foreach (var plexUser in users.User) @@ -80,12 +85,8 @@ namespace Ombi.Schedule.Jobs.Plex }; _log.LogInformation("Creating Plex user {0}", newUser.UserName); var result = await _userManager.CreateAsync(newUser); - if (!result.Succeeded) + if (!LogResult(result)) { - foreach (var identityError in result.Errors) - { - _log.LogError(LoggingEvents.PlexUserImporter, identityError.Description); - } continue; } if (userManagementSettings.DefaultRoles.Any()) @@ -107,5 +108,59 @@ namespace Ombi.Schedule.Jobs.Plex } } } + + private async Task ImportAdmin(UserManagementSettings settings, PlexServers server, List allUsers) + { + if (!settings.ImportPlexAdmin) + { + return; + } + + var plexAdmin = (await _api.GetAccount(server.PlexAuthToken)).user; + + // Check if the admin is already in the DB + var adminUserFromDb = allUsers.FirstOrDefault(x => + x.ProviderUserId.Equals(plexAdmin.id, StringComparison.CurrentCultureIgnoreCase)); + + if (adminUserFromDb != null) + { + // Let's update the user + adminUserFromDb.Email = plexAdmin.email; + adminUserFromDb.UserName = plexAdmin.username; + adminUserFromDb.ProviderUserId = plexAdmin.id; + await _userManager.UpdateAsync(adminUserFromDb); + return; + } + + var newUser = new OmbiUser + { + UserType = UserType.PlexUser, + UserName = plexAdmin.username ?? plexAdmin.id, + ProviderUserId = plexAdmin.id, + Email = plexAdmin.email ?? string.Empty, + Alias = string.Empty + }; + + var result = await _userManager.CreateAsync(newUser); + if (!LogResult(result)) + { + return; + } + + var roleResult = await _userManager.AddToRoleAsync(newUser, OmbiRoles.Admin); + LogResult(roleResult); + } + + private bool LogResult(IdentityResult result) + { + if (!result.Succeeded) + { + foreach (var identityError in result.Errors) + { + _log.LogError(LoggingEvents.PlexUserImporter, identityError.Description); + } + } + return result.Succeeded; + } } } \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs b/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs index e708b694a..3fcde951a 100644 --- a/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs @@ -13,8 +13,6 @@ namespace Ombi.Core.Settings.Models.External public class PlexServers : ExternalSettings { public string Name { get; set; } - public bool EnableEpisodeSearching { get; set; } - public string PlexAuthToken { get; set; } public string MachineIdentifier { get; set; } diff --git a/src/Ombi.Settings/Settings/Models/UserManagementSettings.cs b/src/Ombi.Settings/Settings/Models/UserManagementSettings.cs index f0c984353..c38e1c24c 100644 --- a/src/Ombi.Settings/Settings/Models/UserManagementSettings.cs +++ b/src/Ombi.Settings/Settings/Models/UserManagementSettings.cs @@ -4,6 +4,7 @@ namespace Ombi.Settings.Settings.Models { public class UserManagementSettings : Settings { + public bool ImportPlexAdmin { get; set; } public bool ImportPlexUsers { get; set; } public bool ImportEmbyUsers { get; set; } public List DefaultRoles { get; set; } = new List(); diff --git a/src/Ombi/Attributes/PowerUserAttribute.cs b/src/Ombi/Attributes/PowerUserAttribute.cs index bc0fc0e14..6fe0839d1 100644 --- a/src/Ombi/Attributes/PowerUserAttribute.cs +++ b/src/Ombi/Attributes/PowerUserAttribute.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Authorization; -using Ombi.Core.Claims; +using Ombi.Helpers; namespace Ombi.Attributes { diff --git a/src/Ombi/ClientApp/app/app.component.html b/src/Ombi/ClientApp/app/app.component.html index e56153b1a..bba6b4a52 100644 --- a/src/Ombi/ClientApp/app/app.component.html +++ b/src/Ombi/ClientApp/app/app.component.html @@ -1,5 +1,7 @@  - +
+
+