mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-11 07:46:05 -07:00
User perms
This commit is contained in:
parent
624b32d926
commit
6d1eef9154
17 changed files with 524 additions and 104 deletions
|
@ -22,7 +22,7 @@ namespace PlexRequests.Core.Migration
|
||||||
public void MigrateToLatest()
|
public void MigrateToLatest()
|
||||||
{
|
{
|
||||||
var con = Db.DbConnection();
|
var con = Db.DbConnection();
|
||||||
var versions = GetMigrations().OrderBy(x => x.Key);
|
var versions = GetMigrations();
|
||||||
|
|
||||||
var dbVersion = con.GetVersionInfo().OrderByDescending(x => x.Version).FirstOrDefault();
|
var dbVersion = con.GetVersionInfo().OrderByDescending(x => x.Version).FirstOrDefault();
|
||||||
if (dbVersion == null)
|
if (dbVersion == null)
|
||||||
|
|
58
PlexRequests.Core.Migration/Migrations/Version1100.cs
Normal file
58
PlexRequests.Core.Migration/Migrations/Version1100.cs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: Version1100.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
|
||||||
|
|
||||||
|
using System.Data;
|
||||||
|
using PlexRequests.Store;
|
||||||
|
|
||||||
|
namespace PlexRequests.Core.Migration.Migrations
|
||||||
|
{
|
||||||
|
[Migration(11000, "v1.10.0.0")]
|
||||||
|
public class Version1100 : BaseMigration, IMigration
|
||||||
|
{
|
||||||
|
public Version1100()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public int Version => 11000;
|
||||||
|
|
||||||
|
|
||||||
|
public void Start(IDbConnection con)
|
||||||
|
{
|
||||||
|
UpdateDb(con);
|
||||||
|
|
||||||
|
UpdateSchema(con, Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDb(IDbConnection con)
|
||||||
|
{
|
||||||
|
// Create the two new columns
|
||||||
|
con.AlterTable("Users", "ADD", "Permissions", true, "INTEGER");
|
||||||
|
con.AlterTable("Users", "ADD", "Features", true, "INTEGER");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,6 +65,7 @@
|
||||||
<Compile Include="MigrationAttribute.cs" />
|
<Compile Include="MigrationAttribute.cs" />
|
||||||
<Compile Include="MigrationRunner.cs" />
|
<Compile Include="MigrationRunner.cs" />
|
||||||
<Compile Include="Migrations\BaseMigration.cs" />
|
<Compile Include="Migrations\BaseMigration.cs" />
|
||||||
|
<Compile Include="Migrations\Version1100.cs" />
|
||||||
<Compile Include="Migrations\Version195.cs" />
|
<Compile Include="Migrations\Version195.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -36,6 +36,7 @@ using Nancy.Security;
|
||||||
|
|
||||||
using PlexRequests.Core.Models;
|
using PlexRequests.Core.Models;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
|
using PlexRequests.Helpers.Permissions;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
using PlexRequests.Store.Repository;
|
using PlexRequests.Store.Repository;
|
||||||
|
|
||||||
|
@ -118,6 +119,27 @@ namespace PlexRequests.Core
|
||||||
return new Guid(userRecord.UserGuid);
|
return new Guid(userRecord.UserGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Guid? CreateUser(string username, string password, int permissions, int features, UserProperties properties = null)
|
||||||
|
{
|
||||||
|
var salt = PasswordHasher.GenerateSalt();
|
||||||
|
|
||||||
|
var userModel = new UsersModel
|
||||||
|
{
|
||||||
|
UserName = username,
|
||||||
|
UserGuid = Guid.NewGuid().ToString(),
|
||||||
|
Salt = salt,
|
||||||
|
Hash = PasswordHasher.ComputeHash(password, salt),
|
||||||
|
UserProperties = ByteConverterHelper.ReturnBytes(properties ?? new UserProperties()),
|
||||||
|
Permissions = permissions,
|
||||||
|
Features = features,
|
||||||
|
Claims = new byte[] {0}
|
||||||
|
};
|
||||||
|
Repo.Insert(userModel);
|
||||||
|
var userRecord = Repo.Get(userModel.UserGuid);
|
||||||
|
|
||||||
|
return new Guid(userRecord.UserGuid);
|
||||||
|
}
|
||||||
|
|
||||||
public void DeleteUser(string userId)
|
public void DeleteUser(string userId)
|
||||||
{
|
{
|
||||||
var user = Repo.Get(userId);
|
var user = Repo.Get(userId);
|
||||||
|
@ -187,6 +209,9 @@ namespace PlexRequests.Core
|
||||||
public interface ICustomUserMapper
|
public interface ICustomUserMapper
|
||||||
{
|
{
|
||||||
Guid? CreateUser(string username, string password, string[] claims, UserProperties props);
|
Guid? CreateUser(string username, string password, string[] claims, UserProperties props);
|
||||||
|
|
||||||
|
Guid? CreateUser(string username, string password, int permissions, int features,
|
||||||
|
UserProperties properties = null);
|
||||||
IEnumerable<string> GetAllClaims();
|
IEnumerable<string> GetAllClaims();
|
||||||
IEnumerable<UsersModel> GetUsers();
|
IEnumerable<UsersModel> GetUsers();
|
||||||
Task<IEnumerable<UsersModel>> GetUsersAsync();
|
Task<IEnumerable<UsersModel>> GetUsersAsync();
|
||||||
|
|
54
PlexRequests.Helpers/EnumExtensions.cs
Normal file
54
PlexRequests.Helpers/EnumExtensions.cs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: EnumExtensions.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
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PlexRequests.Helpers
|
||||||
|
{
|
||||||
|
public static class EnumExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<Enum> GetUniqueFlags(this Enum flags)
|
||||||
|
{
|
||||||
|
ulong flag = 1;
|
||||||
|
foreach (var value in Enum.GetValues(flags.GetType()).Cast<Enum>())
|
||||||
|
{
|
||||||
|
var bits = Convert.ToUInt64(value);
|
||||||
|
while (flag < bits)
|
||||||
|
{
|
||||||
|
flag <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag == bits && flags.HasFlag(value))
|
||||||
|
{
|
||||||
|
yield return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
112
PlexRequests.Helpers/EnumHelper.cs
Normal file
112
PlexRequests.Helpers/EnumHelper.cs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: EnumHelper.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
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace PlexRequests.Helpers
|
||||||
|
{
|
||||||
|
public static class EnumHelper<T>
|
||||||
|
{
|
||||||
|
public static IList<T> GetValues(Enum value)
|
||||||
|
{
|
||||||
|
return value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public).Select(fi => (T) Enum.Parse(value.GetType(), fi.Name, false)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Parse(string value)
|
||||||
|
{
|
||||||
|
return (T)Enum.Parse(typeof(T), value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IList<string> GetNames(Enum value)
|
||||||
|
{
|
||||||
|
return value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public).Select(fi => fi.Name).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IList<string> GetDisplayValues(Enum value)
|
||||||
|
{
|
||||||
|
return GetNames(value).Select(obj => GetDisplayValue(Parse(obj))).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string LookupResource(Type resourceManagerProvider, string resourceKey)
|
||||||
|
{
|
||||||
|
foreach (var staticProperty in resourceManagerProvider.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
|
||||||
|
{
|
||||||
|
if (staticProperty.PropertyType == typeof(System.Resources.ResourceManager))
|
||||||
|
{
|
||||||
|
System.Resources.ResourceManager resourceManager = (System.Resources.ResourceManager)staticProperty.GetValue(null, null);
|
||||||
|
return resourceManager.GetString(resourceKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceKey; // Fallback with the key name
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetDisplayValue(T value)
|
||||||
|
{
|
||||||
|
var fieldInfo = value.GetType().GetField(value.ToString());
|
||||||
|
|
||||||
|
var descriptionAttributes = fieldInfo.GetCustomAttributes(
|
||||||
|
typeof(DisplayAttribute), false) as DisplayAttribute[];
|
||||||
|
|
||||||
|
if (descriptionAttributes[0].ResourceType != null)
|
||||||
|
return LookupResource(descriptionAttributes[0].ResourceType, descriptionAttributes[0].Name);
|
||||||
|
|
||||||
|
if (descriptionAttributes == null) return string.Empty;
|
||||||
|
return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Name : value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T GetValueFromName(string name)
|
||||||
|
{
|
||||||
|
var type = typeof(T);
|
||||||
|
if (!type.IsEnum) throw new InvalidOperationException();
|
||||||
|
|
||||||
|
foreach (var field in type.GetFields())
|
||||||
|
{
|
||||||
|
var attribute = Attribute.GetCustomAttribute(field,
|
||||||
|
typeof(DisplayAttribute)) as DisplayAttribute;
|
||||||
|
if (attribute != null)
|
||||||
|
{
|
||||||
|
if (attribute.Name == name)
|
||||||
|
{
|
||||||
|
return (T)field.GetValue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (field.Name == name)
|
||||||
|
return (T)field.GetValue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
PlexRequests.Helpers/Permissions/Features.cs
Normal file
42
PlexRequests.Helpers/Permissions/Features.cs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: Features.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
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace PlexRequests.Helpers.Permissions
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum Features
|
||||||
|
{
|
||||||
|
[Display(Name = "Newsletter")]
|
||||||
|
Newsletter = 1,
|
||||||
|
[Display(Name = "Recently Added Notification")]
|
||||||
|
RecentlyAddedNotification = 2,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
51
PlexRequests.Helpers/Permissions/Permissions.cs
Normal file
51
PlexRequests.Helpers/Permissions/Permissions.cs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: Permissions.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
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace PlexRequests.Helpers.Permissions
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum Permissions
|
||||||
|
{
|
||||||
|
[Display(Name = "Access Administration Settings")]
|
||||||
|
AdminSettings = 1,
|
||||||
|
|
||||||
|
[Display(Name = "Request Movie")]
|
||||||
|
RequestMovie = 2,
|
||||||
|
|
||||||
|
[Display(Name = "Request TV Show")]
|
||||||
|
RequestTvShow = 4,
|
||||||
|
|
||||||
|
[Display(Name = "Request Music")]
|
||||||
|
RequestMusic = 8,
|
||||||
|
|
||||||
|
[Display(Name = "Report Issue")]
|
||||||
|
ReportIssue = 16
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,7 @@
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Runtime.Caching" />
|
<Reference Include="System.Runtime.Caching" />
|
||||||
<Reference Include="System.Web" />
|
<Reference Include="System.Web" />
|
||||||
|
@ -69,6 +70,7 @@
|
||||||
<Compile Include="ByteConverterHelper.cs" />
|
<Compile Include="ByteConverterHelper.cs" />
|
||||||
<Compile Include="CookieHelper.cs" />
|
<Compile Include="CookieHelper.cs" />
|
||||||
<Compile Include="DateTimeHelper.cs" />
|
<Compile Include="DateTimeHelper.cs" />
|
||||||
|
<Compile Include="EnumHelper.cs" />
|
||||||
<Compile Include="Exceptions\ApiRequestException.cs" />
|
<Compile Include="Exceptions\ApiRequestException.cs" />
|
||||||
<Compile Include="Exceptions\ApplicationSettingsException.cs" />
|
<Compile Include="Exceptions\ApplicationSettingsException.cs" />
|
||||||
<Compile Include="HtmlRemover.cs" />
|
<Compile Include="HtmlRemover.cs" />
|
||||||
|
@ -78,6 +80,9 @@
|
||||||
<Compile Include="MemoryCacheProvider.cs" />
|
<Compile Include="MemoryCacheProvider.cs" />
|
||||||
<Compile Include="ObjectCopier.cs" />
|
<Compile Include="ObjectCopier.cs" />
|
||||||
<Compile Include="PasswordHasher.cs" />
|
<Compile Include="PasswordHasher.cs" />
|
||||||
|
<Compile Include="EnumExtensions.cs" />
|
||||||
|
<Compile Include="Permissions\Features.cs" />
|
||||||
|
<Compile Include="Permissions\Permissions.cs" />
|
||||||
<Compile Include="PlexHelper.cs" />
|
<Compile Include="PlexHelper.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SerializerSettings.cs" />
|
<Compile Include="SerializerSettings.cs" />
|
||||||
|
|
|
@ -7,8 +7,9 @@ CREATE TABLE IF NOT EXISTS Users
|
||||||
UserName varchar(50) NOT NULL,
|
UserName varchar(50) NOT NULL,
|
||||||
Salt BLOB NOT NULL,
|
Salt BLOB NOT NULL,
|
||||||
Hash BLOB NOT NULL,
|
Hash BLOB NOT NULL,
|
||||||
Claims BLOB NOT NULL,
|
UserProperties BLOB,
|
||||||
UserProperties BLOB
|
Permissions INTEGER,
|
||||||
|
Features INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS UserLogins
|
CREATE TABLE IF NOT EXISTS UserLogins
|
||||||
|
|
|
@ -57,12 +57,13 @@ namespace PlexRequests.Store
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddColumn(this IDbConnection connection, string tableName, string alterType, string newColumn, bool allowNulls, string dataType)
|
public static void AlterTable(this IDbConnection connection, string tableName, string alterType, string newColumn, bool allowNulls, string dataType)
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
var result = connection.Query<TableInfo>($"PRAGMA table_info({tableName});");
|
var result = connection.Query<TableInfo>($"PRAGMA table_info({tableName});");
|
||||||
if (result.Any(x => x.name == newColumn))
|
if (result.Any(x => x.name == newColumn))
|
||||||
{
|
{
|
||||||
|
connection.Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,10 @@ namespace PlexRequests.Store
|
||||||
{
|
{
|
||||||
public byte[] Hash { get; set; }
|
public byte[] Hash { get; set; }
|
||||||
public byte[] Salt { get; set; }
|
public byte[] Salt { get; set; }
|
||||||
|
[Obsolete]
|
||||||
public byte[] Claims { get; set; }
|
public byte[] Claims { get; set; }
|
||||||
public byte[] UserProperties { get; set; }
|
public byte[] UserProperties { get; set; }
|
||||||
|
public int Permissions { get; set; }
|
||||||
|
public int Features { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,14 @@
|
||||||
|
|
||||||
$scope.user = {}; // The local user
|
$scope.user = {}; // The local user
|
||||||
$scope.users = []; // list of users
|
$scope.users = []; // list of users
|
||||||
$scope.claims = []; // List of claims
|
|
||||||
|
$scope.features = []; // List of features
|
||||||
|
$scope.permissions = []; // List of permissions
|
||||||
|
|
||||||
$scope.selectedUser = {}; // User on the right side
|
$scope.selectedUser = {}; // User on the right side
|
||||||
$scope.selectedClaims = {};
|
|
||||||
|
$scope.selectedFeatures = {};
|
||||||
|
$scope.selectedPermissions = {};
|
||||||
|
|
||||||
$scope.minDate = "0001-01-01T00:00:00.0000000+00:00";
|
$scope.minDate = "0001-01-01T00:00:00.0000000+00:00";
|
||||||
|
|
||||||
|
@ -44,11 +48,16 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the claims and populate the create dropdown
|
// Get the permissions and features and populate the create dropdown
|
||||||
$scope.getClaims = function () {
|
$scope.getFeaturesPermissions = function () {
|
||||||
userManagementService.getClaims()
|
userManagementService.getFeatures()
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
$scope.claims = data.data;
|
$scope.features = data.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
userManagementService.getPermissions()
|
||||||
|
.then(function (data) {
|
||||||
|
$scope.permissions = data.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,14 +71,14 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$scope.selectedClaims) {
|
if ($scope.selectedPermissions.length === 0) {
|
||||||
$scope.error.error = true;
|
$scope.error.error = true;
|
||||||
$scope.error.errorMessage = "Please select a permission";
|
$scope.error.errorMessage = "Please select a permission";
|
||||||
generateNotify($scope.error.errorMessage, 'warning');
|
generateNotify($scope.error.errorMessage, 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
userManagementService.addUser($scope.user, $scope.selectedClaims)
|
userManagementService.addUser($scope.user, $scope.selectedPermissions, $scope.selectedFeatures)
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
if (data.message) {
|
if (data.message) {
|
||||||
$scope.error.error = true;
|
$scope.error.error = true;
|
||||||
|
@ -77,27 +86,33 @@
|
||||||
} else {
|
} else {
|
||||||
$scope.users.push(data.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.user = {};
|
||||||
$scope.selectedClaims = {};
|
$scope.selectedPermissions = {}; // Clear the checkboxes
|
||||||
$scope.claims.forEach(function (entry) {
|
$scope.selectedFeatures = {};
|
||||||
|
$scope.features.forEach(function (entry) {
|
||||||
entry.selected = false;
|
entry.selected = false;
|
||||||
});
|
});
|
||||||
|
$scope.permissions.forEach(function (entry) {
|
||||||
|
entry.selected = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.hasClaim = function (claim) {
|
// Watch the checkboxes for updates (Creating a user)
|
||||||
var claims = $scope.selectedUser.claimsArray;
|
$scope.$watch('features|filter:{selected:true}',
|
||||||
|
|
||||||
var result = claims.some(function (item) {
|
|
||||||
return item === claim.name;
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.$watch('claims|filter:{selected:true}',
|
|
||||||
function (nv) {
|
function (nv) {
|
||||||
$scope.selectedClaims = nv.map(function (claim) {
|
$scope.selectedFeatures = nv.map(function (f) {
|
||||||
return claim.name;
|
return f.name;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
|
||||||
|
$scope.$watch('permissions|filter:{selected:true}',
|
||||||
|
function (nv) {
|
||||||
|
$scope.selectedPermissions = nv.map(function (f) {
|
||||||
|
return f.name;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
|
@ -105,10 +120,15 @@
|
||||||
|
|
||||||
$scope.updateUser = function () {
|
$scope.updateUser = function () {
|
||||||
var u = $scope.selectedUser;
|
var u = $scope.selectedUser;
|
||||||
userManagementService.updateUser(u.id, u.claimsItem, u.alias, u.emailAddress)
|
userManagementService.updateUser(u.id, u.permissions, u.alias, u.emailAddress)
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
$scope.selectedUser = data;
|
$scope.selectedUser = data;
|
||||||
|
|
||||||
|
if (open) {
|
||||||
|
open = false;
|
||||||
|
$("#wrapper").toggleClass("toggled");
|
||||||
|
}
|
||||||
return successCallback("Updated User", "success");
|
return successCallback("Updated User", "success");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -118,7 +138,7 @@
|
||||||
var u = $scope.selectedUser;
|
var u = $scope.selectedUser;
|
||||||
var result = userManagementService.deleteUser(u.id);
|
var result = userManagementService.deleteUser(u.id);
|
||||||
|
|
||||||
result.success(function(data) {
|
result.success(function (data) {
|
||||||
if (data.result) {
|
if (data.result) {
|
||||||
removeUser(u.id, true);
|
removeUser(u.id, true);
|
||||||
return successCallback("Deleted User", "success");
|
return successCallback("Deleted User", "success");
|
||||||
|
@ -138,7 +158,7 @@
|
||||||
// On page load
|
// On page load
|
||||||
$scope.init = function () {
|
$scope.init = function () {
|
||||||
$scope.getUsers();
|
$scope.getUsers();
|
||||||
$scope.getClaims();
|
$scope.getFeaturesPermissions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,5 +177,5 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
angular.module('PlexRequests').controller('userManagementController', ["$scope", "userManagementService","moment", controller]);
|
angular.module('PlexRequests').controller('userManagementController', ["$scope", "userManagementService", "moment", controller]);
|
||||||
}());
|
}());
|
|
@ -8,27 +8,31 @@
|
||||||
return $http.get('/usermanagement/users');
|
return $http.get('/usermanagement/users');
|
||||||
};
|
};
|
||||||
|
|
||||||
var addUser = function (user, claims) {
|
var addUser = function (user, permissions, features) {
|
||||||
if (!user || claims.length === 0) {
|
if (!user || permissions.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $http({
|
return $http({
|
||||||
url: '/usermanagement/createuser',
|
url: '/usermanagement/createuser',
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: { username: user.username, password: user.password, claims: claims, email: user.email }
|
data: { username: user.username, password: user.password, permissions: permissions, features : features, email: user.email }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var getClaims = function () {
|
var getFeatures = function () {
|
||||||
return $http.get('/usermanagement/claims');
|
return $http.get('/usermanagement/features');
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateUser = function (id, claims, alias, email) {
|
var getPermissions = function () {
|
||||||
|
return $http.get('/usermanagement/permissions');
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateUser = function (id, permissions, alias, email) {
|
||||||
return $http({
|
return $http({
|
||||||
url: '/usermanagement/updateUser',
|
url: '/usermanagement/updateUser',
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: { id: id, claims: claims, alias: alias, emailAddress: email }
|
data: { id: id, permissions: permissions, alias: alias, emailAddress: email }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +47,8 @@
|
||||||
return {
|
return {
|
||||||
getUsers: getUsers,
|
getUsers: getUsers,
|
||||||
addUser: addUser,
|
addUser: addUser,
|
||||||
getClaims: getClaims,
|
getFeatures: getFeatures,
|
||||||
|
getPermissions: getPermissions,
|
||||||
updateUser: updateUser,
|
updateUser: updateUser,
|
||||||
deleteUser: deleteUser
|
deleteUser: deleteUser
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,17 +10,20 @@ namespace PlexRequests.UI.Models
|
||||||
public UserManagementUsersViewModel()
|
public UserManagementUsersViewModel()
|
||||||
{
|
{
|
||||||
PlexInfo = new UserManagementPlexInformation();
|
PlexInfo = new UserManagementPlexInformation();
|
||||||
|
Permissions = new List<CheckBox>();
|
||||||
|
Features = new List<CheckBox>();
|
||||||
}
|
}
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public string Claims { get; set; }
|
public string FeaturesFormattedString { get; set; }
|
||||||
|
public string PermissionsFormattedString { get; set; }
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Alias { get; set; }
|
public string Alias { get; set; }
|
||||||
public UserType Type { get; set; }
|
public UserType Type { get; set; }
|
||||||
public string EmailAddress { get; set; }
|
public string EmailAddress { get; set; }
|
||||||
public UserManagementPlexInformation PlexInfo { get; set; }
|
public UserManagementPlexInformation PlexInfo { get; set; }
|
||||||
public string[] ClaimsArray { get; set; }
|
|
||||||
public List<UserManagementUpdateModel.ClaimsModel> ClaimsItem { get; set; }
|
|
||||||
public DateTime LastLoggedIn { get; set; }
|
public DateTime LastLoggedIn { get; set; }
|
||||||
|
public List<CheckBox> Permissions { get; set; }
|
||||||
|
public List<CheckBox> Features { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserManagementPlexInformation
|
public class UserManagementPlexInformation
|
||||||
|
@ -33,6 +36,13 @@ namespace PlexRequests.UI.Models
|
||||||
public List<UserManagementPlexServers> Servers { get; set; }
|
public List<UserManagementPlexServers> Servers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CheckBox
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Value { get; set; }
|
||||||
|
public bool Selected { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class UserManagementPlexServers
|
public class UserManagementPlexServers
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
@ -50,8 +60,10 @@ namespace PlexRequests.UI.Models
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
[JsonProperty("password")]
|
[JsonProperty("password")]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
[JsonProperty("claims")]
|
[JsonProperty("permissions")]
|
||||||
public string[] Claims { get; set; }
|
public List<string> Permissions { get; set; }
|
||||||
|
[JsonProperty("features")]
|
||||||
|
public List<string> Features { get; set; }
|
||||||
|
|
||||||
[JsonProperty("email")]
|
[JsonProperty("email")]
|
||||||
public string EmailAddress { get; set; }
|
public string EmailAddress { get; set; }
|
||||||
|
@ -61,20 +73,10 @@ namespace PlexRequests.UI.Models
|
||||||
{
|
{
|
||||||
[JsonProperty("id")]
|
[JsonProperty("id")]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
[JsonProperty("claims")]
|
[JsonProperty("permissions")]
|
||||||
public List<ClaimsModel> Claims { get; set; }
|
public List<CheckBox> Permissions { get; set; }
|
||||||
|
|
||||||
public string Alias { get; set; }
|
public string Alias { get; set; }
|
||||||
public string EmailAddress { get; set; }
|
public string EmailAddress { get; set; }
|
||||||
|
|
||||||
public class ClaimsModel
|
|
||||||
{
|
|
||||||
[JsonProperty("name")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
[JsonProperty("selected")]
|
|
||||||
public bool Selected { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ using PlexRequests.Core;
|
||||||
using PlexRequests.Core.Models;
|
using PlexRequests.Core.Models;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
|
using PlexRequests.Helpers.Permissions;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
using PlexRequests.Store.Repository;
|
using PlexRequests.Store.Repository;
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.UI.Models;
|
||||||
|
@ -24,7 +25,7 @@ namespace PlexRequests.UI.Modules
|
||||||
public UserManagementModule(ISettingsService<PlexRequestSettings> pr, ICustomUserMapper m, IPlexApi plexApi, ISettingsService<PlexSettings> plex, IRepository<UserLogins> userLogins) : base("usermanagement", pr)
|
public UserManagementModule(ISettingsService<PlexRequestSettings> pr, ICustomUserMapper m, IPlexApi plexApi, ISettingsService<PlexSettings> plex, IRepository<UserLogins> userLogins) : base("usermanagement", pr)
|
||||||
{
|
{
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
this.RequiresClaims(UserClaims.Admin);
|
this.RequiresAnyClaims(UserClaims.Admin);
|
||||||
#endif
|
#endif
|
||||||
UserMapper = m;
|
UserMapper = m;
|
||||||
PlexApi = plexApi;
|
PlexApi = plexApi;
|
||||||
|
@ -37,7 +38,8 @@ namespace PlexRequests.UI.Modules
|
||||||
Post["/createuser"] = x => CreateUser();
|
Post["/createuser"] = x => CreateUser();
|
||||||
Get["/local/{id}"] = x => LocalDetails((Guid)x.id);
|
Get["/local/{id}"] = x => LocalDetails((Guid)x.id);
|
||||||
Get["/plex/{id}", true] = async (x, ct) => await PlexDetails(x.id);
|
Get["/plex/{id}", true] = async (x, ct) => await PlexDetails(x.id);
|
||||||
Get["/claims"] = x => GetClaims();
|
Get["/permissions"] = x => GetEnum<Permissions>();
|
||||||
|
Get["/features"] = x => GetEnum<Features>();
|
||||||
Post["/updateuser"] = x => UpdateUser();
|
Post["/updateuser"] = x => UpdateUser();
|
||||||
Post["/deleteuser"] = x => DeleteUser();
|
Post["/deleteuser"] = x => DeleteUser();
|
||||||
}
|
}
|
||||||
|
@ -79,7 +81,7 @@ namespace PlexRequests.UI.Modules
|
||||||
Username = u.Username,
|
Username = u.Username,
|
||||||
Type = UserType.PlexUser,
|
Type = UserType.PlexUser,
|
||||||
Id = u.Id,
|
Id = u.Id,
|
||||||
Claims = "Requestor",
|
FeaturesFormattedString = "Requestor",
|
||||||
EmailAddress = u.Email,
|
EmailAddress = u.Email,
|
||||||
PlexInfo = new UserManagementPlexInformation
|
PlexInfo = new UserManagementPlexInformation
|
||||||
{
|
{
|
||||||
|
@ -110,7 +112,23 @@ namespace PlexRequests.UI.Modules
|
||||||
Message = "Please enter in a valid Username and Password"
|
Message = "Please enter in a valid Username and Password"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var user = UserMapper.CreateUser(model.Username, model.Password, model.Claims, new UserProperties { EmailAddress = model.EmailAddress });
|
|
||||||
|
var featuresVal = 0;
|
||||||
|
var permissionsVal = 0;
|
||||||
|
|
||||||
|
foreach (var feature in model.Features)
|
||||||
|
{
|
||||||
|
var f = (int)EnumHelper<Features>.GetValueFromName(feature);
|
||||||
|
featuresVal += f;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var permission in model.Permissions)
|
||||||
|
{
|
||||||
|
var f = (int)EnumHelper<Permissions>.GetValueFromName(permission);
|
||||||
|
permissionsVal += f;
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = UserMapper.CreateUser(model.Username, model.Password, featuresVal, permissionsVal, new UserProperties { EmailAddress = model.EmailAddress });
|
||||||
if (user.HasValue)
|
if (user.HasValue)
|
||||||
{
|
{
|
||||||
return Response.AsJson(MapLocalUser(UserMapper.GetUser(user.Value), DateTime.MinValue));
|
return Response.AsJson(MapLocalUser(UserMapper.GetUser(user.Value), DateTime.MinValue));
|
||||||
|
@ -137,20 +155,13 @@ namespace PlexRequests.UI.Modules
|
||||||
Message = "Couldn't find the user"
|
Message = "Couldn't find the user"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var claims = new List<string>();
|
var val = model.Permissions.Where(c => c.Selected).Sum(c => c.Value);
|
||||||
|
|
||||||
foreach (var c in model.Claims)
|
|
||||||
{
|
|
||||||
if (c.Selected)
|
|
||||||
{
|
|
||||||
claims.Add(c.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var userFound = UserMapper.GetUser(new Guid(model.Id));
|
var userFound = UserMapper.GetUser(new Guid(model.Id));
|
||||||
|
|
||||||
userFound.Claims = ByteConverterHelper.ReturnBytes(claims.ToArray());
|
userFound.Permissions = val;
|
||||||
|
|
||||||
var currentProps = ByteConverterHelper.ReturnObject<UserProperties>(userFound.UserProperties);
|
var currentProps = ByteConverterHelper.ReturnObject<UserProperties>(userFound.UserProperties);
|
||||||
currentProps.UserAlias = model.Alias;
|
currentProps.UserAlias = model.Alias;
|
||||||
currentProps.EmailAddress = model.EmailAddress;
|
currentProps.EmailAddress = model.EmailAddress;
|
||||||
|
@ -221,53 +232,69 @@ namespace PlexRequests.UI.Modules
|
||||||
/// Returns all claims for the users.
|
/// Returns all claims for the users.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private Response GetClaims()
|
private Response GetEnum<T>()
|
||||||
{
|
{
|
||||||
var retVal = new List<dynamic>();
|
var retVal = new List<CheckBox>();
|
||||||
var claims = UserMapper.GetAllClaims();
|
foreach (var p in Enum.GetValues(typeof(T)))
|
||||||
foreach (var c in claims)
|
|
||||||
{
|
{
|
||||||
retVal.Add(new { Name = c, Selected = false });
|
var perm = (T)p;
|
||||||
|
var displayValue = EnumHelper<T>.GetDisplayValue(perm);
|
||||||
|
|
||||||
|
retVal.Add(new CheckBox{ Name = displayValue, Selected = false, Value = (int)p });
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.AsJson(retVal);
|
return Response.AsJson(retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserManagementUsersViewModel MapLocalUser(UsersModel user, DateTime lastLoggedIn)
|
private UserManagementUsersViewModel MapLocalUser(UsersModel user, DateTime lastLoggedIn)
|
||||||
{
|
{
|
||||||
var claims = ByteConverterHelper.ReturnObject<string[]>(user.Claims);
|
var features = (Features) user.Features;
|
||||||
var claimsString = string.Join(", ", claims);
|
var permissions = (Permissions) user.Permissions;
|
||||||
|
|
||||||
var userProps = ByteConverterHelper.ReturnObject<UserProperties>(user.UserProperties);
|
var userProps = ByteConverterHelper.ReturnObject<UserProperties>(user.UserProperties);
|
||||||
|
|
||||||
var m = new UserManagementUsersViewModel
|
var m = new UserManagementUsersViewModel
|
||||||
{
|
{
|
||||||
Id = user.UserGuid,
|
Id = user.UserGuid,
|
||||||
Claims = claimsString,
|
PermissionsFormattedString = permissions == 0 ? "None" : permissions.ToString(),
|
||||||
|
FeaturesFormattedString = features.ToString(),
|
||||||
Username = user.UserName,
|
Username = user.UserName,
|
||||||
Type = UserType.LocalUser,
|
Type = UserType.LocalUser,
|
||||||
EmailAddress = userProps.EmailAddress,
|
EmailAddress = userProps.EmailAddress,
|
||||||
Alias = userProps.UserAlias,
|
Alias = userProps.UserAlias,
|
||||||
ClaimsArray = claims,
|
LastLoggedIn = lastLoggedIn,
|
||||||
ClaimsItem = new List<UserManagementUpdateModel.ClaimsModel>(),
|
|
||||||
LastLoggedIn = lastLoggedIn
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add all of the current claims
|
// Add permissions
|
||||||
foreach (var c in claims)
|
foreach (var p in Enum.GetValues(typeof(Permissions)))
|
||||||
{
|
{
|
||||||
m.ClaimsItem.Add(new UserManagementUpdateModel.ClaimsModel { Name = c, Selected = true });
|
var perm = (Permissions)p;
|
||||||
|
var displayValue = EnumHelper<Permissions>.GetDisplayValue(perm);
|
||||||
|
var pm = new CheckBox
|
||||||
|
{
|
||||||
|
Name = displayValue,
|
||||||
|
Selected = permissions.HasFlag(perm),
|
||||||
|
Value = (int)perm
|
||||||
|
};
|
||||||
|
|
||||||
|
m.Permissions.Add(pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
var allClaims = UserMapper.GetAllClaims();
|
// Add features
|
||||||
|
foreach (var p in Enum.GetValues(typeof(Features)))
|
||||||
// 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 });
|
var perm = (Features)p;
|
||||||
|
var displayValue = EnumHelper<Features>.GetDisplayValue(perm);
|
||||||
|
var pm = new CheckBox
|
||||||
|
{
|
||||||
|
Name = displayValue,
|
||||||
|
Selected = features.HasFlag(perm),
|
||||||
|
Value = (int)perm
|
||||||
|
};
|
||||||
|
|
||||||
|
m.Features.Add(pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
<strong>Email Address: </strong><span ng-bind="selectedUser.emailAddress"></span>
|
<strong>Email Address: </strong><span ng-bind="selectedUser.emailAddress"></span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>Permissions: </strong><span ng-bind="selectedUser.claims"></span>
|
<strong>Permissions: </strong><span ng-bind="selectedUser.permissionsFormattedString"></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Features: </strong><span ng-bind="selectedUser.featuresFormattedString"></span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>User Type: </strong><span ng-bind="selectedUser.type === 1 ? 'Local User' : 'Plex User'"></span>
|
<strong>User Type: </strong><span ng-bind="selectedUser.type === 1 ? 'Local User' : 'Plex User'"></span>
|
||||||
|
@ -28,9 +31,9 @@
|
||||||
|
|
||||||
<strong>Modify Roles:</strong>
|
<strong>Modify Roles:</strong>
|
||||||
<!--Load all claims-->
|
<!--Load all claims-->
|
||||||
<div class="checkbox" ng-repeat="claim in selectedUser.claimsItem">
|
<div class="checkbox" ng-repeat="p in selectedUser.permissions">
|
||||||
<input id="claimCheckboxEdit_{{$id}}" class="checkbox-custom" name="selectedClaims[]" ng-checked="claim.selected" ng-model="claim.selected" type="checkbox" value="claim" />
|
<input id="permissionsCheckbox_{{$id}}" class="checkbox-custom" name="permissions[]" ng-checked="p.selected" ng-model="p.selected" type="checkbox" value="{{p.value}}" />
|
||||||
<label for="claimCheckboxEdit_{{$id}}">{{claim.name}}</label>
|
<label for="permissionsCheckbox_{{$id}}">{{p.name}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<strong>Email Address</strong>
|
<strong>Email Address</strong>
|
||||||
|
@ -71,13 +74,23 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input id="email" type="email" placeholder="email address" ng-model="user.email" class="form-control form-control-custom" />
|
<input id="email" type="email" placeholder="email address" ng-model="user.email" class="form-control form-control-custom" />
|
||||||
</div>
|
</div>
|
||||||
|
<h3>Permissions: </h3>
|
||||||
<div class="checkbox" ng-repeat="claim in claims">
|
<div class="checkbox" ng-repeat="permission in permissions">
|
||||||
<input id="claimCheckbox_{{$id}}" class="checkbox-custom" name="selectedClaims[]"
|
<input id="permission_{{$id}}" class="checkbox-custom" name="permission[]"
|
||||||
ng-checked="claim.selected" ng-model="claim.selected" type="checkbox" value="claim" />
|
ng-checked="permission.selected" ng-model="permission.selected" type="checkbox" value="{{permission.value}}" />
|
||||||
<label for="claimCheckbox_{{$id}}">{{claim.name}}</label>
|
<label for="permission_{{$id}}">{{permission.name}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Features: </h3>
|
||||||
|
<div class="checkbox" ng-repeat="f in features">
|
||||||
|
<input id="features_{{$id}}" class="checkbox-custom" name="f[]"
|
||||||
|
ng-checked="f.selected" ng-model="f.selected" type="checkbox" value="{{f.value}}" />
|
||||||
|
<label for="features_{{$id}}">{{f.name}}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<input type="submit" class="btn btn-success-outline" value="Add" />
|
<input type="submit" class="btn btn-success-outline" value="Add" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -119,7 +132,7 @@
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Roles
|
Permissions
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<a href="#" ng-click="sortType = 'type'; sortReverse = !sortReverse">
|
<a href="#" ng-click="sortType = 'type'; sortReverse = !sortReverse">
|
||||||
|
@ -150,7 +163,7 @@
|
||||||
{{u.emailAddress}}
|
{{u.emailAddress}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{u.claims}}
|
{{u.permissionsFormattedString}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{u.type === 1 ? 'Local User' : 'Plex User'}}
|
{{u.type === 1 ? 'Local User' : 'Plex User'}}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue