aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api/UserService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api/UserService.cs')
-rw-r--r--MediaBrowser.Api/UserService.cs225
1 files changed, 154 insertions, 71 deletions
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 2c504bee1..51a7584b8 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -1,10 +1,13 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Connect;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Users;
using ServiceStack;
@@ -28,6 +31,9 @@ namespace MediaBrowser.Api
[ApiMember(Name = "IsDisabled", Description = "Optional filter by IsDisabled=true or false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsDisabled { get; set; }
+
+ [ApiMember(Name = "IsGuest", Description = "Optional filter by IsGuest=true or false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+ public bool? IsGuest { get; set; }
}
[Route("/Users/Public", "GET", Summary = "Gets a list of publicly visible users for display on a login screen.")]
@@ -39,7 +45,7 @@ namespace MediaBrowser.Api
/// Class GetUser
/// </summary>
[Route("/Users/{Id}", "GET", Summary = "Gets a user by Id")]
- [Authenticated]
+ [Authenticated(EscapeParentalControl = true)]
public class GetUser : IReturn<UserDto>
{
/// <summary>
@@ -47,14 +53,14 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
}
/// <summary>
/// Class DeleteUser
/// </summary>
[Route("/Users/{Id}", "DELETE", Summary = "Deletes a user")]
- [Authenticated]
+ [Authenticated(Roles = "Admin")]
public class DeleteUser : IReturnVoid
{
/// <summary>
@@ -62,7 +68,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
}
/// <summary>
@@ -76,7 +82,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
/// <summary>
/// Gets or sets the password.
@@ -105,6 +111,9 @@ namespace MediaBrowser.Api
/// <value>The password.</value>
[ApiMember(Name = "Password", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
public string Password { get; set; }
+
+ [ApiMember(Name = "PasswordMd5", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
+ public string PasswordMd5 { get; set; }
}
/// <summary>
@@ -118,7 +127,7 @@ namespace MediaBrowser.Api
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- public Guid Id { get; set; }
+ public string Id { get; set; }
/// <summary>
/// Gets or sets the password.
@@ -149,12 +158,50 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class CreateUser
+ /// Class UpdateUser
+ /// </summary>
+ [Route("/Users/{Id}/Policy", "POST", Summary = "Updates a user policy")]
+ [Authenticated(Roles = "admin")]
+ public class UpdateUserPolicy : UserPolicy, IReturnVoid
+ {
+ [ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ public string Id { get; set; }
+ }
+
+ /// <summary>
+ /// Class UpdateUser
/// </summary>
- [Route("/Users", "POST", Summary = "Creates a user")]
+ [Route("/Users/{Id}/Configuration", "POST", Summary = "Updates a user configuration")]
[Authenticated]
- public class CreateUser : UserDto, IReturn<UserDto>
+ public class UpdateUserConfiguration : UserConfiguration, IReturnVoid
+ {
+ [ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ public string Id { get; set; }
+ }
+
+ /// <summary>
+ /// Class CreateUser
+ /// </summary>
+ [Route("/Users/New", "POST", Summary = "Creates a user")]
+ [Authenticated(Roles = "Admin")]
+ public class CreateUserByName : IReturn<UserDto>
+ {
+ [ApiMember(Name = "Name", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
+ public string Name { get; set; }
+ }
+
+ [Route("/Users/ForgotPassword", "POST", Summary = "Initiates the forgot password process for a local user")]
+ public class ForgotPassword : IReturn<ForgotPasswordResult>
{
+ [ApiMember(Name = "EnteredUsername", IsRequired = false, DataType = "string", ParameterType = "body", Verb = "POST")]
+ public string EnteredUsername { get; set; }
+ }
+
+ [Route("/Users/ForgotPassword/Pin", "POST", Summary = "Redeems a forgot password pin")]
+ public class ForgotPasswordPin : IReturn<PinRedeemResult>
+ {
+ [ApiMember(Name = "Pin", IsRequired = false, DataType = "string", ParameterType = "body", Verb = "POST")]
+ public string Pin { get; set; }
}
/// <summary>
@@ -170,32 +217,24 @@ namespace MediaBrowser.Api
private readonly ISessionManager _sessionMananger;
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
+ private readonly IDeviceManager _deviceManager;
public IAuthorizationContext AuthorizationContext { get; set; }
- /// <summary>
- /// Initializes a new instance of the <see cref="UserService" /> class.
- /// </summary>
- /// <param name="userManager">The user manager.</param>
- /// <param name="dtoService">The dto service.</param>
- /// <param name="sessionMananger">The session mananger.</param>
- /// <exception cref="System.ArgumentNullException">xmlSerializer</exception>
- public UserService(IUserManager userManager, IDtoService dtoService, ISessionManager sessionMananger, IServerConfigurationManager config, INetworkManager networkManager)
+ public UserService(IUserManager userManager, IDtoService dtoService, ISessionManager sessionMananger, IServerConfigurationManager config, INetworkManager networkManager, IDeviceManager deviceManager)
{
_userManager = userManager;
_dtoService = dtoService;
_sessionMananger = sessionMananger;
_config = config;
_networkManager = networkManager;
+ _deviceManager = deviceManager;
}
public object Get(GetPublicUsers request)
{
- var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);
- var isDashboard = string.Equals(authInfo.Client, "Dashboard", StringComparison.OrdinalIgnoreCase);
-
- if ((Request.IsLocal && isDashboard) ||
- !_config.Configuration.IsStartupWizardCompleted)
+ // If the startup wizard hasn't been completed then just return all users
+ if (!_config.Configuration.IsStartupWizardCompleted)
{
return Get(new GetUsers
{
@@ -203,25 +242,12 @@ namespace MediaBrowser.Api
});
}
- // TODO: Uncomment this once all clients can handle an empty user list.
return Get(new GetUsers
{
IsHidden = false,
IsDisabled = false
- });
- //// TODO: Add or is authenticated
- //if (Request.IsLocal || IsInLocalNetwork(Request.RemoteIp))
- //{
- // return Get(new GetUsers
- // {
- // IsHidden = false,
- // IsDisabled = false
- // });
- //}
-
- //// Return empty when external
- //return ToOptimizedResult(new List<UserDto>());
+ }, true);
}
/// <summary>
@@ -231,16 +257,36 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetUsers request)
{
+ return Get(request, false);
+ }
+
+ private object Get(GetUsers request, bool filterByDevice)
+ {
var users = _userManager.Users;
if (request.IsDisabled.HasValue)
{
- users = users.Where(i => i.Configuration.IsDisabled == request.IsDisabled.Value);
+ users = users.Where(i => i.Policy.IsDisabled == request.IsDisabled.Value);
}
if (request.IsHidden.HasValue)
{
- users = users.Where(i => i.Configuration.IsHidden == request.IsHidden.Value);
+ users = users.Where(i => i.Policy.IsHidden == request.IsHidden.Value);
+ }
+
+ if (request.IsGuest.HasValue)
+ {
+ users = users.Where(i => (i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest) == request.IsGuest.Value);
+ }
+
+ if (filterByDevice)
+ {
+ var deviceId = AuthorizationContext.GetAuthorizationInfo(Request).DeviceId;
+
+ if (!string.IsNullOrWhiteSpace(deviceId))
+ {
+ users = users.Where(i => _deviceManager.CanAccessDevice(i.Id.ToString("N"), deviceId));
+ }
}
var result = users
@@ -291,6 +337,7 @@ namespace MediaBrowser.Api
}
await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false);
+
await _userManager.DeleteUser(user).ConfigureAwait(false);
}
@@ -341,11 +388,12 @@ namespace MediaBrowser.Api
AppVersion = auth.Version,
DeviceId = auth.DeviceId,
DeviceName = auth.Device,
- Password = request.Password,
+ PasswordSha1 = request.Password,
+ PasswordMd5 = request.PasswordMd5,
RemoteEndPoint = Request.RemoteIp,
Username = request.Username
- }, Request.IsLocal).ConfigureAwait(false);
+ }).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@@ -385,7 +433,7 @@ namespace MediaBrowser.Api
await _userManager.ChangePassword(user, request.NewPassword).ConfigureAwait(false);
}
}
-
+
/// <summary>
/// Posts the specified request.
/// </summary>
@@ -408,39 +456,13 @@ namespace MediaBrowser.Api
var user = _userManager.GetUserById(id);
- // If removing admin access
- if (!dtoUser.Configuration.IsAdministrator && user.Configuration.IsAdministrator)
- {
- if (_userManager.Users.Count(i => i.Configuration.IsAdministrator) == 1)
- {
- throw new ArgumentException("There must be at least one user in the system with administrative access.");
- }
- }
-
- // If disabling
- if (dtoUser.Configuration.IsDisabled && user.Configuration.IsAdministrator)
- {
- throw new ArgumentException("Administrators cannot be disabled.");
- }
-
- // If disabling
- 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.");
- }
-
- await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false);
- }
-
var task = user.Name.Equals(dtoUser.Name, StringComparison.Ordinal) ?
_userManager.UpdateUser(user) :
_userManager.RenameUser(user, dtoUser.Name);
await task.ConfigureAwait(false);
- user.UpdateConfiguration(dtoUser.Configuration);
+ await _userManager.UpdateConfiguration(dtoUser.Id, dtoUser.Configuration);
}
/// <summary>
@@ -448,17 +470,78 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Post(CreateUser request)
+ public object Post(CreateUserByName request)
{
var dtoUser = request;
var newUser = _userManager.CreateUser(dtoUser.Name).Result;
- newUser.UpdateConfiguration(dtoUser.Configuration);
-
var result = _userManager.GetUserDto(newUser, Request.RemoteIp);
return ToOptimizedResult(result);
}
+
+ /// <summary>
+ /// Posts the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>System.Object.</returns>
+ public object Post(ForgotPassword request)
+ {
+ var isLocal = Request.IsLocal || _networkManager.IsInLocalNetwork(Request.RemoteIp);
+
+ return _userManager.StartForgotPasswordProcess(request.EnteredUsername, isLocal);
+ }
+
+ public object Post(ForgotPasswordPin request)
+ {
+ return _userManager.RedeemPasswordResetPin(request.Pin);
+ }
+
+ public void Post(UpdateUserConfiguration request)
+ {
+ var task = _userManager.UpdateConfiguration(request.Id, request);
+
+ Task.WaitAll(task);
+ }
+
+ public void Post(UpdateUserPolicy request)
+ {
+ var task = UpdateUserPolicy(request);
+ Task.WaitAll(task);
+ }
+
+ private async Task UpdateUserPolicy(UpdateUserPolicy request)
+ {
+ var user = _userManager.GetUserById(request.Id);
+
+ // If removing admin access
+ if (!request.IsAdministrator && user.Policy.IsAdministrator)
+ {
+ if (_userManager.Users.Count(i => i.Policy.IsAdministrator) == 1)
+ {
+ throw new ArgumentException("There must be at least one user in the system with administrative access.");
+ }
+ }
+
+ // If disabling
+ if (request.IsDisabled && user.Policy.IsAdministrator)
+ {
+ throw new ArgumentException("Administrators cannot be disabled.");
+ }
+
+ // If disabling
+ if (request.IsDisabled && !user.Policy.IsDisabled)
+ {
+ if (_userManager.Users.Count(i => !i.Policy.IsDisabled) == 1)
+ {
+ throw new ArgumentException("There must be at least one enabled user in the system.");
+ }
+
+ await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false);
+ }
+
+ await _userManager.UpdateUserPolicy(request.Id, request).ConfigureAwait(false);
+ }
}
}