From 643676e7ead277f3b692a465b685525495ea0036 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Mon, 30 Jan 2017 23:12:12 +0000 Subject: [PATCH] Added the user login for emby users #435 --- Ombi.Api.Interfaces/IEmbyApi.cs | 1 + Ombi.Api.Models/Emby/EmbyUser.cs | 5 + Ombi.Api/EmbyApi.cs | 46 ++- Ombi.Core/ISecurityExtensions.cs | 2 +- Ombi.Core/SecurityExtensions.cs | 26 +- Ombi.Helpers/StringHasher.cs | 6 + Ombi.Services/Jobs/EmbyUserChecker.cs | 2 - .../Repository/BaseExternalUserRepository.cs | 24 +- .../CustomAuthenticationConfiguration.cs | 2 + Ombi.UI/Bootstrapper.cs | 4 +- Ombi.UI/Helpers/HtmlSecurityHelper.cs | 4 +- Ombi.UI/Jobs/Scheduler.cs | 4 +- Ombi.UI/Modules/UserLoginModule.cs | 303 +++++++++++------- Ombi.UI/Program.cs | 2 +- Ombi.UI/Views/Shared/Partial/_Navbar.cshtml | 2 +- 15 files changed, 296 insertions(+), 137 deletions(-) diff --git a/Ombi.Api.Interfaces/IEmbyApi.cs b/Ombi.Api.Interfaces/IEmbyApi.cs index c02bcb2e0..7a2e4f6c4 100644 --- a/Ombi.Api.Interfaces/IEmbyApi.cs +++ b/Ombi.Api.Interfaces/IEmbyApi.cs @@ -12,5 +12,6 @@ namespace Ombi.Api.Interfaces List GetUsers(Uri baseUri, string apiKey); EmbyItemContainer ViewLibrary(string apiKey, string userId, Uri baseUri); EmbyInformation GetInformation(string mediaId, EmbyMediaType type, string apiKey, string userId, Uri baseUri); + EmbyUser LogIn(string username, string password, string apiKey, Uri baseUri); } } \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyUser.cs b/Ombi.Api.Models/Emby/EmbyUser.cs index 9ebf75731..f93cd8230 100644 --- a/Ombi.Api.Models/Emby/EmbyUser.cs +++ b/Ombi.Api.Models/Emby/EmbyUser.cs @@ -45,4 +45,9 @@ namespace Ombi.Api.Models.Emby public EmbyConfiguration Configuration { get; set; } public EmbyPolicy Policy { get; set; } } + + public class EmbyUserLogin + { + public EmbyUser User { get; set; } + } } \ No newline at end of file diff --git a/Ombi.Api/EmbyApi.cs b/Ombi.Api/EmbyApi.cs index 9ca6e5845..bbd25dadd 100644 --- a/Ombi.Api/EmbyApi.cs +++ b/Ombi.Api/EmbyApi.cs @@ -27,9 +27,12 @@ using System; using System.Collections.Generic; +using System.Net; +using Newtonsoft.Json; using NLog; using Ombi.Api.Interfaces; using Ombi.Api.Models.Emby; +using Ombi.Helpers; using RestSharp; namespace Ombi.Api @@ -152,6 +155,43 @@ namespace Ombi.Api return GetAll("Series", apiKey, userId, baseUri); } + public EmbyUser LogIn(string username, string password, string apiKey, Uri baseUri) + { + var request = new RestRequest + { + Resource = "emby/users/authenticatebyname", + Method = Method.POST + }; + + var body = new + { + username, + password = StringHasher.GetSha1Hash(password).ToLower(), + passwordMd5 = StringHasher.CalcuateMd5Hash(password) + }; + + request.AddJsonBody(body); + + request.AddHeader("X-Emby-Authorization", + $"MediaBrowser Client=\"Ombi\", Device=\"Ombi\", DeviceId=\"{AssemblyHelper.GetProductVersion()}\", Version=\"{AssemblyHelper.GetAssemblyVersion()}\""); + AddHeaders(request, apiKey); + + + var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling LogInfor Emby, Retrying {0}", timespan), new[] { + TimeSpan.FromSeconds (1), + TimeSpan.FromSeconds(5) + }); + + var obj = policy.Execute(() => Api.Execute(request, baseUri)); + + if (obj.StatusCode == HttpStatusCode.Unauthorized) + { + return null; + } + + return JsonConvert.DeserializeObject(obj.Content)?.User; + } + private EmbyItemContainer GetAll(string type, string apiKey, string userId, Uri baseUri) { var request = new RestRequest @@ -180,9 +220,13 @@ namespace Ombi.Api private static void AddHeaders(IRestRequest req, string apiKey) { - req.AddHeader("X-MediaBrowser-Token", apiKey); + if (!string.IsNullOrEmpty(apiKey)) + { + req.AddHeader("X-MediaBrowser-Token", apiKey); + } req.AddHeader("Accept", "application/json"); req.AddHeader("Content-Type", "application/json"); + req.AddHeader("Device", "Ombi"); } } } \ No newline at end of file diff --git a/Ombi.Core/ISecurityExtensions.cs b/Ombi.Core/ISecurityExtensions.cs index 0743b5a51..056d171a9 100644 --- a/Ombi.Core/ISecurityExtensions.cs +++ b/Ombi.Core/ISecurityExtensions.cs @@ -22,7 +22,7 @@ namespace Ombi.Core Func HttpStatusCodeIfNot(HttpStatusCode statusCode, Func test); bool IsLoggedIn(NancyContext context); bool IsNormalUser(IUserIdentity user); - bool IsPlexUser(IUserIdentity user); + bool IsExternalUser(IUserIdentity user); bool HasPermissions(string userName, Permissions perm); /// diff --git a/Ombi.Core/SecurityExtensions.cs b/Ombi.Core/SecurityExtensions.cs index 71d8284fb..326b0b448 100644 --- a/Ombi.Core/SecurityExtensions.cs +++ b/Ombi.Core/SecurityExtensions.cs @@ -36,6 +36,7 @@ using Ombi.Core.SettingModels; using Ombi.Core.Users; using Ombi.Helpers; using Ombi.Helpers.Permissions; +using Ombi.Store.Models.Emby; using Ombi.Store.Models.Plex; using Ombi.Store.Repository; @@ -43,17 +44,20 @@ namespace Ombi.Core { public class SecurityExtensions : ISecurityExtensions { - public SecurityExtensions(IUserRepository userRepository, IResourceLinker linker, IExternalUserRepository plexUsers, ISettingsService umSettings) + public SecurityExtensions(IUserRepository userRepository, IResourceLinker linker, IExternalUserRepository plexUsers, ISettingsService umSettings, + IExternalUserRepository embyUsers) { UserRepository = userRepository; Linker = linker; PlexUsers = plexUsers; UserManagementSettings = umSettings; + EmbyUsers = embyUsers; } private IUserRepository UserRepository { get; } private IResourceLinker Linker { get; } private IExternalUserRepository PlexUsers { get; } + private IExternalUserRepository EmbyUsers { get; } private ISettingsService UserManagementSettings { get; } public bool IsLoggedIn(NancyContext context) @@ -70,16 +74,18 @@ namespace Ombi.Core return realUser || plexUser; } - public bool IsPlexUser(IUserIdentity user) + public bool IsExternalUser(IUserIdentity user) { if (user == null) { return false; } var plexUser = PlexUsers.GetUserByUsername(user.UserName); - return plexUser != null; - } + var embyUser = EmbyUsers.GetUserByUsername(user.UserName); + return plexUser != null || embyUser != null; + } + public bool IsNormalUser(IUserIdentity user) { if (user == null) @@ -107,6 +113,12 @@ namespace Ombi.Core return !string.IsNullOrEmpty(plexUser.UserAlias) ? plexUser.UserAlias : plexUser.Username; } + var embyUser = EmbyUsers.GetUserByUsername(username); + if (embyUser != null) + { + return !string.IsNullOrEmpty(embyUser.UserAlias) ? embyUser.UserAlias : embyUser.Username; + } + var dbUser = UserRepository.GetUserByUsername(username); if (dbUser != null) { @@ -303,6 +315,12 @@ namespace Ombi.Core return permissions; } + var embyUsers = EmbyUsers.GetUserByUsername(userName); + if (embyUsers != null) + { + return (Permissions) embyUsers.Permissions; + } + return 0; } } diff --git a/Ombi.Helpers/StringHasher.cs b/Ombi.Helpers/StringHasher.cs index 319eeb392..40228616c 100644 --- a/Ombi.Helpers/StringHasher.cs +++ b/Ombi.Helpers/StringHasher.cs @@ -25,6 +25,7 @@ // ************************************************************************/ #endregion +using System.Linq; using System.Security.Cryptography; using System.Text; @@ -49,5 +50,10 @@ namespace Ombi.Helpers return sb.ToString(); } } + + public static string GetSha1Hash(string input) + { + return string.Join("", (new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input))).Select(x => x.ToString("x2")).ToArray()); + } } } \ No newline at end of file diff --git a/Ombi.Services/Jobs/EmbyUserChecker.cs b/Ombi.Services/Jobs/EmbyUserChecker.cs index a33fb19f8..3e7c9c3f9 100644 --- a/Ombi.Services/Jobs/EmbyUserChecker.cs +++ b/Ombi.Services/Jobs/EmbyUserChecker.cs @@ -81,10 +81,8 @@ namespace Ombi.Services.Jobs } var embyUsers = EmbyApi.GetUsers(settings.FullUri, settings.ApiKey); var userManagementSettings = UserManagementSettings.GetSettings(); - var requests = RequestService.GetAll().ToList(); var dbUsers = Repo.GetAll().ToList(); - var localUsers = LocalUserRepository.GetAll().ToList(); // Regular users foreach (var user in embyUsers) diff --git a/Ombi.Store/Repository/BaseExternalUserRepository.cs b/Ombi.Store/Repository/BaseExternalUserRepository.cs index 3df071f78..7206a5bc5 100644 --- a/Ombi.Store/Repository/BaseExternalUserRepository.cs +++ b/Ombi.Store/Repository/BaseExternalUserRepository.cs @@ -30,6 +30,8 @@ using System.Data; using System.Threading.Tasks; using Dapper; using Ombi.Helpers; +using Ombi.Store.Models.Emby; +using Ombi.Store.Models.Plex; namespace Ombi.Store.Repository { @@ -43,9 +45,25 @@ namespace Ombi.Store.Repository private ISqliteConfiguration DbConfig { get; } private IDbConnection Db => DbConfig.DbConnection(); + private string TableName + { + get + { + if (typeof(T) == typeof(PlexUsers)) + { + return "PlexUsers"; + } + if (typeof(T) == typeof(EmbyUsers)) + { + return "EmbyUsers"; + } + return string.Empty; + } + } + public T GetUser(string userGuid) { - var sql = @"SELECT * FROM PlexUsers + var sql = $@"SELECT * FROM {TableName} WHERE PlexUserId = @UserGuid COLLATE NOCASE"; return Db.QueryFirstOrDefault(sql, new {UserGuid = userGuid}); @@ -53,7 +71,7 @@ namespace Ombi.Store.Repository public T GetUserByUsername(string username) { - var sql = @"SELECT * FROM PlexUsers + var sql = $@"SELECT * FROM {TableName} WHERE Username = @UserName COLLATE NOCASE"; return Db.QueryFirstOrDefault(sql, new {UserName = username}); @@ -61,7 +79,7 @@ namespace Ombi.Store.Repository public async Task GetUserAsync(string userguid) { - var sql = @"SELECT * FROM PlexUsers + var sql = $@"SELECT * FROM {TableName} WHERE PlexUserId = @UserGuid COLLATE NOCASE"; return await Db.QueryFirstOrDefaultAsync(sql, new {UserGuid = userguid}); diff --git a/Ombi.UI/Authentication/CustomAuthenticationConfiguration.cs b/Ombi.UI/Authentication/CustomAuthenticationConfiguration.cs index 548e97053..bdf00e396 100644 --- a/Ombi.UI/Authentication/CustomAuthenticationConfiguration.cs +++ b/Ombi.UI/Authentication/CustomAuthenticationConfiguration.cs @@ -26,6 +26,7 @@ #endregion using Nancy.Cryptography; +using Ombi.Store.Models.Emby; using Ombi.Store.Models.Plex; using Ombi.Store.Repository; @@ -49,6 +50,7 @@ namespace Ombi.UI.Authentication public IUserRepository LocalUserRepository { get; set; } public IExternalUserRepository PlexUserRepository { get; set; } + public IExternalUserRepository EmbyUserRepository { get; set; } /// Gets or sets RequiresSSL property /// The flag that indicates whether SSL is required diff --git a/Ombi.UI/Bootstrapper.cs b/Ombi.UI/Bootstrapper.cs index e2931fa6a..acb9d871e 100644 --- a/Ombi.UI/Bootstrapper.cs +++ b/Ombi.UI/Bootstrapper.cs @@ -42,6 +42,7 @@ using Ombi.Core; using Ombi.Core.SettingModels; using Ombi.Helpers; using Ombi.Store; +using Ombi.Store.Models.Emby; using Ombi.Store.Models.Plex; using Ombi.Store.Repository; using Ombi.UI.Authentication; @@ -89,7 +90,8 @@ namespace Ombi.UI var config = new CustomAuthenticationConfiguration { RedirectUrl = redirect, - PlexUserRepository = container.Get>(), // TODO emby + PlexUserRepository = container.Get>(), + EmbyUserRepository = container.Get>(), LocalUserRepository = container.Get() }; diff --git a/Ombi.UI/Helpers/HtmlSecurityHelper.cs b/Ombi.UI/Helpers/HtmlSecurityHelper.cs index 1ae398091..8dc2335d3 100644 --- a/Ombi.UI/Helpers/HtmlSecurityHelper.cs +++ b/Ombi.UI/Helpers/HtmlSecurityHelper.cs @@ -72,9 +72,9 @@ namespace Ombi.UI.Helpers return Security.IsLoggedIn(context); } - public static bool IsPlexUser(this HtmlHelpers helper) + public static bool IsExternalUser(this HtmlHelpers helper) { - return Security.IsPlexUser(helper.CurrentUser); + return Security.IsExternalUser(helper.CurrentUser); } public static bool IsNormalUser(this HtmlHelpers helper) { diff --git a/Ombi.UI/Jobs/Scheduler.cs b/Ombi.UI/Jobs/Scheduler.cs index dd4fb034f..25151b59f 100644 --- a/Ombi.UI/Jobs/Scheduler.cs +++ b/Ombi.UI/Jobs/Scheduler.cs @@ -326,8 +326,8 @@ namespace Ombi.UI.Jobs var embyUserChecker = TriggerBuilder.Create() .WithIdentity("EmbyUserChecker", "Emby") - .StartNow() - //.StartAt(DateBuilder.FutureDate(1, IntervalUnit.Minute)) + //.StartNow() + .StartAt(DateBuilder.FutureDate(1, IntervalUnit.Minute)) .WithSimpleSchedule(x => x.WithIntervalInHours(s.EmbyUserChecker).RepeatForever()) .Build(); diff --git a/Ombi.UI/Modules/UserLoginModule.cs b/Ombi.UI/Modules/UserLoginModule.cs index 8126f1c83..fd3dea0b3 100644 --- a/Ombi.UI/Modules/UserLoginModule.cs +++ b/Ombi.UI/Modules/UserLoginModule.cs @@ -36,6 +36,7 @@ using Nancy.Linker; using NLog; using Ombi.Api; using Ombi.Api.Interfaces; +using Ombi.Api.Models.Emby; using Ombi.Api.Models.Plex; using Ombi.Core; using Ombi.Core.SettingModels; @@ -45,6 +46,7 @@ using Ombi.Helpers.Analytics; using Ombi.Helpers.Permissions; using Ombi.Store; using Ombi.Store.Models; +using Ombi.Store.Models.Emby; using Ombi.Store.Models.Plex; using Ombi.Store.Repository; using Ombi.UI.Authentication; @@ -57,7 +59,7 @@ namespace Ombi.UI.Modules { public UserLoginModule(ISettingsService auth, IPlexApi api, ISettingsService plexSettings, ISettingsService pr, ISettingsService lp, IAnalytics a, IResourceLinker linker, IRepository userLogins, IExternalUserRepository plexUsers, ICustomUserMapper custom, - ISecurityExtensions security, ISettingsService userManagementSettings) + ISecurityExtensions security, ISettingsService userManagementSettings, IEmbyApi embyApi, ISettingsService emby, IExternalUserRepository embyU) : base("userlogin", pr, security) { AuthService = auth; @@ -70,45 +72,9 @@ namespace Ombi.UI.Modules PlexUserRepository = plexUsers; CustomUserMapper = custom; UserManagementSettings = userManagementSettings; - - //Get["UserLoginIndex", "/", true] = async (x, ct) => - //{ - // if (Request.Query["landing"] == null) - // { - // var s = await LandingPageSettings.GetSettingsAsync(); - // if (s.Enabled) - // { - // if (s.BeforeLogin) // Before login - // { - // if (string.IsNullOrEmpty(Username)) - // { - // // They are not logged in - // return - // Context.GetRedirect(Linker.BuildRelativeUri(Context, "LandingPageIndex").ToString()); - // } - // return Context.GetRedirect(Linker.BuildRelativeUri(Context, "SearchIndex").ToString()); - // } - - // // After login - // if (string.IsNullOrEmpty(Username)) - // { - // // Not logged in yet - // return Context.GetRedirect(Linker.BuildRelativeUri(Context, "UserLoginIndex").ToString() + "?landing"); - // } - // // Send them to landing - // var landingUrl = Linker.BuildRelativeUri(Context, "LandingPageIndex").ToString(); - // return Context.GetRedirect(landingUrl); - // } - // } - - // if (!string.IsNullOrEmpty(Username) || IsAdmin) - // { - // var url = Linker.BuildRelativeUri(Context, "SearchIndex").ToString(); - // return Response.AsRedirect(url); - // } - // var settings = await AuthService.GetSettingsAsync(); - // return View["Index", settings]; - //}; + EmbySettings = emby; + EmbyApi = embyApi; + EmbyUserRepository = embyU; Post["/", true] = async (x, ct) => await LoginUser(); Get["/logout"] = x => Logout(); @@ -159,11 +125,14 @@ namespace Ombi.UI.Modules private ISettingsService AuthService { get; } private ISettingsService LandingPageSettings { get; } private ISettingsService PlexSettings { get; } + private ISettingsService EmbySettings { get; } private IPlexApi Api { get; } + private IEmbyApi EmbyApi { get; } private IResourceLinker Linker { get; } private IAnalytics Analytics { get; } private IRepository UserLogins { get; } private IExternalUserRepository PlexUserRepository { get; } + private IExternalUserRepository EmbyUserRepository { get; } private ICustomUserMapper CustomUserMapper { get; } private ISettingsService UserManagementSettings { get; } @@ -182,41 +151,77 @@ namespace Ombi.UI.Modules } var plexSettings = await PlexSettings.GetSettingsAsync(); + var embySettings = await EmbySettings.GetSettingsAsync(); var authenticated = false; var isOwner = false; var userId = string.Empty; + EmbyUser embyUser = null; - if (settings.UserAuthentication) // Check against the users in Plex + if (plexSettings.Enable) { - Log.Debug("Need to auth"); - authenticated = CheckIfUserIsInPlexFriends(username, plexSettings.PlexAuthToken); - if (authenticated) + if (settings.UserAuthentication) // Check against the users in Plex { - userId = GetUserIdIsInPlexFriends(username, plexSettings.PlexAuthToken); + Log.Debug("Need to auth"); + authenticated = CheckIfUserIsInPlexFriends(username, plexSettings.PlexAuthToken); + if (authenticated) + { + userId = GetUserIdIsInPlexFriends(username, plexSettings.PlexAuthToken); + } + if (CheckIfUserIsOwner(plexSettings.PlexAuthToken, username)) + { + Log.Debug("User is the account owner"); + authenticated = true; + isOwner = true; + userId = GetOwnerId(plexSettings.PlexAuthToken, username); + } + UsersModel dbUser = await IsDbuser(username); + if (dbUser != null) // in the db? + { + var perms = (Permissions) dbUser.Permissions; + authenticated = true; + isOwner = perms.HasFlag(Permissions.Administrator); + userId = dbUser.UserGuid; + } + Log.Debug("Friends list result = {0}", authenticated); } - if (CheckIfUserIsOwner(plexSettings.PlexAuthToken, username)) + else if (!settings.UserAuthentication) // No auth, let them pass! { - Log.Debug("User is the account owner"); authenticated = true; - isOwner = true; - userId = GetOwnerId(plexSettings.PlexAuthToken, username); } - UsersModel dbUser = await IsDbuser(username); - if (dbUser != null) // in the db? - { - var perms = (Permissions)dbUser.Permissions; - authenticated = true; - isOwner = perms.HasFlag(Permissions.Administrator); - userId = dbUser.UserGuid; - } - Log.Debug("Friends list result = {0}", authenticated); } - else if (!settings.UserAuthentication) // No auth, let them pass! + if (embySettings.Enable) { - authenticated = true; + if (settings.UserAuthentication) // Check against the users in Plex + { + Log.Debug("Need to auth"); + authenticated = CheckIfEmbyUser(username, embySettings); + if (authenticated) + { + embyUser = GetEmbyUser(username, embySettings); + userId = embyUser?.Id; + } + if (embyUser?.Policy?.IsAdministrator ?? false) + { + Log.Debug("User is the account owner"); + authenticated = true; + isOwner = true; + } + UsersModel dbUser = await IsDbuser(username); + if (dbUser != null) // in the db? + { + var perms = (Permissions)dbUser.Permissions; + authenticated = true; + isOwner = perms.HasFlag(Permissions.Administrator); + userId = dbUser.UserGuid; + } + Log.Debug("Friends list result = {0}", authenticated); + } + else if (!settings.UserAuthentication) // No auth, let them pass! + { + authenticated = true; + } } - if (settings.UsePassword || isOwner || Security.HasPermissions(username, Permissions.Administrator)) { Session[SessionKeys.UserLoginName] = username; @@ -232,7 +237,7 @@ namespace Ombi.UI.Modules { return Response.AsJson(new { result = false, message = Resources.UI.UserLogin_IncorrectUserPass }); } - var result = await AuthenticationSetup(userId, username, dateTimeOffset, loginGuid, isOwner); + var result = await AuthenticationSetup(userId, username, dateTimeOffset, loginGuid, isOwner, plexSettings.Enable, embySettings.Enable); var landingSettings = await LandingPageSettings.GetSettingsAsync(); @@ -294,26 +299,54 @@ namespace Ombi.UI.Modules var userId = string.Empty; var plexSettings = await PlexSettings.GetSettingsAsync(); + var embySettings = await EmbySettings.GetSettingsAsync(); - if (settings.UserAuthentication) // Authenticate with Plex + if (plexSettings.Enable) { - Log.Debug("Need to auth and also provide pass"); - var signedIn = (PlexAuthentication)Api.SignIn(username, password); - if (signedIn.user?.authentication_token != null) + if (settings.UserAuthentication) // Authenticate with Plex { - Log.Debug("Correct credentials, checking if the user is account owner or in the friends list"); - if (CheckIfUserIsOwner(plexSettings.PlexAuthToken, signedIn.user?.username)) + Log.Debug("Need to auth and also provide pass"); + var signedIn = (PlexAuthentication) Api.SignIn(username, password); + if (signedIn.user?.authentication_token != null) { - Log.Debug("User is the account owner"); - authenticated = true; - isOwner = true; + Log.Debug("Correct credentials, checking if the user is account owner or in the friends list"); + if (CheckIfUserIsOwner(plexSettings.PlexAuthToken, signedIn.user?.username)) + { + Log.Debug("User is the account owner"); + authenticated = true; + isOwner = true; + } + else + { + authenticated = CheckIfUserIsInPlexFriends(username, plexSettings.PlexAuthToken); + Log.Debug("Friends list result = {0}", authenticated); + } + userId = signedIn.user.uuid; } - else + } + } + if (embySettings.Enable) + { + if (settings.UserAuthentication) // Authenticate with Plex + { + Log.Debug("Need to auth and also provide pass"); + var signedIn = (EmbyUser)EmbyApi.LogIn(username, password, embySettings.ApiKey, embySettings.FullUri); + if (signedIn != null) { - authenticated = CheckIfUserIsInPlexFriends(username, plexSettings.PlexAuthToken); - Log.Debug("Friends list result = {0}", authenticated); + Log.Debug("Correct credentials, checking if the user is account owner or in the friends list"); + if (signedIn?.Policy?.IsAdministrator ?? false) + { + Log.Debug("User is the account owner"); + authenticated = true; + isOwner = true; + } + else + { + authenticated = CheckIfEmbyUser(username, embySettings); + Log.Debug("Friends list result = {0}", authenticated); + } + userId = signedIn?.Id; } - userId = signedIn.user.uuid; } } @@ -333,7 +366,7 @@ namespace Ombi.UI.Modules } - var m = await AuthenticationSetup(userId, username, dateTimeOffset, loginGuid, isOwner); + var m = await AuthenticationSetup(userId, username, dateTimeOffset, loginGuid, isOwner, plexSettings.Enable, embySettings.Enable); var landingSettings = await LandingPageSettings.GetSettingsAsync(); @@ -555,59 +588,47 @@ namespace Ombi.UI.Modules public string UserId { get; set; } } - private async Task AuthenticationSetup(string userId, string username, int dateTimeOffset, Guid loginGuid, bool isOwner) + private async Task AuthenticationSetup(string userId, string username, int dateTimeOffset, Guid loginGuid, bool isOwner, bool plex, bool emby) { var m = new LoginModel(); var settings = await AuthService.GetSettingsAsync(); var localUsers = await CustomUserMapper.GetUsersAsync(); var plexLocalUsers = await PlexUserRepository.GetAllAsync(); + var embyLocalUsers = await EmbyUserRepository.GetAllAsync(); + + var localUser = false; + - UserLogins.Insert(new UserLogins { UserId = userId, Type = UserType.PlexUser, LastLoggedIn = DateTime.UtcNow }); Log.Debug("We are authenticated! Setting session."); // Add to the session (Used in the BaseModules) Session[SessionKeys.UsernameKey] = username; Session[SessionKeys.ClientDateTimeOffsetKey] = dateTimeOffset; - var plexLocal = plexLocalUsers.FirstOrDefault(x => x.Username == username); - if (plexLocal != null) + if (plex) { - loginGuid = Guid.Parse(plexLocal.LoginId); + var plexLocal = plexLocalUsers.FirstOrDefault(x => x.Username == username); + if (plexLocal != null) + { + loginGuid = Guid.Parse(plexLocal.LoginId); + } + } + if (emby) + { + var embyLocal = embyLocalUsers.FirstOrDefault(x => x.Username == username); + if (embyLocal != null) + { + loginGuid = Guid.Parse(embyLocal.LoginId); + } } var dbUser = localUsers.FirstOrDefault(x => x.UserName == username); if (dbUser != null) { loginGuid = Guid.Parse(dbUser.UserGuid); + localUser = true; } - //if (loginGuid != Guid.Empty) - //{ - // if (!settings.UserAuthentication)// Do not need to auth make admin use login screen for now TODO remove this - // { - // if (dbUser != null) - // { - // var perms = (Permissions)dbUser.Permissions; - // if (perms.HasFlag(Permissions.Administrator)) - // { - // var uri = Linker.BuildRelativeUri(Context, "UserLoginIndex"); - // Session["TempMessage"] = Resources.UI.UserLogin_AdminUsePassword; - // //return Response.AsRedirect(uri.ToString()); - // } - // } - // if (plexLocal != null) - // { - // var perms = (Permissions)plexLocal.Permissions; - // if (perms.HasFlag(Permissions.Administrator)) - // { - // var uri = Linker.BuildRelativeUri(Context, "UserLoginIndex"); - // Session["TempMessage"] = Resources.UI.UserLogin_AdminUsePassword; - // //return Response.AsRedirect(uri.ToString()); - // } - // } - // } - //} - if (loginGuid == Guid.Empty && settings.UserAuthentication) { var defaultSettings = UserManagementSettings.GetSettings(); @@ -622,21 +643,52 @@ namespace Ombi.UI.Modules defaultPermissions += (int)Permissions.Administrator; } } - - // Looks like we still don't have an entry, so this user does not exist - await PlexUserRepository.InsertAsync(new PlexUsers + if (plex) { - PlexUserId = userId, - UserAlias = string.Empty, - Permissions = (int)defaultPermissions, - Features = UserManagementHelper.GetPermissions(defaultSettings), - Username = username, - EmailAddress = string.Empty, // We don't have it, we will get it on the next scheduled job run (in 30 mins) - LoginId = loginGuid.ToString() - }); + // Looks like we still don't have an entry, so this user does not exist + await PlexUserRepository.InsertAsync(new PlexUsers + { + PlexUserId = userId, + UserAlias = string.Empty, + Permissions = (int) defaultPermissions, + Features = UserManagementHelper.GetPermissions(defaultSettings), + Username = username, + EmailAddress = string.Empty, + // We don't have it, we will get it on the next scheduled job run (in 30 mins) + LoginId = loginGuid.ToString() + }); + } + if (emby) + { + await EmbyUserRepository.InsertAsync(new EmbyUsers + { + EmbyUserId = userId, + UserAlias = string.Empty, + Permissions = (int)defaultPermissions, + Features = UserManagementHelper.GetPermissions(defaultSettings), + Username = username, + EmailAddress = string.Empty, + LoginId = loginGuid.ToString() + }); + } } m.LoginGuid = loginGuid; m.UserId = userId; + var type = UserType.LocalUser; + if (localUser) + { + type = UserType.LocalUser; + } + else if (plex) + { + type = UserType.PlexUser; + } + else if (emby) + { + type = UserType.EmbyUser;; + } + UserLogins.Insert(new UserLogins { UserId = userId, Type = type, LastLoggedIn = DateTime.UtcNow }); + return m; } @@ -678,6 +730,19 @@ namespace Ombi.UI.Modules return allUsers != null && allUsers.Any(x => x.Title.Equals(username, StringComparison.CurrentCultureIgnoreCase)); } + private bool CheckIfEmbyUser(string username, EmbySettings s) + { + var users = EmbyApi.GetUsers(s.FullUri, s.ApiKey); + var allUsers = users?.Where(x => !string.IsNullOrEmpty(x.Name)); + return allUsers != null && allUsers.Any(x => x.Name.Equals(username, StringComparison.CurrentCultureIgnoreCase)); + } + private EmbyUser GetEmbyUser(string username, EmbySettings s) + { + var users = EmbyApi.GetUsers(s.FullUri, s.ApiKey); + var allUsers = users?.Where(x => !string.IsNullOrEmpty(x.Name)); + return allUsers?.FirstOrDefault(x => x.Name.Equals(username, StringComparison.CurrentCultureIgnoreCase)); + } + private string GetUserIdIsInPlexFriends(string username, string authToken) { diff --git a/Ombi.UI/Program.cs b/Ombi.UI/Program.cs index 4b563f7df..b454550c5 100644 --- a/Ombi.UI/Program.cs +++ b/Ombi.UI/Program.cs @@ -110,7 +110,7 @@ namespace Ombi.UI { Log.Info("This is not Mono"); Console.WriteLine("Press any key to exit"); - Console.ReadLine(); + Console.ReadLine(); } } } diff --git a/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml b/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml index f801cc9a4..e6f08774f 100644 --- a/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml +++ b/Ombi.UI/Views/Shared/Partial/_Navbar.cshtml @@ -77,7 +77,7 @@ } - else if (Html.IsPlexUser()) // Logged in but not admin + else if (Html.IsExternalUser()) // Logged in but not admin {