added some user access settings
This commit is contained in:
parent
6992d31155
commit
56eea6a626
|
@ -3,6 +3,7 @@ using MediaBrowser.Controller.Dto;
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Model.Users;
|
||||
using ServiceStack.ServiceHost;
|
||||
using ServiceStack.Text.Controller;
|
||||
using System;
|
||||
|
@ -19,6 +20,11 @@ namespace MediaBrowser.Api
|
|||
[Api(Description = "Gets a list of users")]
|
||||
public class GetUsers : IReturn<List<UserDto>>
|
||||
{
|
||||
[ApiMember(Name = "IsHidden", Description="Optional filter by IsHidden=true or false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsHidden { get; set; }
|
||||
|
||||
[ApiMember(Name = "IsDisabled", Description = "Optional filter by IsDisabled=true or false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsDisabled { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -56,7 +62,7 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
[Route("/Users/{Id}/Authenticate", "POST")]
|
||||
[Api(Description = "Authenticates a user")]
|
||||
public class AuthenticateUser : IReturnVoid
|
||||
public class AuthenticateUser : IReturn<AuthenticationResult>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
|
@ -73,6 +79,28 @@ namespace MediaBrowser.Api
|
|||
public string Password { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class AuthenticateUser
|
||||
/// </summary>
|
||||
[Route("/Users/{Name}/AuthenticateByName", "POST")]
|
||||
[Api(Description = "Authenticates a user")]
|
||||
public class AuthenticateUserByName : IReturn<AuthenticationResult>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
/// <value>The password.</value>
|
||||
[ApiMember(Name = "Password", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class UpdateUserPassword
|
||||
/// </summary>
|
||||
|
@ -168,11 +196,21 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
var dtoBuilder = new UserDtoBuilder(Logger);
|
||||
|
||||
var tasks = _userManager.Users.OrderBy(u => u.Name).Select(dtoBuilder.GetUserDto);
|
||||
var users = _userManager.Users;
|
||||
|
||||
var users = tasks.Select(i => i.Result).ToList();
|
||||
if (request.IsDisabled.HasValue)
|
||||
{
|
||||
users = users.Where(i => i.Configuration.IsDisabled == request.IsDisabled.Value);
|
||||
}
|
||||
|
||||
return ToOptimizedResult(users);
|
||||
if (request.IsHidden.HasValue)
|
||||
{
|
||||
users = users.Where(i => i.Configuration.IsHidden == request.IsHidden.Value);
|
||||
}
|
||||
|
||||
var tasks = users.OrderBy(u => u.Name).Select(dtoBuilder.GetUserDto).Select(i => i.Result);
|
||||
|
||||
return ToOptimizedResult(tasks.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -218,7 +256,21 @@ namespace MediaBrowser.Api
|
|||
/// Posts the specified request.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
public void Post(AuthenticateUser request)
|
||||
public object Post(AuthenticateUser request)
|
||||
{
|
||||
var result = AuthenticateUser(request).Result;
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public object Post(AuthenticateUserByName request)
|
||||
{
|
||||
var user = _userManager.Users.FirstOrDefault(i => string.Equals(request.Name, i.Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return AuthenticateUser(new AuthenticateUser { Id = user.Id, Password = request.Password }).Result;
|
||||
}
|
||||
|
||||
private async Task<object> AuthenticateUser(AuthenticateUser request)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.Id);
|
||||
|
||||
|
@ -227,13 +279,20 @@ namespace MediaBrowser.Api
|
|||
throw new ResourceNotFoundException("User not found");
|
||||
}
|
||||
|
||||
var success = _userManager.AuthenticateUser(user, request.Password).Result;
|
||||
var success = await _userManager.AuthenticateUser(user, request.Password).ConfigureAwait(false);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// Unauthorized
|
||||
throw new UnauthorizedAccessException("Invalid user or password entered.");
|
||||
}
|
||||
|
||||
var result = new AuthenticationResult
|
||||
{
|
||||
User = await new UserDtoBuilder(Logger).GetUserDto(user).ConfigureAwait(false)
|
||||
};
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -294,6 +353,15 @@ namespace MediaBrowser.Api
|
|||
}
|
||||
}
|
||||
|
||||
// If removing admin access
|
||||
if (dtoUser.Configuration.IsDisabled && !user.Configuration.IsDisabled)
|
||||
{
|
||||
if (_userManager.Users.Count(i => !i.Configuration.IsDisabled) == 1)
|
||||
{
|
||||
throw new ArgumentException("There must be at least one enabled user in the system.");
|
||||
}
|
||||
}
|
||||
|
||||
var task = user.Name.Equals(dtoUser.Name, StringComparison.Ordinal) ? _userManager.UpdateUser(user) : _userManager.RenameUser(user, dtoUser.Name);
|
||||
|
||||
Task.WaitAll(task);
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Configuration\BaseApplicationConfiguration.cs">
|
||||
<Link>Configuration\BaseApplicationConfiguration.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\ManualLoginCategory.cs">
|
||||
<Link>Configuration\ManualLoginCategory.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\ServerConfiguration.cs">
|
||||
<Link>Configuration\ServerConfiguration.cs</Link>
|
||||
</Compile>
|
||||
|
@ -331,6 +334,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Updates\PackageVersionInfo.cs">
|
||||
<Link>Updates\PackageVersionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Users\AuthenticationResult.cs">
|
||||
<Link>Users\AuthenticationResult.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Weather\WeatherUnits.cs">
|
||||
<Link>Weather\WeatherUnits.cs</Link>
|
||||
</Compile>
|
||||
|
|
10
MediaBrowser.Model/Configuration/ManualLoginCategory.cs
Normal file
10
MediaBrowser.Model/Configuration/ManualLoginCategory.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
public enum ManualLoginCategory
|
||||
{
|
||||
Mobile,
|
||||
MediaBrowserTheater,
|
||||
Roku
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using MediaBrowser.Model.Weather;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// </summary>
|
||||
/// <value>The weather unit.</value>
|
||||
public WeatherUnits WeatherUnit { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable HTTP level logging].
|
||||
/// </summary>
|
||||
|
@ -223,6 +223,8 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// <value>The dashboard source path.</value>
|
||||
public string DashboardSourcePath { get; set; }
|
||||
|
||||
public ManualLoginCategory[] ManualLoginClients { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||
/// </summary>
|
||||
|
@ -249,6 +251,8 @@ namespace MediaBrowser.Model.Configuration
|
|||
EnableInternetProviders = true; //initial installs will need these
|
||||
InternetProviderExcludeTypes = new string[] { };
|
||||
|
||||
ManualLoginClients = new ManualLoginCategory[] { };
|
||||
|
||||
MetadataRefreshDays = 30;
|
||||
PreferredMetadataLanguage = "en";
|
||||
MetadataCountryCode = "US";
|
||||
|
|
|
@ -47,7 +47,15 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// </summary>
|
||||
/// <value><c>true</c> if [use forced subtitles only]; otherwise, <c>false</c>.</value>
|
||||
public bool UseForcedSubtitlesOnly { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is hidden.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
|
||||
public bool IsHidden { get; set; }
|
||||
|
||||
public bool IsDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
||||
/// </summary>
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
</Compile>
|
||||
<Compile Include="ApiClient\IApiClient.cs" />
|
||||
<Compile Include="Configuration\BaseApplicationConfiguration.cs" />
|
||||
<Compile Include="Configuration\ManualLoginCategory.cs" />
|
||||
<Compile Include="Configuration\ServerConfiguration.cs" />
|
||||
<Compile Include="Dto\BaseItemPerson.cs" />
|
||||
<Compile Include="Dto\ChapterInfoDto.cs" />
|
||||
|
@ -141,6 +142,7 @@
|
|||
<Compile Include="Tasks\TaskTriggerInfo.cs" />
|
||||
<Compile Include="Updates\PackageInfo.cs" />
|
||||
<Compile Include="Updates\PackageVersionInfo.cs" />
|
||||
<Compile Include="Users\AuthenticationResult.cs" />
|
||||
<Compile Include="Weather\WeatherUnits.cs" />
|
||||
<Compile Include="Web\QueryStringDictionary.cs" />
|
||||
<None Include="FodyWeavers.xml" />
|
||||
|
|
9
MediaBrowser.Model/Users/AuthenticationResult.cs
Normal file
9
MediaBrowser.Model/Users/AuthenticationResult.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Model.Users
|
||||
{
|
||||
public class AuthenticationResult
|
||||
{
|
||||
public UserDto User { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,10 +1,7 @@
|
|||
using System.IO;
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Session;
|
||||
|
@ -12,12 +9,12 @@ using MediaBrowser.Model.Logging;
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Session;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Library
|
||||
{
|
||||
|
@ -174,6 +171,11 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
if (user.Configuration.IsDisabled)
|
||||
{
|
||||
throw new UnauthorizedAccessException(string.Format("The {0} account is currently disabled. Please consult with your administrator.", user.Name));
|
||||
}
|
||||
|
||||
var existingPasswordString = string.IsNullOrEmpty(user.Password) ? GetSha1String(string.Empty) : user.Password;
|
||||
|
||||
var success = string.Equals(existingPasswordString, password.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
|
||||
|
|
|
@ -101,6 +101,11 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
public Task LogConnectionActivity(string clientType, string deviceId, string deviceName, User user)
|
||||
{
|
||||
if (user != null && user.Configuration.IsDisabled)
|
||||
{
|
||||
throw new UnauthorizedAccessException(string.Format("The {0} account is currently disabled. Please consult with your administrator.", user.Name));
|
||||
}
|
||||
|
||||
var activityDate = DateTime.UtcNow;
|
||||
|
||||
GetConnection(clientType, deviceId, deviceName, user).LastActivityDate = activityDate;
|
||||
|
|
|
@ -5,7 +5,6 @@ using MediaBrowser.Common.ScheduledTasks;
|
|||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
@ -221,7 +220,21 @@ namespace MediaBrowser.WebDashboard.Api
|
|||
/// <returns>System.Object.</returns>
|
||||
public object Get(GetDashboardConfigurationPages request)
|
||||
{
|
||||
var pages = ServerEntryPoint.Instance.PluginConfigurationPages;
|
||||
const string unavilableMessage = "The server is still loading. Please try again momentarily.";
|
||||
|
||||
var instance = ServerEntryPoint.Instance;
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
throw new InvalidOperationException(unavilableMessage);
|
||||
}
|
||||
|
||||
var pages = instance.PluginConfigurationPages;
|
||||
|
||||
if (pages == null)
|
||||
{
|
||||
throw new InvalidOperationException(unavilableMessage);
|
||||
}
|
||||
|
||||
if (request.PageType.HasValue)
|
||||
{
|
||||
|
@ -428,6 +441,7 @@ namespace MediaBrowser.WebDashboard.Api
|
|||
"librarybrowser.js",
|
||||
|
||||
"aboutpage.js",
|
||||
"allusersettings.js",
|
||||
"alphapicker.js",
|
||||
"addpluginpage.js",
|
||||
"advancedconfigurationpage.js",
|
||||
|
|
|
@ -1432,9 +1432,9 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||
/**
|
||||
* Gets all users from the server
|
||||
*/
|
||||
self.getUsers = function () {
|
||||
self.getUsers = function (options) {
|
||||
|
||||
var url = self.getUrl("users");
|
||||
var url = self.getUrl("users", options || {});
|
||||
|
||||
return self.ajax({
|
||||
type: "GET",
|
||||
|
@ -1870,6 +1870,32 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||
return files;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticates a user
|
||||
* @param {String} name
|
||||
* @param {String} password
|
||||
*/
|
||||
self.authenticateUserByName = function (name, password) {
|
||||
|
||||
if (!name) {
|
||||
throw new Error("null name");
|
||||
}
|
||||
|
||||
var url = self.getUrl("Users/" + name + "/authenticatebyname");
|
||||
|
||||
var postData = {
|
||||
password: MediaBrowser.SHA1(password || "")
|
||||
};
|
||||
|
||||
return self.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: JSON.stringify(postData),
|
||||
dataType: "json",
|
||||
contentType: "application/json"
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticates a user
|
||||
* @param {String} userId
|
||||
|
@ -1891,6 +1917,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||
type: "POST",
|
||||
url: url,
|
||||
data: JSON.stringify(postData),
|
||||
dataType: "json",
|
||||
contentType: "application/json"
|
||||
});
|
||||
};
|
||||
|
|
|
@ -81,6 +81,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="ApiClient.js" />
|
||||
<Content Include="dashboard-ui\allusersettings.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\boxsets.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -354,6 +357,9 @@
|
|||
<Content Include="dashboard-ui\musicvideos.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\allusersettings.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\alphapicker.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.135" targetFramework="net45" />
|
||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.138" targetFramework="net45" />
|
||||
<package id="ServiceStack.Common" version="3.9.54" targetFramework="net45" />
|
||||
<package id="ServiceStack.Text" version="3.9.54" targetFramework="net45" />
|
||||
</packages>
|
Loading…
Reference in New Issue
Block a user