Cleans up IBackofficeSecurity, ensures authn for the AuthenticationController/BackOfficeController

This commit is contained in:
Shannon
2020-12-02 14:28:16 +11:00
parent 372674abde
commit 0846fc5690
13 changed files with 82 additions and 122 deletions

View File

@@ -12,6 +12,10 @@ namespace Umbraco.Core.BackOffice
[Serializable] [Serializable]
public class UmbracoBackOfficeIdentity : ClaimsIdentity public class UmbracoBackOfficeIdentity : ClaimsIdentity
{ {
// TODO: Ideally we remove this class and only deal with ClaimsIdentity as a best practice. All things relevant to our own
// identity are part of claims. This class would essentially become extension methods on a ClaimsIdentity for resolving
// values from it.
public static bool FromClaimsIdentity(ClaimsIdentity identity, out UmbracoBackOfficeIdentity backOfficeIdentity) public static bool FromClaimsIdentity(ClaimsIdentity identity, out UmbracoBackOfficeIdentity backOfficeIdentity)
{ {
//validate that all claims exist //validate that all claims exist

View File

@@ -9,41 +9,38 @@ namespace Umbraco.Core.Security
/// <summary> /// <summary>
/// Gets the current user. /// Gets the current user.
/// </summary> /// </summary>
/// <value>The current user.</value> /// <returns>The current user that has been authenticated for the request.</returns>
/// <remarks>If authentication hasn't taken place this will be null.</remarks>
// TODO: This is used a lot but most of it can be refactored to not use this at all since the IUser instance isn't
// needed in most cases. Where an IUser is required this could be an ext method on the ClaimsIdentity/ClaimsPrincipal that passes in
// an IUserService, like HttpContext.User.GetUmbracoUser(_userService);
// This one isn't as easy to remove as the others below.
IUser CurrentUser { get; } IUser CurrentUser { get; }
/// <summary> /// <summary>
/// Gets the current user's id. /// Gets the current user's id.
/// </summary> /// </summary>
/// <returns></returns> /// <returns>The current user's Id that has been authenticated for the request.</returns>
/// <remarks>If authentication hasn't taken place this will be unsuccessful.</remarks>
// TODO: This should just be an extension method on ClaimsIdentity
Attempt<int> GetUserId(); Attempt<int> GetUserId();
/// <summary>
/// Validates the currently logged in user and ensures they are not timed out
/// </summary>
/// <returns></returns>
bool ValidateCurrentUser();
/// <summary>
/// Validates the current user assigned to the request and ensures the stored user data is valid
/// </summary>
/// <param name="throwExceptions">set to true if you want exceptions to be thrown if failed</param>
/// <param name="requiresApproval">If true requires that the user is approved to be validated</param>
/// <returns></returns>
ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true);
/// <summary> /// <summary>
/// Checks if the specified user as access to the app /// Checks if the specified user as access to the app
/// </summary> /// </summary>
/// <param name="section"></param> /// <param name="section"></param>
/// <param name="user"></param> /// <param name="user"></param>
/// <returns></returns> /// <returns></returns>
/// <remarks>If authentication hasn't taken place this will be unsuccessful.</remarks>
// TODO: Should be part of IBackOfficeUserManager
bool UserHasSectionAccess(string section, IUser user); bool UserHasSectionAccess(string section, IUser user);
/// <summary> /// <summary>
/// Ensures that a back office user is logged in /// Ensures that a back office user is logged in
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
/// <remarks>This does not force authentication, that must be done before calls to this are made.</remarks>
// TODO: Should be removed, this should not be necessary
bool IsAuthenticated(); bool IsAuthenticated();
} }
} }

View File

@@ -1,14 +0,0 @@
namespace Umbraco.Core.Security
{
public enum ValidateRequestAttempt
{
Success = 0,
FailedNoPrivileges = 100,
//FailedTimedOut,
FailedNoContextId = 101,
FailedNoSsl = 102
}
}

View File

@@ -120,8 +120,6 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
.Returns(mockUser.Object); .Returns(mockUser.Object);
//mock Validate //mock Validate
backofficeSecurity.Setup(x => x.ValidateCurrentUser())
.Returns(() => true);
backofficeSecurity.Setup(x => x.UserHasSectionAccess(It.IsAny<string>(), It.IsAny<IUser>())) backofficeSecurity.Setup(x => x.UserHasSectionAccess(It.IsAny<string>(), It.IsAny<IUser>()))
.Returns(() => true); .Returns(() => true);

View File

@@ -22,18 +22,17 @@ namespace Umbraco.Web.BackOffice.Authorization
protected override Task<bool> IsAuthorized(AuthorizationHandlerContext context, BackOfficeRequirement requirement) protected override Task<bool> IsAuthorized(AuthorizationHandlerContext context, BackOfficeRequirement requirement)
{ {
try // if not configured (install or upgrade) then we can continue
// otherwise we need to ensure that a user is logged in
switch (_runtimeState.Level)
{ {
// if not configured (install or upgrade) then we can continue case RuntimeLevel.Install:
// otherwise we need to ensure that a user is logged in case RuntimeLevel.Upgrade:
var isAuth = _runtimeState.Level == RuntimeLevel.Install return Task.FromResult(true);
|| _runtimeState.Level == RuntimeLevel.Upgrade default:
|| _backOfficeSecurity.BackOfficeSecurity?.ValidateCurrentUser(false, requirement.RequireApproval) == ValidateRequestAttempt.Success; var userApprovalSucceeded = !requirement.RequireApproval || (_backOfficeSecurity.BackOfficeSecurity.CurrentUser?.IsApproved ?? false);
return Task.FromResult(isAuth); return Task.FromResult(userApprovalSucceeded);
}
catch (Exception)
{
return Task.FromResult(false);
} }
} }

View File

@@ -51,6 +51,9 @@ namespace Umbraco.Web.BackOffice.Controllers
[IsBackOffice] [IsBackOffice]
public class AuthenticationController : UmbracoApiControllerBase public class AuthenticationController : UmbracoApiControllerBase
{ {
// NOTE: Each action must either be explicitly authorized or explicitly [AllowAnonymous], the latter is optional because
// this controller itself doesn't require authz but it's more clear what the intention is.
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
private readonly IBackOfficeUserManager _userManager; private readonly IBackOfficeUserManager _userManager;
private readonly IBackOfficeSignInManager _signInManager; private readonly IBackOfficeSignInManager _signInManager;
@@ -211,6 +214,7 @@ namespace Umbraco.Web.BackOffice.Controllers
} }
[HttpGet] [HttpGet]
[AllowAnonymous]
public async Task<double> GetRemainingTimeoutSeconds() public async Task<double> GetRemainingTimeoutSeconds()
{ {
// force authentication to occur since this is not an authorized endpoint // force authentication to occur since this is not an authorized endpoint
@@ -242,6 +246,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[AllowAnonymous]
public async Task<bool> IsAuthenticated() public async Task<bool> IsAuthenticated()
{ {
// force authentication to occur since this is not an authorized endpoint // force authentication to occur since this is not an authorized endpoint
@@ -399,6 +404,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[SetAngularAntiForgeryTokens] [SetAngularAntiForgeryTokens]
[AllowAnonymous]
public async Task<ActionResult<IEnumerable<string>>> Get2FAProviders() public async Task<ActionResult<IEnumerable<string>>> Get2FAProviders()
{ {
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
@@ -413,6 +419,7 @@ namespace Umbraco.Web.BackOffice.Controllers
} }
[SetAngularAntiForgeryTokens] [SetAngularAntiForgeryTokens]
[AllowAnonymous]
public async Task<IActionResult> PostSend2FACode([FromBody] string provider) public async Task<IActionResult> PostSend2FACode([FromBody] string provider)
{ {
if (provider.IsNullOrWhiteSpace()) if (provider.IsNullOrWhiteSpace())
@@ -458,6 +465,7 @@ namespace Umbraco.Web.BackOffice.Controllers
} }
[SetAngularAntiForgeryTokens] [SetAngularAntiForgeryTokens]
[AllowAnonymous]
public async Task<ActionResult<UserDetail>> PostVerify2FACode(Verify2FACodeModel model) public async Task<ActionResult<UserDetail>> PostVerify2FACode(Verify2FACodeModel model)
{ {
if (ModelState.IsValid == false) if (ModelState.IsValid == false)
@@ -495,6 +503,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[SetAngularAntiForgeryTokens] [SetAngularAntiForgeryTokens]
[AllowAnonymous]
public async Task<IActionResult> PostSetPassword(SetPasswordModel model) public async Task<IActionResult> PostSetPassword(SetPasswordModel model)
{ {
var identityUser = await _userManager.FindByIdAsync(model.UserId.ToString()); var identityUser = await _userManager.FindByIdAsync(model.UserId.ToString());
@@ -559,6 +568,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[ValidateAngularAntiForgeryToken] [ValidateAngularAntiForgeryToken]
[AllowAnonymous]
public async Task<IActionResult> PostLogout() public async Task<IActionResult> PostLogout()
{ {
// force authentication to occur since this is not an authorized endpoint // force authentication to occur since this is not an authorized endpoint

View File

@@ -36,15 +36,19 @@ using Umbraco.Web.BackOffice.Security;
using Umbraco.Web.Common.ActionsResults; using Umbraco.Web.Common.ActionsResults;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Umbraco.Web.Common.Authorization; using Umbraco.Web.Common.Authorization;
using Microsoft.AspNetCore.Authentication;
namespace Umbraco.Web.BackOffice.Controllers namespace Umbraco.Web.BackOffice.Controllers
{ {
[DisableBrowserCache] [DisableBrowserCache]
//[UmbracoRequireHttps] //TODO Reintroduce [UmbracoRequireHttps]
[PluginController(Constants.Web.Mvc.BackOfficeArea)] [PluginController(Constants.Web.Mvc.BackOfficeArea)]
[IsBackOffice] [IsBackOffice]
public class BackOfficeController : UmbracoController public class BackOfficeController : UmbracoController
{ {
// NOTE: Each action must either be explicitly authorized or explicitly [AllowAnonymous], the latter is optional because
// this controller itself doesn't require authz but it's more clear what the intention is.
private readonly IBackOfficeUserManager _userManager; private readonly IBackOfficeUserManager _userManager;
private readonly IRuntimeMinifier _runtimeMinifier; private readonly IRuntimeMinifier _runtimeMinifier;
private readonly GlobalSettings _globalSettings; private readonly GlobalSettings _globalSettings;
@@ -96,23 +100,31 @@ namespace Umbraco.Web.BackOffice.Controllers
} }
[HttpGet] [HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Default() public async Task<IActionResult> Default()
{ {
// force authentication to occur since this is not an authorized endpoint
var result = await HttpContext.AuthenticateAsync(Constants.Security.BackOfficeAuthenticationType);
var viewPath = Path.Combine(_globalSettings.UmbracoPath , Constants.Web.Mvc.BackOfficeArea, nameof(Default) + ".cshtml") var viewPath = Path.Combine(_globalSettings.UmbracoPath , Constants.Web.Mvc.BackOfficeArea, nameof(Default) + ".cshtml")
.Replace("\\", "/"); // convert to forward slashes since it's a virtual path .Replace("\\", "/"); // convert to forward slashes since it's a virtual path
return await RenderDefaultOrProcessExternalLoginAsync( return await RenderDefaultOrProcessExternalLoginAsync(
result,
() => View(viewPath), () => View(viewPath),
() => View(viewPath)); () => View(viewPath));
} }
[HttpGet] [HttpGet]
[AllowAnonymous]
public async Task<IActionResult> VerifyInvite(string invite) public async Task<IActionResult> VerifyInvite(string invite)
{ {
var authenticate = await HttpContext.AuthenticateAsync(Constants.Security.BackOfficeAuthenticationType);
//if you are hitting VerifyInvite, you're already signed in as a different user, and the token is invalid //if you are hitting VerifyInvite, you're already signed in as a different user, and the token is invalid
//you'll exit on one of the return RedirectToAction(nameof(Default)) but you're still logged in so you just get //you'll exit on one of the return RedirectToAction(nameof(Default)) but you're still logged in so you just get
//dumped at the default admin view with no detail //dumped at the default admin view with no detail
if (_backofficeSecurityAccessor.BackOfficeSecurity.IsAuthenticated()) if (authenticate.Succeeded)
{ {
await _signInManager.SignOutAsync(); await _signInManager.SignOutAsync();
} }
@@ -174,10 +186,16 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[StatusCodeResult(System.Net.HttpStatusCode.ServiceUnavailable)] [StatusCodeResult(System.Net.HttpStatusCode.ServiceUnavailable)]
[AllowAnonymous]
public async Task<IActionResult> AuthorizeUpgrade() public async Task<IActionResult> AuthorizeUpgrade()
{ {
var viewPath = Path.Combine(_globalSettings.UmbracoPath, Umbraco.Core.Constants.Web.Mvc.BackOfficeArea, nameof(AuthorizeUpgrade) + ".cshtml"); // force authentication to occur since this is not an authorized endpoint
var result = await HttpContext.AuthenticateAsync(Constants.Security.BackOfficeAuthenticationType);
var viewPath = Path.Combine(_globalSettings.UmbracoPath, Constants.Web.Mvc.BackOfficeArea, nameof(AuthorizeUpgrade) + ".cshtml");
return await RenderDefaultOrProcessExternalLoginAsync( return await RenderDefaultOrProcessExternalLoginAsync(
result,
//The default view to render when there is no external login info or errors //The default view to render when there is no external login info or errors
() => View(viewPath), () => View(viewPath),
//The IActionResult to perform if external login is successful //The IActionResult to perform if external login is successful
@@ -190,6 +208,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <returns></returns> /// <returns></returns>
[MinifyJavaScriptResult(Order = 0)] [MinifyJavaScriptResult(Order = 0)]
[HttpGet] [HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Application() public async Task<IActionResult> Application()
{ {
var result = await _runtimeMinifier.GetScriptForLoadingBackOfficeAsync(_globalSettings, _hostingEnvironment); var result = await _runtimeMinifier.GetScriptForLoadingBackOfficeAsync(_globalSettings, _hostingEnvironment);
@@ -203,6 +222,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <param name="culture"></param> /// <param name="culture"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[AllowAnonymous]
public Dictionary<string, Dictionary<string, string>> LocalizedText(string culture = null) public Dictionary<string, Dictionary<string, string>> LocalizedText(string culture = null)
{ {
var isAuthenticated = _backofficeSecurityAccessor.BackOfficeSecurity.IsAuthenticated(); var isAuthenticated = _backofficeSecurityAccessor.BackOfficeSecurity.IsAuthenticated();
@@ -265,6 +285,7 @@ namespace Umbraco.Web.BackOffice.Controllers
} }
[HttpPost] [HttpPost]
[AllowAnonymous]
public ActionResult ExternalLogin(string provider, string redirectUrl = null) public ActionResult ExternalLogin(string provider, string redirectUrl = null)
{ {
if (redirectUrl == null) if (redirectUrl == null)
@@ -297,6 +318,7 @@ namespace Umbraco.Web.BackOffice.Controllers
} }
[HttpGet] [HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ValidatePasswordResetCode([Bind(Prefix = "u")]int userId, [Bind(Prefix = "r")]string resetCode) public async Task<IActionResult> ValidatePasswordResetCode([Bind(Prefix = "u")]int userId, [Bind(Prefix = "r")]string resetCode)
{ {
var user = await _userManager.FindByIdAsync(userId.ToString()); var user = await _userManager.FindByIdAsync(userId.ToString());
@@ -362,6 +384,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task<IActionResult> RenderDefaultOrProcessExternalLoginAsync( private async Task<IActionResult> RenderDefaultOrProcessExternalLoginAsync(
AuthenticateResult authenticateResult,
Func<IActionResult> defaultResponse, Func<IActionResult> defaultResponse,
Func<IActionResult> externalSignInResponse) Func<IActionResult> externalSignInResponse)
{ {
@@ -382,7 +405,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (loginInfo == null || loginInfo.Principal == null) if (loginInfo == null || loginInfo.Principal == null)
{ {
// if the user is not logged in, check if there's any auto login redirects specified // if the user is not logged in, check if there's any auto login redirects specified
if (!_backofficeSecurityAccessor.BackOfficeSecurity.ValidateCurrentUser()) if (!authenticateResult.Succeeded)
{ {
var oauthRedirectAuthProvider = _externalLogins.GetAutoLoginProvider(); var oauthRedirectAuthProvider = _externalLogins.GetAutoLoginProvider();
if (!oauthRedirectAuthProvider.IsNullOrWhiteSpace()) if (!oauthRedirectAuthProvider.IsNullOrWhiteSpace())

View File

@@ -13,38 +13,32 @@ namespace Umbraco.Web.Common.Install
/// </summary> /// </summary>
public class InstallAuthorizeAttribute : TypeFilterAttribute public class InstallAuthorizeAttribute : TypeFilterAttribute
{ {
// NOTE: This doesn't need to be an authz policy, it's only used for the installer
public InstallAuthorizeAttribute() : base(typeof(InstallAuthorizeFilter)) public InstallAuthorizeAttribute() : base(typeof(InstallAuthorizeFilter))
{ {
} }
private class InstallAuthorizeFilter : IAuthorizationFilter private class InstallAuthorizeFilter : IAuthorizationFilter
{ {
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IRuntimeState _runtimeState; private readonly IRuntimeState _runtimeState;
private readonly ILogger<InstallAuthorizeFilter> _logger; private readonly ILogger<InstallAuthorizeFilter> _logger;
public InstallAuthorizeFilter( public InstallAuthorizeFilter(
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IRuntimeState runtimeState, IRuntimeState runtimeState,
ILogger<InstallAuthorizeFilter> logger) ILogger<InstallAuthorizeFilter> logger)
{ {
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
_runtimeState = runtimeState; _runtimeState = runtimeState;
_logger = logger; _logger = logger;
} }
public void OnAuthorization(AuthorizationFilterContext authorizationFilterContext) public void OnAuthorization(AuthorizationFilterContext authorizationFilterContext)
{ {
if (!IsAllowed()) if (!IsAllowed(authorizationFilterContext))
{ {
authorizationFilterContext.Result = new ForbidResult(); authorizationFilterContext.Result = new ForbidResult();
} }
} }
private bool IsAllowed() private bool IsAllowed(AuthorizationFilterContext authorizationFilterContext)
{ {
try try
{ {
@@ -52,7 +46,7 @@ namespace Umbraco.Web.Common.Install
// otherwise we need to ensure that a user is logged in // otherwise we need to ensure that a user is logged in
return _runtimeState.Level == RuntimeLevel.Install return _runtimeState.Level == RuntimeLevel.Install
|| _runtimeState.Level == RuntimeLevel.Upgrade || _runtimeState.Level == RuntimeLevel.Upgrade
|| (_backOfficeSecurityAccessor?.BackOfficeSecurity?.ValidateCurrentUser() ?? false); || (authorizationFilterContext.HttpContext.User?.Identity?.IsAuthenticated ?? false);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -15,6 +15,7 @@ using Umbraco.Web.Install;
using Umbraco.Web.Security; using Umbraco.Web.Security;
using Umbraco.Core.Configuration.Models; using Umbraco.Core.Configuration.Models;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authentication;
namespace Umbraco.Web.Common.Install namespace Umbraco.Web.Common.Install
{ {
@@ -73,13 +74,11 @@ namespace Umbraco.Web.Common.Install
// Update ClientDependency version and delete its temp directories to make sure we get fresh caches // Update ClientDependency version and delete its temp directories to make sure we get fresh caches
_runtimeMinifier.Reset(); _runtimeMinifier.Reset();
var result = _backofficeSecurityAccessor.BackOfficeSecurity.ValidateCurrentUser(false); var authResult = await HttpContext.AuthenticateAsync(Core.Constants.Security.BackOfficeAuthenticationType);
switch (result) if (!authResult.Succeeded)
{ {
case ValidateRequestAttempt.FailedNoPrivileges: return Redirect(_globalSettings.UmbracoPath + "/AuthorizeUpgrade?redir=" + Request.GetEncodedUrl());
case ValidateRequestAttempt.FailedNoContextId:
return Redirect(_globalSettings.UmbracoPath + "/AuthorizeUpgrade?redir=" + Request.GetEncodedUrl());
} }
} }

View File

@@ -72,41 +72,5 @@ namespace Umbraco.Web.Common.Security
return user.HasSectionAccess(section); return user.HasSectionAccess(section);
} }
/// <inheritdoc />
public bool ValidateCurrentUser()
{
return ValidateCurrentUser(false, true) == ValidateRequestAttempt.Success;
}
/// <inheritdoc />
public ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true)
{
//This will first check if the current user is already authenticated - which should be the case in nearly all circumstances
// since the authentication happens in the Module, that authentication also checks the ticket expiry. We don't
// need to check it a second time because that requires another decryption phase and nothing can tamper with it during the request.
if (IsAuthenticated() == false)
{
//There is no user
if (throwExceptions) throw new InvalidOperationException("The user has no umbraco contextid - try logging in");
return ValidateRequestAttempt.FailedNoContextId;
}
var user = CurrentUser;
// TODO: All of this is done as part of identity/backofficesigninmanager
// Check for console access
if (user == null || (requiresApproval && user.IsApproved == false) || (user.IsLockedOut && RequestIsInUmbracoApplication(_httpContextAccessor, _globalSettings, _hostingEnvironment)))
{
if (throwExceptions) throw new ArgumentException("You have no privileges to the umbraco console. Please contact your administrator");
return ValidateRequestAttempt.FailedNoPrivileges;
}
return ValidateRequestAttempt.Success;
}
private static bool RequestIsInUmbracoApplication(IHttpContextAccessor httpContextAccessor, GlobalSettings globalSettings, IHostingEnvironment hostingEnvironment)
{
return httpContextAccessor.GetRequiredHttpContext().Request.Path.ToString().IndexOf(hostingEnvironment.ToAbsolute(globalSettings.UmbracoPath), StringComparison.InvariantCultureIgnoreCase) > -1;
}
} }
} }

View File

@@ -76,7 +76,7 @@ namespace Umbraco.Web.Mvc
// otherwise we need to ensure that a user is logged in // otherwise we need to ensure that a user is logged in
return RuntimeState.Level == RuntimeLevel.Install return RuntimeState.Level == RuntimeLevel.Install
|| RuntimeState.Level == RuntimeLevel.Upgrade || RuntimeState.Level == RuntimeLevel.Upgrade
|| BackOfficeSecurity.ValidateCurrentUser(); || (httpContext.User?.Identity?.IsAuthenticated ?? false);
} }
catch (Exception) catch (Exception)
{ {

View File

@@ -11,11 +11,6 @@ namespace Umbraco.Web.Security
{ {
public IUser CurrentUser => throw new NotImplementedException(); public IUser CurrentUser => throw new NotImplementedException();
public ValidateRequestAttempt AuthorizeRequest(bool throwExceptions = false)
{
throw new NotImplementedException();
}
public Attempt<int> GetUserId() public Attempt<int> GetUserId()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@@ -31,14 +26,5 @@ namespace Umbraco.Web.Security
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool ValidateCurrentUser()
{
throw new NotImplementedException();
}
public ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true)
{
throw new NotImplementedException();
}
} }
} }

View File

@@ -53,17 +53,17 @@ namespace Umbraco.Web.WebApi
return true; return true;
} }
try // if not configured (install or upgrade) then we can continue
// otherwise we need to ensure that a user is logged in
switch (_runtimeState.Level)
{ {
// if not configured (install or upgrade) then we can continue case RuntimeLevel.Install:
// otherwise we need to ensure that a user is logged in case RuntimeLevel.Upgrade:
return RuntimeState.Level == RuntimeLevel.Install return true;
|| RuntimeState.Level == RuntimeLevel.Upgrade default:
|| BackOfficeSecurity.ValidateCurrentUser(false, _requireApproval) == ValidateRequestAttempt.Success; var userApprovalSucceeded = !_requireApproval || (BackOfficeSecurity.CurrentUser?.IsApproved ?? false);
} return userApprovalSucceeded;
catch (Exception)
{
return false;
} }
} }
} }