diff --git a/PlexRequests.Core/UserMapper.cs b/PlexRequests.Core/UserMapper.cs index cbaa8ee08..f172226d0 100644 --- a/PlexRequests.Core/UserMapper.cs +++ b/PlexRequests.Core/UserMapper.cs @@ -118,6 +118,12 @@ namespace PlexRequests.Core return new Guid(userRecord.UserGuid); } + public void DeleteUser(string userId) + { + var user = Repo.Get(userId); + Repo.Delete(user); + } + public Guid? CreateAdmin(string username, string password, UserProperties properties = null) { return CreateUser(username, password, new[] { UserClaims.User, UserClaims.PowerUser, UserClaims.Admin }, properties); @@ -193,7 +199,7 @@ namespace PlexRequests.Core Guid? CreateAdmin(string username, string password, UserProperties properties = null); Guid? CreatePowerUser(string username, string password, UserProperties properties = null); Guid? CreateRegularUser(string username, string password, UserProperties properties = null); - + void DeleteUser(string userId); } } diff --git a/PlexRequests.Helpers/UserClaims.cs b/PlexRequests.Helpers/UserClaims.cs index 502aeec5f..0f1c0c4c9 100644 --- a/PlexRequests.Helpers/UserClaims.cs +++ b/PlexRequests.Helpers/UserClaims.cs @@ -7,6 +7,7 @@ namespace PlexRequests.Helpers public const string Admin = nameof(Admin); // Can do everything including creating new users and editing settings public const string PowerUser = nameof(PowerUser); // Can only manage the requests, approve etc. public const string User = nameof(User); // Can only request + public const string ReadOnlyUser = nameof(ReadOnlyUser); // Can only view stuff public const string Newsletter = nameof(Newsletter); // Has newsletter feature enabled } } diff --git a/PlexRequests.UI/Content/app/userManagement/userManagementController.js b/PlexRequests.UI/Content/app/userManagement/userManagementController.js index e747389c8..d344cc49e 100644 --- a/PlexRequests.UI/Content/app/userManagement/userManagementController.js +++ b/PlexRequests.UI/Content/app/userManagement/userManagementController.js @@ -54,20 +54,30 @@ return; } + if (!$scope.selectedClaims) { + $scope.error.error = true; + $scope.error.errorMessage = "Please select a permission"; + generateNotify($scope.error.errorMessage, 'warning'); + return; + } + userManagementService.addUser($scope.user, $scope.selectedClaims) .then(function (data) { if (data.message) { $scope.error.error = true; $scope.error.errorMessage = data.message; } else { - $scope.users.push(data); // Push the new user into the array to update the DOM + $scope.users.push(data.data); // Push the new user into the array to update the DOM $scope.user = {}; $scope.selectedClaims = {}; + $scope.claims.forEach(function (entry) { + entry.selected = false; + }); } }); }; - $scope.hasClaim = function(claim) { + $scope.hasClaim = function (claim) { var claims = $scope.selectedUser.claimsArray; var result = claims.some(function (item) { @@ -86,7 +96,26 @@ $scope.updateUser = function () { - userManagementService.updateUser($scope.selectedUser.id, $scope.selectedUser.claimsItem); + var u = $scope.selectedUser; + userManagementService.updateUser(u.id, u.claimsItem, u.alias, u.emailAddress) + .then(function (data) { + if (data) { + $scope.selectedUser = data; + return successCallback("Updated User", "success"); + } + }); + } + + $scope.deleteUser = function () { + var u = $scope.selectedUser; + var result = userManagementService.deleteUser(u.id); + + result.success(function(data) { + if (data.result) { + removeUser(u.id, true); + return successCallback("Deleted User", "success"); + } + }); } function getBaseUrl() { @@ -100,7 +129,20 @@ $scope.getClaims(); return; } + + function removeUser(id, current) { + $scope.users = $scope.users.filter(function (user) { + return user.id !== id; + }); + if (current) { + $scope.selectedUser = null; + } + } } + function successCallback(message, type) { + generateNotify(message, type); + }; + angular.module('PlexRequests').controller('userManagementController', ["$scope", "userManagementService", controller]); }()); \ No newline at end of file diff --git a/PlexRequests.UI/Content/app/userManagement/userManagementService.js b/PlexRequests.UI/Content/app/userManagement/userManagementService.js index b74100f7e..209ca20b9 100644 --- a/PlexRequests.UI/Content/app/userManagement/userManagementService.js +++ b/PlexRequests.UI/Content/app/userManagement/userManagementService.js @@ -24,12 +24,19 @@ return $http.get('/usermanagement/claims'); } - var updateUser = function (id, claims) { - + var updateUser = function (id, claims, alias, email) { return $http({ url: '/usermanagement/updateUser', method: "POST", - data: { id: id, claims: claims } + data: { id: id, claims: claims, alias: alias, emailAddress: email } + }); + } + + var deleteUser = function (id) { + return $http({ + url: '/usermanagement/deleteUser', + method: "POST", + data: { id: id } }); } @@ -38,6 +45,7 @@ addUser: addUser, getClaims: getClaims, updateUser: updateUser, + deleteUser: deleteUser }; } diff --git a/PlexRequests.UI/Models/UserManagement/DeleteUserViewModel.cs b/PlexRequests.UI/Models/UserManagement/DeleteUserViewModel.cs new file mode 100644 index 000000000..d4ab5cfaf --- /dev/null +++ b/PlexRequests.UI/Models/UserManagement/DeleteUserViewModel.cs @@ -0,0 +1,33 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: DeleteUserViewModel.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +namespace PlexRequests.UI.Models +{ + public class DeleteUserViewModel + { + public string Id { get; set; } + } +} \ No newline at end of file diff --git a/PlexRequests.UI/Models/UserManagementUsersViewModel.cs b/PlexRequests.UI/Models/UserManagement/UserManagementUsersViewModel.cs similarity index 96% rename from PlexRequests.UI/Models/UserManagementUsersViewModel.cs rename to PlexRequests.UI/Models/UserManagement/UserManagementUsersViewModel.cs index 7661943ba..21f267fb2 100644 --- a/PlexRequests.UI/Models/UserManagementUsersViewModel.cs +++ b/PlexRequests.UI/Models/UserManagement/UserManagementUsersViewModel.cs @@ -66,6 +66,9 @@ namespace PlexRequests.UI.Models [JsonProperty("claims")] public List Claims { get; set; } + public string Alias { get; set; } + public string EmailAddress { get; set; } + public class ClaimsModel { [JsonProperty("name")] diff --git a/PlexRequests.UI/Models/UserUpdateViewModel.cs b/PlexRequests.UI/Models/UserManagement/UserUpdateViewModel.cs similarity index 100% rename from PlexRequests.UI/Models/UserUpdateViewModel.cs rename to PlexRequests.UI/Models/UserManagement/UserUpdateViewModel.cs diff --git a/PlexRequests.UI/Modules/UserManagementModule.cs b/PlexRequests.UI/Modules/UserManagementModule.cs index 9e5dc0dff..7a4005026 100644 --- a/PlexRequests.UI/Modules/UserManagementModule.cs +++ b/PlexRequests.UI/Modules/UserManagementModule.cs @@ -13,6 +13,7 @@ using PlexRequests.Core; using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Helpers; +using PlexRequests.Store; using PlexRequests.UI.Models; namespace PlexRequests.UI.Modules @@ -36,6 +37,7 @@ namespace PlexRequests.UI.Modules Get["/plex/{id}", true] = async (x, ct) => await PlexDetails(x.id); Get["/claims"] = x => GetClaims(); Post["/updateuser"] = x => UpdateUser(); + Post["/deleteuser"] = x => DeleteUser(); } private ICustomUserMapper UserMapper { get; } @@ -53,40 +55,7 @@ namespace PlexRequests.UI.Modules var model = new List(); foreach (var user in localUsers) { - var claims = ByteConverterHelper.ReturnObject(user.Claims); - var claimsString = string.Join(", ", claims); - - var userProps = ByteConverterHelper.ReturnObject(user.UserProperties); - - var m = new UserManagementUsersViewModel - { - Id = user.UserGuid, - Claims = claimsString, - Username = user.UserName, - Type = UserType.LocalUser, - EmailAddress = userProps.EmailAddress, - ClaimsArray = claims, - ClaimsItem = new List() - }; - - // Add all of the current claims - foreach (var c in claims) - { - m.ClaimsItem.Add(new UserManagementUpdateModel.ClaimsModel { Name = c, Selected = true }); - } - - var allClaims = UserMapper.GetAllClaims(); - - // Get me the current claims that the user does not have - var missingClaims = allClaims.Except(claims); - - // Add them into the view - foreach (var missingClaim in missingClaims) - { - m.ClaimsItem.Add(new UserManagementUpdateModel.ClaimsModel { Name = missingClaim, Selected = false }); - } - - model.Add(m); + model.Add(MapLocalUser(user)); } var plexSettings = await PlexSettings.GetSettingsAsync(); @@ -136,7 +105,7 @@ namespace PlexRequests.UI.Modules var user = UserMapper.CreateUser(model.Username, model.Password, model.Claims, new UserProperties { EmailAddress = model.EmailAddress }); if (user.HasValue) { - return Response.AsJson(user); + return Response.AsJson(MapLocalUser(UserMapper.GetUser(user.Value))); } return Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not save user" }); @@ -174,10 +143,40 @@ namespace PlexRequests.UI.Modules var userFound = UserMapper.GetUser(new Guid(model.Id)); userFound.Claims = ByteConverterHelper.ReturnBytes(claims.ToArray()); + var currentProps = ByteConverterHelper.ReturnObject(userFound.UserProperties); + currentProps.UserAlias = model.Alias; + currentProps.EmailAddress = model.EmailAddress; + + userFound.UserProperties = ByteConverterHelper.ReturnBytes(currentProps); var user = UserMapper.EditUser(userFound); - return Response.AsJson(user); + var retUser = MapLocalUser(user); + return Response.AsJson(retUser); + } + + private Response DeleteUser() + { + var body = Request.Body.AsString(); + if (string.IsNullOrEmpty(body)) + { + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not save user, invalid JSON body" }); + } + + var model = JsonConvert.DeserializeObject(body); + + if (string.IsNullOrWhiteSpace(model.Id)) + { + return Response.AsJson(new JsonResponseModel + { + Result = true, + Message = "Couldn't find the user" + }); + } + + UserMapper.DeleteUser(model.Id); + + return Response.AsJson(new JsonResponseModel {Result = true}); } private Response LocalDetails(Guid id) @@ -224,6 +223,44 @@ namespace PlexRequests.UI.Modules } return Response.AsJson(retVal); } + + private UserManagementUsersViewModel MapLocalUser(UsersModel user) + { + var claims = ByteConverterHelper.ReturnObject(user.Claims); + var claimsString = string.Join(", ", claims); + + var userProps = ByteConverterHelper.ReturnObject(user.UserProperties); + + var m = new UserManagementUsersViewModel + { + Id = user.UserGuid, + Claims = claimsString, + Username = user.UserName, + Type = UserType.LocalUser, + EmailAddress = userProps.EmailAddress, + Alias = userProps.UserAlias, + ClaimsArray = claims, + ClaimsItem = new List() + }; + + // Add all of the current claims + foreach (var c in claims) + { + m.ClaimsItem.Add(new UserManagementUpdateModel.ClaimsModel { Name = c, Selected = true }); + } + + var allClaims = UserMapper.GetAllClaims(); + + // Get me the current claims that the user does not have + var missingClaims = allClaims.Except(claims); + + // Add them into the view + foreach (var missingClaim in missingClaims) + { + m.ClaimsItem.Add(new UserManagementUpdateModel.ClaimsModel { Name = missingClaim, Selected = false }); + } + return m; + } } } diff --git a/PlexRequests.UI/PlexRequests.UI.csproj b/PlexRequests.UI/PlexRequests.UI.csproj index 695f42ed7..a9fe57283 100644 --- a/PlexRequests.UI/PlexRequests.UI.csproj +++ b/PlexRequests.UI/PlexRequests.UI.csproj @@ -240,7 +240,8 @@ - + + @@ -496,7 +497,7 @@ - + diff --git a/PlexRequests.UI/Views/UserManagement/Index.cshtml b/PlexRequests.UI/Views/UserManagement/Index.cshtml index 764ba0f0f..7f9547c28 100644 --- a/PlexRequests.UI/Views/UserManagement/Index.cshtml +++ b/PlexRequests.UI/Views/UserManagement/Index.cshtml @@ -54,6 +54,13 @@ + + + Alias + + + + Email @@ -61,6 +68,9 @@ + + Roles + User Type @@ -75,6 +85,9 @@ {{u.username}} + + {{u.alias}} + {{u.emailAddress}} @@ -85,7 +98,7 @@ {{u.type === 1 ? 'Local User' : 'Plex User'}} - Details/Edit + Details/Edit @@ -109,23 +122,31 @@
User Type:
-
-
+
+
- + Modify Roles: -
- - -
- +
+ + +
+ + Email Address +
+ +
+ + Alias +
+ +
+ - - - +