From f381f9765b4271c2906f142f2f7f99860da29584 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Mon, 5 Dec 2016 08:48:56 +0000 Subject: [PATCH] Fixed #727 --- PlexRequests.Services/Jobs/PlexUserChecker.cs | 29 ++++++++--- .../userManagementController.js | 8 +++ .../Modules/UserManagementModule.cs | 50 ++++++++++++++++--- PlexRequests.UI/Views/UserWizard/Index.cshtml | 2 +- 4 files changed, 74 insertions(+), 15 deletions(-) diff --git a/PlexRequests.Services/Jobs/PlexUserChecker.cs b/PlexRequests.Services/Jobs/PlexUserChecker.cs index 220be5e69..d4bd53f12 100644 --- a/PlexRequests.Services/Jobs/PlexUserChecker.cs +++ b/PlexRequests.Services/Jobs/PlexUserChecker.cs @@ -46,7 +46,7 @@ namespace PlexRequests.Services.Jobs private static readonly Logger Log = LogManager.GetCurrentClassLogger(); public PlexUserChecker(IPlexUserRepository plexUsers, IPlexApi plexAPi, IJobRecord rec, ISettingsService plexSettings, ISettingsService prSettings, ISettingsService umSettings, - IRequestService requestService) + IRequestService requestService, IUserRepository localUser) { Repo = plexUsers; JobRecord = rec; @@ -55,6 +55,7 @@ namespace PlexRequests.Services.Jobs PlexRequestSettings = prSettings; UserManagementSettings = umSettings; RequestService = requestService; + LocalUserRepository = localUser; } private IJobRecord JobRecord { get; } @@ -64,6 +65,7 @@ namespace PlexRequests.Services.Jobs private ISettingsService PlexRequestSettings { get; } private ISettingsService UserManagementSettings { get; } private IRequestService RequestService { get; } + private IUserRepository LocalUserRepository { get; } public void Execute(IJobExecutionContext context) { @@ -81,23 +83,24 @@ namespace PlexRequests.Services.Jobs var requests = RequestService.GetAll().ToList(); var dbUsers = Repo.GetAll().ToList(); + var localUsers = LocalUserRepository.GetAll().ToList(); foreach (var user in plexUsers.User) { var dbUser = dbUsers.FirstOrDefault(x => x.PlexUserId == user.Id); if (dbUser != null) { + // We already have the user, let's check if they have updated any of their info. var needToUpdate = false; var usernameChanged = false; // Do we need up update any info? - if (dbUser.EmailAddress != user.Email) + if (!dbUser.EmailAddress.Equals(user.Email, StringComparison.CurrentCultureIgnoreCase)) { dbUser.EmailAddress = user.Email; needToUpdate = true; } - if (dbUser.Username != user.Username) + if (!dbUser.Username.Equals(user.Username, StringComparison.CurrentCultureIgnoreCase)) { - dbUser.Username = user.Username; needToUpdate = true; usernameChanged = true; } @@ -106,7 +109,20 @@ namespace PlexRequests.Services.Jobs { if (usernameChanged) { - // Since the username has changed, we need to update all requests with that username (unless we are using the alias!) + // The username has changed, let's check if the username matches any local users + var localUser = localUsers.FirstOrDefault(x => x.UserName.Equals(user.Username, StringComparison.CurrentCultureIgnoreCase)); + dbUser.Username = user.Username; + if (localUser != null) + { + // looks like we have a local user with the same name... + // We should delete the local user and the Plex user will become the master, + // I am not going to update the Plex Users permissions as that could end up leading to a security vulnerability + // Where anyone could change their Plex Username to the PR.Net server admins name and get all the admin permissions. + + LocalUserRepository.Delete(localUser); + } + + // Since the username has changed, we need to update all requests with that username (unless we are using the alias! Since the alias won't change) if (string.IsNullOrEmpty(dbUser.UserAlias)) { // Update all requests @@ -128,7 +144,8 @@ namespace PlexRequests.Services.Jobs continue; } - + + // Looks like it's a new user! var m = new PlexUsers { PlexUserId = user.Id, diff --git a/PlexRequests.UI/Content/app/userManagement/userManagementController.js b/PlexRequests.UI/Content/app/userManagement/userManagementController.js index 65da53bc7..7803318d7 100644 --- a/PlexRequests.UI/Content/app/userManagement/userManagementController.js +++ b/PlexRequests.UI/Content/app/userManagement/userManagementController.js @@ -74,6 +74,14 @@ } } + var existingUsername = $scope.users.some(function (u) { + return u.username === $scope.user.username; + }); + + if (existingUsername) { + return generateNotify("A user with the username " + $scope.user.username + " already exists!", 'danger'); + } + userManagementService.addUser($scope.user, $scope.selectedPermissions, $scope.selectedFeatures) .then(function (data) { if (data.message) { diff --git a/PlexRequests.UI/Modules/UserManagementModule.cs b/PlexRequests.UI/Modules/UserManagementModule.cs index 34f6c5ce7..b870536b0 100644 --- a/PlexRequests.UI/Modules/UserManagementModule.cs +++ b/PlexRequests.UI/Modules/UserManagementModule.cs @@ -26,7 +26,7 @@ namespace PlexRequests.UI.Modules public class UserManagementModule : BaseModule { public UserManagementModule(ISettingsService pr, ICustomUserMapper m, IPlexApi plexApi, ISettingsService plex, IRepository userLogins, IPlexUserRepository plexRepo - , ISecurityExtensions security) : base("usermanagement", pr, security) + , ISecurityExtensions security, IRequestService req) : base("usermanagement", pr, security) { #if !DEBUG Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx); @@ -37,6 +37,7 @@ namespace PlexRequests.UI.Modules UserLoginsRepo = userLogins; PlexUsersRepository = plexRepo; PlexRequestSettings = pr; + RequestService = req; Get["/"] = x => Load(); @@ -56,6 +57,7 @@ namespace PlexRequests.UI.Modules private IRepository UserLoginsRepo { get; } private IPlexUserRepository PlexUsersRepository { get; } private ISettingsService PlexRequestSettings { get; } + private IRequestService RequestService { get; } private Negotiator Load() { @@ -144,7 +146,7 @@ namespace PlexRequests.UI.Modules var f = (int)EnumHelper.GetValueFromName(permission); permissionsVal += f; } - + var user = UserMapper.CreateUser(model.Username, model.Password, permissionsVal, featuresVal, new UserProperties { EmailAddress = model.EmailAddress }); if (user.HasValue) { @@ -172,7 +174,7 @@ namespace PlexRequests.UI.Modules Message = "Couldn't find the user" }); } - + var permissionsValue = model.Permissions.Where(c => c.Selected).Sum(c => c.Value); var featuresValue = model.Features.Where(c => c.Selected).Sum(c => c.Value); @@ -186,7 +188,12 @@ namespace PlexRequests.UI.Modules localUser.Permissions = permissionsValue; localUser.Features = featuresValue; + var currentProps = ByteConverterHelper.ReturnObject(localUser.UserProperties); + + // Let's check if the alias has changed, if so we need to change all the requests associated with this + await UpdateRequests(localUser.UserName, currentProps.UserAlias, model.Alias); + currentProps.UserAlias = model.Alias; currentProps.EmailAddress = model.EmailAddress; @@ -210,10 +217,12 @@ namespace PlexRequests.UI.Modules plexDbUser.Permissions = permissionsValue; plexDbUser.Features = featuresValue; + await UpdateRequests(plexDbUser.Username, plexDbUser.UserAlias, model.Alias); + plexDbUser.UserAlias = model.Alias; await PlexUsersRepository.UpdateAsync(plexDbUser); - + var retUser = MapPlexUser(plexUser, plexDbUser, userLogin?.LastLoggedIn ?? DateTime.MinValue); return Response.AsJson(retUser); } @@ -240,6 +249,31 @@ namespace PlexRequests.UI.Modules return null; // We should never end up here. } + private async Task UpdateRequests(string username, string oldAlias, string newAlias) + { + // Let's check if the alias has changed, if so we need to change all the requests associated with this + if (!oldAlias.Equals(newAlias, StringComparison.CurrentCultureIgnoreCase)) + { + var newUsername = string.IsNullOrEmpty(newAlias) ? username : newAlias; // User the username if we are clearing the alias + var olderUsername = string.IsNullOrEmpty(oldAlias) ? username : oldAlias; + + var requests = await RequestService.GetAllAsync(); + // Update all requests + var requestsWithThisUser = requests.Where(x => x.RequestedUsers.Contains(olderUsername)).ToList(); + foreach (var r in requestsWithThisUser) + { + r.RequestedUsers.Remove(olderUsername); // Remove old + r.RequestedUsers.Add(newUsername); // Add new + } + + if (requestsWithThisUser.Any()) + { + RequestService.BatchUpdate(requestsWithThisUser); + } + + } + } + private Response DeleteUser() { var body = Request.Body.AsString(); @@ -259,9 +293,9 @@ namespace PlexRequests.UI.Modules }); } - UserMapper.DeleteUser(model.Id); + UserMapper.DeleteUser(model.Id); - return Response.AsJson(new JsonResponseModel {Result = true}); + return Response.AsJson(new JsonResponseModel { Result = true }); } private Response LocalDetails(Guid id) @@ -305,8 +339,8 @@ namespace PlexRequests.UI.Modules { var perm = (T)p; var displayValue = EnumHelper.GetDisplayValue(perm); - - retVal.Add(new CheckBox{ Name = displayValue, Selected = false, Value = (int)p }); + + retVal.Add(new CheckBox { Name = displayValue, Selected = false, Value = (int)p }); } return Response.AsJson(retVal); diff --git a/PlexRequests.UI/Views/UserWizard/Index.cshtml b/PlexRequests.UI/Views/UserWizard/Index.cshtml index f8136ba53..cf9365e55 100644 --- a/PlexRequests.UI/Views/UserWizard/Index.cshtml +++ b/PlexRequests.UI/Views/UserWizard/Index.cshtml @@ -140,7 +140,7 @@