From f5f890e68562e55d4bed16c454c4b4305152b296 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Tue, 31 Jan 2023 12:18:10 +0100 Subject: Migrate to file-scoped namespaces --- Jellyfin.Api/Controllers/UserController.cs | 923 ++++++++++++++--------------- 1 file changed, 461 insertions(+), 462 deletions(-) (limited to 'Jellyfin.Api/Controllers/UserController.cs') diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs index 06f2227b8..7f184f31e 100644 --- a/Jellyfin.Api/Controllers/UserController.cs +++ b/Jellyfin.Api/Controllers/UserController.cs @@ -25,564 +25,563 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; -namespace Jellyfin.Api.Controllers +namespace Jellyfin.Api.Controllers; + +/// +/// User controller. +/// +[Route("Users")] +public class UserController : BaseJellyfinApiController { + private readonly IUserManager _userManager; + private readonly ISessionManager _sessionManager; + private readonly INetworkManager _networkManager; + private readonly IDeviceManager _deviceManager; + private readonly IAuthorizationContext _authContext; + private readonly IServerConfigurationManager _config; + private readonly ILogger _logger; + private readonly IQuickConnect _quickConnectManager; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + public UserController( + IUserManager userManager, + ISessionManager sessionManager, + INetworkManager networkManager, + IDeviceManager deviceManager, + IAuthorizationContext authContext, + IServerConfigurationManager config, + ILogger logger, + IQuickConnect quickConnectManager) + { + _userManager = userManager; + _sessionManager = sessionManager; + _networkManager = networkManager; + _deviceManager = deviceManager; + _authContext = authContext; + _config = config; + _logger = logger; + _quickConnectManager = quickConnectManager; + } + + /// + /// Gets a list of users. + /// + /// Optional filter by IsHidden=true or false. + /// Optional filter by IsDisabled=true or false. + /// Users returned. + /// An containing the users. + [HttpGet] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult> GetUsers( + [FromQuery] bool? isHidden, + [FromQuery] bool? isDisabled) + { + var users = Get(isHidden, isDisabled, false, false); + return Ok(users); + } + /// - /// User controller. + /// Gets a list of publicly visible users for display on a login screen. /// - [Route("Users")] - public class UserController : BaseJellyfinApiController + /// Public users returned. + /// An containing the public users. + [HttpGet("Public")] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult> GetPublicUsers() { - private readonly IUserManager _userManager; - private readonly ISessionManager _sessionManager; - private readonly INetworkManager _networkManager; - private readonly IDeviceManager _deviceManager; - private readonly IAuthorizationContext _authContext; - private readonly IServerConfigurationManager _config; - private readonly ILogger _logger; - private readonly IQuickConnect _quickConnectManager; - - /// - /// Initializes a new instance of the class. - /// - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - /// Instance of the interface. - public UserController( - IUserManager userManager, - ISessionManager sessionManager, - INetworkManager networkManager, - IDeviceManager deviceManager, - IAuthorizationContext authContext, - IServerConfigurationManager config, - ILogger logger, - IQuickConnect quickConnectManager) + // If the startup wizard hasn't been completed then just return all users + if (!_config.Configuration.IsStartupWizardCompleted) { - _userManager = userManager; - _sessionManager = sessionManager; - _networkManager = networkManager; - _deviceManager = deviceManager; - _authContext = authContext; - _config = config; - _logger = logger; - _quickConnectManager = quickConnectManager; + return Ok(Get(false, false, false, false)); } - /// - /// Gets a list of users. - /// - /// Optional filter by IsHidden=true or false. - /// Optional filter by IsDisabled=true or false. - /// Users returned. - /// An containing the users. - [HttpGet] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult> GetUsers( - [FromQuery] bool? isHidden, - [FromQuery] bool? isDisabled) + return Ok(Get(false, false, true, true)); + } + + /// + /// Gets a user by Id. + /// + /// The user id. + /// User returned. + /// User not found. + /// An with information about the user or a if the user was not found. + [HttpGet("{userId}")] + [Authorize(Policy = Policies.IgnoreParentalControl)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult GetUserById([FromRoute, Required] Guid userId) + { + var user = _userManager.GetUserById(userId); + + if (user is null) { - var users = Get(isHidden, isDisabled, false, false); - return Ok(users); + return NotFound("User not found"); } - /// - /// Gets a list of publicly visible users for display on a login screen. - /// - /// Public users returned. - /// An containing the public users. - [HttpGet("Public")] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult> GetPublicUsers() - { - // If the startup wizard hasn't been completed then just return all users - if (!_config.Configuration.IsStartupWizardCompleted) - { - return Ok(Get(false, false, false, false)); - } + var result = _userManager.GetUserDto(user, HttpContext.GetNormalizedRemoteIp().ToString()); + return result; + } + + /// + /// Deletes a user. + /// + /// The user id. + /// User deleted. + /// User not found. + /// A indicating success or a if the user was not found. + [HttpDelete("{userId}")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task DeleteUser([FromRoute, Required] Guid userId) + { + var user = _userManager.GetUserById(userId); + await _sessionManager.RevokeUserTokens(user.Id, null).ConfigureAwait(false); + await _userManager.DeleteUserAsync(userId).ConfigureAwait(false); + return NoContent(); + } + + /// + /// Authenticates a user. + /// + /// The user id. + /// The password as plain text. + /// User authenticated. + /// Sha1-hashed password only is not allowed. + /// User not found. + /// A containing an . + [HttpPost("{userId}/Authenticate")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [Obsolete("Authenticate with username instead")] + public async Task> AuthenticateUser( + [FromRoute, Required] Guid userId, + [FromQuery, Required] string pw) + { + var user = _userManager.GetUserById(userId); - return Ok(Get(false, false, true, true)); + if (user is null) + { + return NotFound("User not found"); } - /// - /// Gets a user by Id. - /// - /// The user id. - /// User returned. - /// User not found. - /// An with information about the user or a if the user was not found. - [HttpGet("{userId}")] - [Authorize(Policy = Policies.IgnoreParentalControl)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetUserById([FromRoute, Required] Guid userId) + AuthenticateUserByName request = new AuthenticateUserByName { - var user = _userManager.GetUserById(userId); + Username = user.Username, + Pw = pw + }; + return await AuthenticateUserByName(request).ConfigureAwait(false); + } + + /// + /// Authenticates a user by name. + /// + /// The request. + /// User authenticated. + /// A containing an with information about the new session. + [HttpPost("AuthenticateByName")] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> AuthenticateUserByName([FromBody, Required] AuthenticateUserByName request) + { + var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false); - if (user is null) + try + { + var result = await _sessionManager.AuthenticateNewSession(new AuthenticationRequest { - return NotFound("User not found"); - } + App = auth.Client, + AppVersion = auth.Version, + DeviceId = auth.DeviceId, + DeviceName = auth.Device, + Password = request.Pw, + RemoteEndPoint = HttpContext.GetNormalizedRemoteIp().ToString(), + Username = request.Username + }).ConfigureAwait(false); - var result = _userManager.GetUserDto(user, HttpContext.GetNormalizedRemoteIp().ToString()); return result; } - - /// - /// Deletes a user. - /// - /// The user id. - /// User deleted. - /// User not found. - /// A indicating success or a if the user was not found. - [HttpDelete("{userId}")] - [Authorize(Policy = Policies.RequiresElevation)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task DeleteUser([FromRoute, Required] Guid userId) + catch (SecurityException e) { - var user = _userManager.GetUserById(userId); - await _sessionManager.RevokeUserTokens(user.Id, null).ConfigureAwait(false); - await _userManager.DeleteUserAsync(userId).ConfigureAwait(false); - return NoContent(); + // rethrow adding IP address to message + throw new SecurityException($"[{HttpContext.GetNormalizedRemoteIp()}] {e.Message}", e); } + } - /// - /// Authenticates a user. - /// - /// The user id. - /// The password as plain text. - /// User authenticated. - /// Sha1-hashed password only is not allowed. - /// User not found. - /// A containing an . - [HttpPost("{userId}/Authenticate")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [Obsolete("Authenticate with username instead")] - public async Task> AuthenticateUser( - [FromRoute, Required] Guid userId, - [FromQuery, Required] string pw) + /// + /// Authenticates a user with quick connect. + /// + /// The request. + /// User authenticated. + /// Missing token. + /// A containing an with information about the new session. + [HttpPost("AuthenticateWithQuickConnect")] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult AuthenticateWithQuickConnect([FromBody, Required] QuickConnectDto request) + { + try { - var user = _userManager.GetUserById(userId); - - if (user is null) - { - return NotFound("User not found"); - } - - AuthenticateUserByName request = new AuthenticateUserByName - { - Username = user.Username, - Pw = pw - }; - return await AuthenticateUserByName(request).ConfigureAwait(false); + return _quickConnectManager.GetAuthorizedRequest(request.Secret); } - - /// - /// Authenticates a user by name. - /// - /// The request. - /// User authenticated. - /// A containing an with information about the new session. - [HttpPost("AuthenticateByName")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> AuthenticateUserByName([FromBody, Required] AuthenticateUserByName request) + catch (SecurityException e) { - var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false); + // rethrow adding IP address to message + throw new SecurityException($"[{HttpContext.GetNormalizedRemoteIp()}] {e.Message}", e); + } + } - try - { - var result = await _sessionManager.AuthenticateNewSession(new AuthenticationRequest - { - App = auth.Client, - AppVersion = auth.Version, - DeviceId = auth.DeviceId, - DeviceName = auth.Device, - Password = request.Pw, - RemoteEndPoint = HttpContext.GetNormalizedRemoteIp().ToString(), - Username = request.Username - }).ConfigureAwait(false); - - return result; - } - catch (SecurityException e) - { - // rethrow adding IP address to message - throw new SecurityException($"[{HttpContext.GetNormalizedRemoteIp()}] {e.Message}", e); - } + /// + /// Updates a user's password. + /// + /// The user id. + /// The request. + /// Password successfully reset. + /// User is not allowed to update the password. + /// User not found. + /// A indicating success or a or a on failure. + [HttpPost("{userId}/Password")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task UpdateUserPassword( + [FromRoute, Required] Guid userId, + [FromBody, Required] UpdateUserPassword request) + { + if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) + { + return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the password."); } - /// - /// Authenticates a user with quick connect. - /// - /// The request. - /// User authenticated. - /// Missing token. - /// A containing an with information about the new session. - [HttpPost("AuthenticateWithQuickConnect")] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult AuthenticateWithQuickConnect([FromBody, Required] QuickConnectDto request) + var user = _userManager.GetUserById(userId); + + if (user is null) { - try - { - return _quickConnectManager.GetAuthorizedRequest(request.Secret); - } - catch (SecurityException e) - { - // rethrow adding IP address to message - throw new SecurityException($"[{HttpContext.GetNormalizedRemoteIp()}] {e.Message}", e); - } + return NotFound("User not found"); } - /// - /// Updates a user's password. - /// - /// The user id. - /// The request. - /// Password successfully reset. - /// User is not allowed to update the password. - /// User not found. - /// A indicating success or a or a on failure. - [HttpPost("{userId}/Password")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdateUserPassword( - [FromRoute, Required] Guid userId, - [FromBody, Required] UpdateUserPassword request) + if (request.ResetPassword) { - if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) + await _userManager.ResetPassword(user).ConfigureAwait(false); + } + else + { + if (!User.IsInRole(UserRoles.Administrator) || User.GetUserId().Equals(userId)) { - return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the password."); + var success = await _userManager.AuthenticateUser( + user.Username, + request.CurrentPw, + request.CurrentPw, + HttpContext.GetNormalizedRemoteIp().ToString(), + false).ConfigureAwait(false); + + if (success is null) + { + return StatusCode(StatusCodes.Status403Forbidden, "Invalid user or password entered."); + } } - var user = _userManager.GetUserById(userId); + await _userManager.ChangePassword(user, request.NewPw).ConfigureAwait(false); - if (user is null) - { - return NotFound("User not found"); - } + var currentToken = User.GetToken(); - if (request.ResetPassword) - { - await _userManager.ResetPassword(user).ConfigureAwait(false); - } - else - { - if (!User.IsInRole(UserRoles.Administrator) || User.GetUserId().Equals(userId)) - { - var success = await _userManager.AuthenticateUser( - user.Username, - request.CurrentPw, - request.CurrentPw, - HttpContext.GetNormalizedRemoteIp().ToString(), - false).ConfigureAwait(false); - - if (success is null) - { - return StatusCode(StatusCodes.Status403Forbidden, "Invalid user or password entered."); - } - } + await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false); + } - await _userManager.ChangePassword(user, request.NewPw).ConfigureAwait(false); + return NoContent(); + } - var currentToken = User.GetToken(); + /// + /// Updates a user's easy password. + /// + /// The user id. + /// The request. + /// Password successfully reset. + /// User is not allowed to update the password. + /// User not found. + /// A indicating success or a or a on failure. + [HttpPost("{userId}/EasyPassword")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task UpdateUserEasyPassword( + [FromRoute, Required] Guid userId, + [FromBody, Required] UpdateUserEasyPassword request) + { + if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) + { + return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the easy password."); + } - await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false); - } + var user = _userManager.GetUserById(userId); - return NoContent(); + if (user is null) + { + return NotFound("User not found"); } - /// - /// Updates a user's easy password. - /// - /// The user id. - /// The request. - /// Password successfully reset. - /// User is not allowed to update the password. - /// User not found. - /// A indicating success or a or a on failure. - [HttpPost("{userId}/EasyPassword")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdateUserEasyPassword( - [FromRoute, Required] Guid userId, - [FromBody, Required] UpdateUserEasyPassword request) + if (request.ResetPassword) { - if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) - { - return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the easy password."); - } + await _userManager.ResetEasyPassword(user).ConfigureAwait(false); + } + else + { + await _userManager.ChangeEasyPassword(user, request.NewPw, request.NewPassword).ConfigureAwait(false); + } - var user = _userManager.GetUserById(userId); + return NoContent(); + } - if (user is null) - { - return NotFound("User not found"); - } + /// + /// Updates a user. + /// + /// The user id. + /// The updated user model. + /// User updated. + /// User information was not supplied. + /// User update forbidden. + /// A indicating success or a or a on failure. + [HttpPost("{userId}")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task UpdateUser( + [FromRoute, Required] Guid userId, + [FromBody, Required] UserDto updateUser) + { + if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) + { + return StatusCode(StatusCodes.Status403Forbidden, "User update not allowed."); + } - if (request.ResetPassword) - { - await _userManager.ResetEasyPassword(user).ConfigureAwait(false); - } - else - { - await _userManager.ChangeEasyPassword(user, request.NewPw, request.NewPassword).ConfigureAwait(false); - } + var user = _userManager.GetUserById(userId); - return NoContent(); + if (!string.Equals(user.Username, updateUser.Name, StringComparison.Ordinal)) + { + await _userManager.RenameUser(user, updateUser.Name).ConfigureAwait(false); } - /// - /// Updates a user. - /// - /// The user id. - /// The updated user model. - /// User updated. - /// User information was not supplied. - /// User update forbidden. - /// A indicating success or a or a on failure. - [HttpPost("{userId}")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task UpdateUser( - [FromRoute, Required] Guid userId, - [FromBody, Required] UserDto updateUser) - { - if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) - { - return StatusCode(StatusCodes.Status403Forbidden, "User update not allowed."); - } + await _userManager.UpdateConfigurationAsync(user.Id, updateUser.Configuration).ConfigureAwait(false); - var user = _userManager.GetUserById(userId); + return NoContent(); + } + + /// + /// Updates a user policy. + /// + /// The user id. + /// The new user policy. + /// User policy updated. + /// User policy was not supplied. + /// User policy update forbidden. + /// A indicating success or a or a on failure.. + [HttpPost("{userId}/Policy")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task UpdateUserPolicy( + [FromRoute, Required] Guid userId, + [FromBody, Required] UserPolicy newPolicy) + { + var user = _userManager.GetUserById(userId); - if (!string.Equals(user.Username, updateUser.Name, StringComparison.Ordinal)) + // If removing admin access + if (!newPolicy.IsAdministrator && user.HasPermission(PermissionKind.IsAdministrator)) + { + if (_userManager.Users.Count(i => i.HasPermission(PermissionKind.IsAdministrator)) == 1) { - await _userManager.RenameUser(user, updateUser.Name).ConfigureAwait(false); + return StatusCode(StatusCodes.Status403Forbidden, "There must be at least one user in the system with administrative access."); } - - await _userManager.UpdateConfigurationAsync(user.Id, updateUser.Configuration).ConfigureAwait(false); - - return NoContent(); } - /// - /// Updates a user policy. - /// - /// The user id. - /// The new user policy. - /// User policy updated. - /// User policy was not supplied. - /// User policy update forbidden. - /// A indicating success or a or a on failure.. - [HttpPost("{userId}/Policy")] - [Authorize(Policy = Policies.RequiresElevation)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task UpdateUserPolicy( - [FromRoute, Required] Guid userId, - [FromBody, Required] UserPolicy newPolicy) + // If disabling + if (newPolicy.IsDisabled && user.HasPermission(PermissionKind.IsAdministrator)) { - var user = _userManager.GetUserById(userId); - - // If removing admin access - if (!newPolicy.IsAdministrator && user.HasPermission(PermissionKind.IsAdministrator)) - { - if (_userManager.Users.Count(i => i.HasPermission(PermissionKind.IsAdministrator)) == 1) - { - return StatusCode(StatusCodes.Status403Forbidden, "There must be at least one user in the system with administrative access."); - } - } + return StatusCode(StatusCodes.Status403Forbidden, "Administrators cannot be disabled."); + } - // If disabling - if (newPolicy.IsDisabled && user.HasPermission(PermissionKind.IsAdministrator)) + // If disabling + if (newPolicy.IsDisabled && !user.HasPermission(PermissionKind.IsDisabled)) + { + if (_userManager.Users.Count(i => !i.HasPermission(PermissionKind.IsDisabled)) == 1) { - return StatusCode(StatusCodes.Status403Forbidden, "Administrators cannot be disabled."); + return StatusCode(StatusCodes.Status403Forbidden, "There must be at least one enabled user in the system."); } - // If disabling - if (newPolicy.IsDisabled && !user.HasPermission(PermissionKind.IsDisabled)) - { - if (_userManager.Users.Count(i => !i.HasPermission(PermissionKind.IsDisabled)) == 1) - { - return StatusCode(StatusCodes.Status403Forbidden, "There must be at least one enabled user in the system."); - } + var currentToken = User.GetToken(); + await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false); + } - var currentToken = User.GetToken(); - await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false); - } + await _userManager.UpdatePolicyAsync(userId, newPolicy).ConfigureAwait(false); - await _userManager.UpdatePolicyAsync(userId, newPolicy).ConfigureAwait(false); + return NoContent(); + } - return NoContent(); + /// + /// Updates a user configuration. + /// + /// The user id. + /// The new user configuration. + /// User configuration updated. + /// User configuration update forbidden. + /// A indicating success. + [HttpPost("{userId}/Configuration")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task UpdateUserConfiguration( + [FromRoute, Required] Guid userId, + [FromBody, Required] UserConfiguration userConfig) + { + if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) + { + return StatusCode(StatusCodes.Status403Forbidden, "User configuration update not allowed"); } - /// - /// Updates a user configuration. - /// - /// The user id. - /// The new user configuration. - /// User configuration updated. - /// User configuration update forbidden. - /// A indicating success. - [HttpPost("{userId}/Configuration")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task UpdateUserConfiguration( - [FromRoute, Required] Guid userId, - [FromBody, Required] UserConfiguration userConfig) - { - if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) - { - return StatusCode(StatusCodes.Status403Forbidden, "User configuration update not allowed"); - } + await _userManager.UpdateConfigurationAsync(userId, userConfig).ConfigureAwait(false); - await _userManager.UpdateConfigurationAsync(userId, userConfig).ConfigureAwait(false); + return NoContent(); + } - return NoContent(); - } + /// + /// Creates a user. + /// + /// The create user by name request body. + /// User created. + /// An of the new user. + [HttpPost("New")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> CreateUserByName([FromBody, Required] CreateUserByName request) + { + var newUser = await _userManager.CreateUserAsync(request.Name).ConfigureAwait(false); - /// - /// Creates a user. - /// - /// The create user by name request body. - /// User created. - /// An of the new user. - [HttpPost("New")] - [Authorize(Policy = Policies.RequiresElevation)] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> CreateUserByName([FromBody, Required] CreateUserByName request) + // no need to authenticate password for new user + if (request.Password is not null) { - var newUser = await _userManager.CreateUserAsync(request.Name).ConfigureAwait(false); + await _userManager.ChangePassword(newUser, request.Password).ConfigureAwait(false); + } - // no need to authenticate password for new user - if (request.Password is not null) - { - await _userManager.ChangePassword(newUser, request.Password).ConfigureAwait(false); - } + var result = _userManager.GetUserDto(newUser, HttpContext.GetNormalizedRemoteIp().ToString()); - var result = _userManager.GetUserDto(newUser, HttpContext.GetNormalizedRemoteIp().ToString()); + return result; + } - return result; - } + /// + /// Initiates the forgot password process for a local user. + /// + /// The forgot password request containing the entered username. + /// Password reset process started. + /// A containing a . + [HttpPost("ForgotPassword")] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> ForgotPassword([FromBody, Required] ForgotPasswordDto forgotPasswordRequest) + { + var ip = HttpContext.GetNormalizedRemoteIp(); + var isLocal = HttpContext.IsLocal() + || _networkManager.IsInLocalNetwork(ip); - /// - /// Initiates the forgot password process for a local user. - /// - /// The forgot password request containing the entered username. - /// Password reset process started. - /// A containing a . - [HttpPost("ForgotPassword")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> ForgotPassword([FromBody, Required] ForgotPasswordDto forgotPasswordRequest) + if (isLocal) { - var ip = HttpContext.GetNormalizedRemoteIp(); - var isLocal = HttpContext.IsLocal() - || _networkManager.IsInLocalNetwork(ip); + _logger.LogWarning("Password reset process initiated from outside the local network with IP: {IP}", ip); + } - if (isLocal) - { - _logger.LogWarning("Password reset process initiated from outside the local network with IP: {IP}", ip); - } + var result = await _userManager.StartForgotPasswordProcess(forgotPasswordRequest.EnteredUsername, isLocal).ConfigureAwait(false); - var result = await _userManager.StartForgotPasswordProcess(forgotPasswordRequest.EnteredUsername, isLocal).ConfigureAwait(false); + return result; + } - return result; - } + /// + /// Redeems a forgot password pin. + /// + /// The forgot password pin request containing the entered pin. + /// Pin reset process started. + /// A containing a . + [HttpPost("ForgotPassword/Pin")] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> ForgotPasswordPin([FromBody, Required] ForgotPasswordPinDto forgotPasswordPinRequest) + { + var result = await _userManager.RedeemPasswordResetPin(forgotPasswordPinRequest.Pin).ConfigureAwait(false); + return result; + } - /// - /// Redeems a forgot password pin. - /// - /// The forgot password pin request containing the entered pin. - /// Pin reset process started. - /// A containing a . - [HttpPost("ForgotPassword/Pin")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> ForgotPasswordPin([FromBody, Required] ForgotPasswordPinDto forgotPasswordPinRequest) + /// + /// Gets the user based on auth token. + /// + /// User returned. + /// Token is not owned by a user. + /// A for the authenticated user. + [HttpGet("Me")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public ActionResult GetCurrentUser() + { + var userId = User.GetUserId(); + if (userId.Equals(default)) { - var result = await _userManager.RedeemPasswordResetPin(forgotPasswordPinRequest.Pin).ConfigureAwait(false); - return result; + return BadRequest(); } - /// - /// Gets the user based on auth token. - /// - /// User returned. - /// Token is not owned by a user. - /// A for the authenticated user. - [HttpGet("Me")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public ActionResult GetCurrentUser() + var user = _userManager.GetUserById(userId); + if (user is null) { - var userId = User.GetUserId(); - if (userId.Equals(default)) - { - return BadRequest(); - } + return BadRequest(); + } - var user = _userManager.GetUserById(userId); - if (user is null) - { - return BadRequest(); - } + return _userManager.GetUserDto(user); + } - return _userManager.GetUserDto(user); - } + private IEnumerable Get(bool? isHidden, bool? isDisabled, bool filterByDevice, bool filterByNetwork) + { + var users = _userManager.Users; - private IEnumerable Get(bool? isHidden, bool? isDisabled, bool filterByDevice, bool filterByNetwork) + if (isDisabled.HasValue) { - var users = _userManager.Users; + users = users.Where(i => i.HasPermission(PermissionKind.IsDisabled) == isDisabled.Value); + } - if (isDisabled.HasValue) - { - users = users.Where(i => i.HasPermission(PermissionKind.IsDisabled) == isDisabled.Value); - } + if (isHidden.HasValue) + { + users = users.Where(i => i.HasPermission(PermissionKind.IsHidden) == isHidden.Value); + } - if (isHidden.HasValue) - { - users = users.Where(i => i.HasPermission(PermissionKind.IsHidden) == isHidden.Value); - } + if (filterByDevice) + { + var deviceId = User.GetDeviceId(); - if (filterByDevice) + if (!string.IsNullOrWhiteSpace(deviceId)) { - var deviceId = User.GetDeviceId(); - - if (!string.IsNullOrWhiteSpace(deviceId)) - { - users = users.Where(i => _deviceManager.CanAccessDevice(i, deviceId)); - } + users = users.Where(i => _deviceManager.CanAccessDevice(i, deviceId)); } + } - if (filterByNetwork) + if (filterByNetwork) + { + if (!_networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp())) { - if (!_networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp())) - { - users = users.Where(i => i.HasPermission(PermissionKind.EnableRemoteAccess)); - } + users = users.Where(i => i.HasPermission(PermissionKind.EnableRemoteAccess)); } + } - var result = users - .OrderBy(u => u.Username) - .Select(i => _userManager.GetUserDto(i, HttpContext.GetNormalizedRemoteIp().ToString())); + var result = users + .OrderBy(u => u.Username) + .Select(i => _userManager.GetUserDto(i, HttpContext.GetNormalizedRemoteIp().ToString())); - return result; - } + return result; } } -- cgit v1.2.3