Merge branch 'netcore/feature/AB4919-untable-umbraco-context' into netcore/feature/move-files-after-umbraco-context-abstractions
# Conflicts: # src/Umbraco.Web/Security/WebSecurity.cs # src/Umbraco.Web/UmbracoContextFactory.cs
This commit is contained in:
@@ -137,7 +137,7 @@ namespace Umbraco.Core
|
||||
public static readonly string UmbracoMemberProviderName = "UmbracoMembershipProvider";
|
||||
|
||||
public static readonly string UmbracoRoleProviderName = "UmbracoRoleProvider";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Comments on a Member
|
||||
/// </summary>
|
||||
@@ -285,6 +285,7 @@ namespace Umbraco.Core
|
||||
|
||||
//TODO: return a list of built in types so we can use that to prevent deletion in the uI
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,8 +88,6 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
bool InPreviewMode { get; }
|
||||
|
||||
string PreviewToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url of a content identified by its identifier.
|
||||
/// </summary>
|
||||
|
||||
@@ -123,14 +123,6 @@ namespace Umbraco.Web.Routing
|
||||
/// should use the specified description. The description will or will not be used, in due time.</remarks>
|
||||
string ResponseStatusDescription { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <c>System.Web.HttpCacheability</c>
|
||||
/// </summary>
|
||||
// Note: we used to set a default value here but that would then be the default
|
||||
// for ALL requests, we shouldn't overwrite it though if people are using [OutputCache] for example
|
||||
// see: https://our.umbraco.com/forum/using-umbraco-and-getting-started/79715-output-cache-in-umbraco-752
|
||||
//HttpCacheability Cacheability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of Extensions to append to the Response.Cache object.
|
||||
/// </summary>
|
||||
|
||||
@@ -12,11 +12,6 @@ namespace Umbraco.Web.Routing
|
||||
/// </summary>
|
||||
UrlMode Mode { get; set; }
|
||||
|
||||
UrlMode GetMode(bool absolute);
|
||||
IPublishedContent GetDocument(int id);
|
||||
IPublishedContent GetDocument(Guid id);
|
||||
IPublishedContent GetMedia(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url of a published content.
|
||||
/// </summary>
|
||||
@@ -107,4 +102,4 @@ namespace Umbraco.Web.Routing
|
||||
/// </remarks>
|
||||
string GetMediaUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
@@ -11,41 +12,18 @@ namespace Umbraco.Web.Security
|
||||
/// <value>The current user.</value>
|
||||
IUser CurrentUser { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Logs a user in.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user Id</param>
|
||||
/// <returns>returns the number of seconds until their session times out</returns>
|
||||
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
|
||||
double PerformLogin(int userId);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current login for the currently logged in user
|
||||
/// </summary>
|
||||
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
|
||||
void ClearCurrentLogin();
|
||||
|
||||
/// <summary>
|
||||
/// Validates credentials for a back office user
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This uses ASP.NET Identity to perform the validation
|
||||
/// </remarks>
|
||||
bool ValidateBackOfficeCredentials(string username, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current user's id.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Attempt<int> GetUserId();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current user's unique session id - used to mitigate csrf attacks or any other reason to validate a request
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetSessionId();
|
||||
|
||||
/// <summary>
|
||||
/// Validates the currently logged in user and ensures they are not timed out
|
||||
/// </summary>
|
||||
@@ -75,14 +53,6 @@ namespace Umbraco.Web.Security
|
||||
/// <returns></returns>
|
||||
bool UserHasSectionAccess(string section, IUser user);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the specified user by username as access to the app
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
bool UserHasSectionAccess(string section, string username);
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a back office user is logged in
|
||||
/// </summary>
|
||||
|
||||
@@ -42,10 +42,6 @@ namespace Umbraco.Tests.TestHelpers
|
||||
// need to specify a custom callback for unit tests
|
||||
// AutoPublishedContentTypes generates properties automatically
|
||||
|
||||
var dataTypeService = new TestObjects.TestDataTypeService(
|
||||
new DataType(new VoidEditor(Mock.Of<ILogger>(), Mock.Of<IDataTypeService>(), Mock.Of<ILocalizationService>(),Mock.Of<ILocalizedTextService>(), Mock.Of<IShortStringHelper>())) { Id = 1 });
|
||||
|
||||
var factory = new PublishedContentTypeFactory(Mock.Of<IPublishedModelFactory>(), new PropertyValueConverterCollection(Array.Empty<IPropertyValueConverter>()), dataTypeService);
|
||||
var type = new AutoPublishedContentType(0, "anything", new PublishedPropertyType[] { });
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = alias => GetPublishedContentTypeByAlias(alias) ?? type;
|
||||
}
|
||||
|
||||
@@ -73,10 +73,9 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
#region GetUrl
|
||||
|
||||
public UrlMode GetMode(bool absolute) => absolute ? UrlMode.Absolute : Mode;
|
||||
public IPublishedContent GetDocument(int id) => _umbracoContext.Content.GetById(id);
|
||||
public IPublishedContent GetDocument(Guid id) => _umbracoContext.Content.GetById(id);
|
||||
public IPublishedContent GetMedia(Guid id) => _umbracoContext.Media.GetById(id);
|
||||
private IPublishedContent GetDocument(int id) => _umbracoContext.Content.GetById(id);
|
||||
private IPublishedContent GetDocument(Guid id) => _umbracoContext.Content.GetById(id);
|
||||
private IPublishedContent GetMedia(Guid id) => _umbracoContext.Media.GetById(id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url of a published content.
|
||||
|
||||
@@ -10,9 +10,7 @@ using Microsoft.Owin;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
using Umbraco.Web.Models.Identity;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Security
|
||||
{
|
||||
@@ -41,7 +39,7 @@ namespace Umbraco.Web.Security
|
||||
/// Gets the current user.
|
||||
/// </summary>
|
||||
/// <value>The current user.</value>
|
||||
public virtual IUser CurrentUser
|
||||
public IUser CurrentUser
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -78,12 +76,8 @@ namespace Umbraco.Web.Security
|
||||
protected BackOfficeUserManager<BackOfficeIdentityUser> UserManager
|
||||
=> _userManager ?? (_userManager = _httpContextAccessor.HttpContext.GetOwinContext().GetBackOfficeUserManager());
|
||||
|
||||
/// <summary>
|
||||
/// Logs a user in.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user Id</param>
|
||||
/// <returns>returns the number of seconds until their session times out</returns>
|
||||
public virtual double PerformLogin(int userId)
|
||||
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
|
||||
public double PerformLogin(int userId)
|
||||
{
|
||||
var owinCtx = _httpContextAccessor.HttpContext.GetOwinContext();
|
||||
//ensure it's done for owin too
|
||||
@@ -98,10 +92,8 @@ namespace Umbraco.Web.Security
|
||||
return TimeSpan.FromMinutes(_globalSettings.TimeOutInMinutes).TotalSeconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current login for the currently logged in user
|
||||
/// </summary>
|
||||
public virtual void ClearCurrentLogin()
|
||||
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
|
||||
public void ClearCurrentLogin()
|
||||
{
|
||||
_httpContextAccessor.HttpContext.UmbracoLogout();
|
||||
_httpContextAccessor.HttpContext.GetOwinContext().Authentication.SignOut(
|
||||
@@ -112,67 +104,26 @@ namespace Umbraco.Web.Security
|
||||
/// <summary>
|
||||
/// Renews the user's login ticket
|
||||
/// </summary>
|
||||
public virtual void RenewLoginTimeout()
|
||||
public void RenewLoginTimeout()
|
||||
{
|
||||
_httpContextAccessor.HttpContext.RenewUmbracoAuthTicket();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates credentials for a back office user
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This uses ASP.NET Identity to perform the validation
|
||||
/// </remarks>
|
||||
public virtual bool ValidateBackOfficeCredentials(string username, string password)
|
||||
{
|
||||
//find the user by username
|
||||
var user = UserManager.FindByNameAsync(username).Result;
|
||||
return user != null && UserManager.CheckPasswordAsync(user, password).Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the current user to see if they have access to the specified app
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
internal bool ValidateUserApp(string app)
|
||||
{
|
||||
//if it is empty, don't validate
|
||||
if (app.IsNullOrWhiteSpace())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return CurrentUser.AllowedSections.Any(uApp => uApp.InvariantEquals(app));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current user's id.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual Attempt<int> GetUserId()
|
||||
public Attempt<int> GetUserId()
|
||||
{
|
||||
var identity = _httpContextAccessor.HttpContext.GetCurrentIdentity(false);
|
||||
return identity == null ? Attempt.Fail<int>() : Attempt.Succeed(Convert.ToInt32(identity.Id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current user's unique session id - used to mitigate csrf attacks or any other reason to validate a request
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual string GetSessionId()
|
||||
{
|
||||
var identity = _httpContextAccessor.HttpContext.GetCurrentIdentity(false);
|
||||
return identity?.SessionId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the currently logged in user and ensures they are not timed out
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool ValidateCurrentUser()
|
||||
public bool ValidateCurrentUser()
|
||||
{
|
||||
return ValidateCurrentUser(false, true) == ValidateRequestAttempt.Success;
|
||||
}
|
||||
@@ -183,7 +134,7 @@ namespace Umbraco.Web.Security
|
||||
/// <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>
|
||||
public virtual ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true)
|
||||
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
|
||||
@@ -235,27 +186,11 @@ namespace Umbraco.Web.Security
|
||||
/// <param name="section"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool UserHasSectionAccess(string section, IUser user)
|
||||
public bool UserHasSectionAccess(string section, IUser user)
|
||||
{
|
||||
return user.HasSectionAccess(section);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the specified user by username as access to the app
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
public bool UserHasSectionAccess(string section, string username)
|
||||
{
|
||||
var user = _userService.GetByUsername(username);
|
||||
if (user == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return user.HasSectionAccess(section);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a back office user is logged in
|
||||
/// </summary>
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Umbraco.Web.Templates
|
||||
|
||||
//First, save all of the items locally that we know are used in the chain of execution, we'll need to restore these
|
||||
//after this page has rendered.
|
||||
SaveExistingItems(out var oldPublishedRequest, out var oldAltTemplate);
|
||||
SaveExistingItems(out var oldPublishedRequest);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Web.Templates
|
||||
finally
|
||||
{
|
||||
//restore items on context objects to continuing rendering the parent template
|
||||
RestoreItems(oldPublishedRequest, oldAltTemplate);
|
||||
RestoreItems(oldPublishedRequest);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -175,28 +175,25 @@ namespace Umbraco.Web.Templates
|
||||
private void SetNewItemsOnContextObjects(IPublishedRequest request)
|
||||
{
|
||||
//now, set the new ones for this page execution
|
||||
_httpContextAccessor.HttpContext.Items[Core.Constants.Conventions.Url.AltTemplate] = null;
|
||||
_umbracoContextAccessor.UmbracoContext.PublishedRequest = request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save all items that we know are used for rendering execution to variables so we can restore after rendering
|
||||
/// </summary>
|
||||
private void SaveExistingItems(out IPublishedRequest oldPublishedRequest, out object oldAltTemplate)
|
||||
private void SaveExistingItems(out IPublishedRequest oldPublishedRequest)
|
||||
{
|
||||
//Many objects require that these legacy items are in the http context items... before we render this template we need to first
|
||||
//save the values in them so that we can re-set them after we render so the rest of the execution works as per normal
|
||||
oldPublishedRequest = _umbracoContextAccessor.UmbracoContext.PublishedRequest;
|
||||
oldAltTemplate = _httpContextAccessor.HttpContext.Items[Core.Constants.Conventions.Url.AltTemplate];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores all items back to their context's to continue normal page rendering execution
|
||||
/// </summary>
|
||||
private void RestoreItems(IPublishedRequest oldPublishedRequest, object oldAltTemplate)
|
||||
private void RestoreItems(IPublishedRequest oldPublishedRequest)
|
||||
{
|
||||
_umbracoContextAccessor.UmbracoContext.PublishedRequest = oldPublishedRequest;
|
||||
_httpContextAccessor.HttpContext.Items[Core.Constants.Conventions.Url.AltTemplate] = oldAltTemplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,7 +678,6 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Reference.map</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UmbracoAuthorizedHttpHandler.cs" />
|
||||
<Compile Include="UmbracoHttpHandler.cs" />
|
||||
<Compile Include="UmbracoWebService.cs">
|
||||
<SubType>Component</SubType>
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
using System;
|
||||
using System.Security;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
public abstract class UmbracoAuthorizedHttpHandler : UmbracoHttpHandler
|
||||
{
|
||||
protected UmbracoAuthorizedHttpHandler()
|
||||
{
|
||||
}
|
||||
|
||||
protected UmbracoAuthorizedHttpHandler(IUmbracoContextAccessor umbracoContextAccessor, UmbracoHelper umbracoHelper, ServiceContext service, IProfilingLogger plogger) : base(umbracoContextAccessor, umbracoHelper, service, plogger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the umbraco context id is valid
|
||||
/// </summary>
|
||||
/// <param name="currentUmbracoUserContextId"></param>
|
||||
/// <returns></returns>
|
||||
protected bool ValidateUserContextId(string currentUmbracoUserContextId)
|
||||
{
|
||||
return Security.ValidateCurrentUser();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the username/password credentials are valid
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
protected bool ValidateCredentials(string username, string password)
|
||||
{
|
||||
return Security.ValidateBackOfficeCredentials(username, password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the user for access to a certain application
|
||||
/// </summary>
|
||||
/// <param name="app">The application alias.</param>
|
||||
/// <param name="throwExceptions">true if an exception should be thrown if authorization fails</param>
|
||||
/// <returns></returns>
|
||||
protected bool AuthorizeRequest(string app, bool throwExceptions = false)
|
||||
{
|
||||
//ensure we have a valid user first!
|
||||
if (!AuthorizeRequest(throwExceptions)) return false;
|
||||
|
||||
//if it is empty, don't validate
|
||||
if (app.IsNullOrWhiteSpace())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var hasAccess = UserHasAppAccess(app, Security.CurrentUser);
|
||||
if (!hasAccess && throwExceptions)
|
||||
throw new SecurityException("The user does not have access to the required application");
|
||||
return hasAccess;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the specified user as access to the app
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
protected bool UserHasAppAccess(string app, IUser user)
|
||||
{
|
||||
return Security.UserHasSectionAccess(app, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the specified user by username as access to the app
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
protected bool UserHasAppAccess(string app, string username)
|
||||
{
|
||||
return Security.UserHasSectionAccess(app, username);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if there is a valid logged in user and that ssl is enabled if required
|
||||
/// </summary>
|
||||
/// <param name="throwExceptions">true if an exception should be thrown if authorization fails</param>
|
||||
/// <returns></returns>
|
||||
protected bool AuthorizeRequest(bool throwExceptions = false)
|
||||
{
|
||||
var result = Security.AuthorizeRequest(throwExceptions);
|
||||
return result == ValidateRequestAttempt.Success;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user