mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 08:16:05 -07:00
User management work
This commit is contained in:
parent
40f6bad063
commit
0828756171
10 changed files with 209 additions and 57 deletions
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}());
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
33
PlexRequests.UI/Models/UserManagement/DeleteUserViewModel.cs
Normal file
33
PlexRequests.UI/Models/UserManagement/DeleteUserViewModel.cs
Normal file
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -66,6 +66,9 @@ namespace PlexRequests.UI.Models
|
|||
[JsonProperty("claims")]
|
||||
public List<ClaimsModel> Claims { get; set; }
|
||||
|
||||
public string Alias { get; set; }
|
||||
public string EmailAddress { get; set; }
|
||||
|
||||
public class ClaimsModel
|
||||
{
|
||||
[JsonProperty("name")]
|
|
@ -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<UserManagementUsersViewModel>();
|
||||
foreach (var user in localUsers)
|
||||
{
|
||||
var claims = ByteConverterHelper.ReturnObject<string[]>(user.Claims);
|
||||
var claimsString = string.Join(", ", claims);
|
||||
|
||||
var userProps = ByteConverterHelper.ReturnObject<UserProperties>(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<UserManagementUpdateModel.ClaimsModel>()
|
||||
};
|
||||
|
||||
// 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<UserProperties>(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<DeleteUserViewModel>(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<string[]>(user.Claims);
|
||||
var claimsString = string.Join(", ", claims);
|
||||
|
||||
var userProps = ByteConverterHelper.ReturnObject<UserProperties>(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<UserManagementUpdateModel.ClaimsModel>()
|
||||
};
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -240,7 +240,8 @@
|
|||
<Compile Include="Models\SearchViewModel.cs" />
|
||||
<Compile Include="Models\SearchMusicViewModel.cs" />
|
||||
<Compile Include="Models\SearchMovieViewModel.cs" />
|
||||
<Compile Include="Models\UserUpdateViewModel.cs" />
|
||||
<Compile Include="Models\UserManagement\DeleteUserViewModel.cs" />
|
||||
<Compile Include="Models\UserManagement\UserUpdateViewModel.cs" />
|
||||
<Compile Include="Modules\ApiDocsModule.cs" />
|
||||
<Compile Include="Modules\ApiSettingsMetadataModule.cs" />
|
||||
<Compile Include="Modules\ApiUserMetadataModule.cs" />
|
||||
|
@ -496,7 +497,7 @@
|
|||
</Content>
|
||||
<Compile Include="Modules\ApiRequestModule.cs" />
|
||||
<Compile Include="Models\ApiModel.cs" />
|
||||
<Compile Include="Models\UserManagementUsersViewModel.cs" />
|
||||
<Compile Include="Models\UserManagement\UserManagementUsersViewModel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\bootstrap.min.js">
|
||||
|
|
|
@ -54,6 +54,13 @@
|
|||
<span ng-show="sortType == 'username' && sortReverse" class="fa fa-caret-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a href="#" ng-click="sortType = 'alias'; sortReverse = !sortReverse">
|
||||
Alias
|
||||
<span ng-show="sortType == 'alias' && !sortReverse" class="fa fa-caret-down"></span>
|
||||
<span ng-show="sortType == 'alias' && sortReverse" class="fa fa-caret-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a href="#" ng-click="sortType = 'emailAddress'; sortReverse = !sortReverse">
|
||||
Email
|
||||
|
@ -61,6 +68,9 @@
|
|||
<span ng-show="sortType == 'emailAddress' && sortReverse" class="fa fa-caret-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
Roles
|
||||
</th>
|
||||
<th>
|
||||
<a href="#" ng-click="sortType = 'type'; sortReverse = !sortReverse">
|
||||
User Type
|
||||
|
@ -75,6 +85,9 @@
|
|||
<td>
|
||||
{{u.username}}
|
||||
</td>
|
||||
<td>
|
||||
{{u.alias}}
|
||||
</td>
|
||||
<td>
|
||||
{{u.emailAddress}}
|
||||
</td>
|
||||
|
@ -85,7 +98,7 @@
|
|||
{{u.type === 1 ? 'Local User' : 'Plex User'}}
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" ng-click="selectUser(u.id)" class="btn btn-info-outline">Details/Edit</a>
|
||||
<a href="#" ng-click="selectUser(u.id)" class="btn btn-sm btn-info-outline">Details/Edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -109,8 +122,8 @@
|
|||
<div>
|
||||
<strong>User Type: </strong><span ng-bind="selectedUser.type === 1 ? 'Local User' : 'Plex User'"></span>
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
<br />
|
||||
<br />
|
||||
<div ng-show="selectedUser.type === 1">
|
||||
<!--Edit-->
|
||||
|
||||
|
@ -121,11 +134,19 @@
|
|||
<label for="claimCheckboxEdit_{{$id}}">{{claim.name}}</label>
|
||||
</div>
|
||||
|
||||
<strong>Email Address</strong>
|
||||
<div class="form-group">
|
||||
<input id="emailAddress" type="email" ng-model="selectedUser.emailAddress" class="form-control form-control-custom" />
|
||||
</div>
|
||||
|
||||
|
||||
<strong>Alias</strong>
|
||||
<div class="form-group">
|
||||
<input id="alias" type="text" ng-model="selectedUser.alias" class="form-control form-control-custom" />
|
||||
</div>
|
||||
|
||||
|
||||
<button ng-click="updateUser()" class="btn btn-primary-outline">Update</button>
|
||||
<button ng-click="deleteUser()" class="btn btn-danger-outline">Delete</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue