Merge branch 'temp8' of https://github.com/umbraco/Umbraco-CMS into temp8

This commit is contained in:
Niels Lyngsø
2019-01-31 12:58:21 +01:00
17 changed files with 111 additions and 60 deletions

View File

@@ -150,7 +150,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
urlHelper.Setup(provider => provider.GetUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlProviderMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Returns(UrlInfo.Url("/hello/world/1234"));
var membershipHelper = new MembershipHelper(new TestUmbracoContextAccessor(umbCtx), Mock.Of<MembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IUserService>(), Mock.Of<IPublicAccessService>(), null, Mock.Of<AppCaches>(), Mock.Of<ILogger>());
var membershipHelper = new MembershipHelper(new TestUmbracoContextAccessor(umbCtx), Mock.Of<MembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IUserService>(), Mock.Of<IPublicAccessService>(), Mock.Of<AppCaches>(), Mock.Of<ILogger>());
var umbHelper = new UmbracoHelper(umbCtx,
Mock.Of<IPublishedContent>(),

View File

@@ -65,7 +65,7 @@ namespace Umbraco.Tests.Testing.TestingTests
Mock.Of<ITagQuery>(),
Mock.Of<ICultureDictionary>(),
Mock.Of<IUmbracoComponentRenderer>(),
new MembershipHelper(new TestUmbracoContextAccessor(umbracoContext), Mock.Of<MembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IUserService>(), Mock.Of<IPublicAccessService>(), null, Mock.Of<AppCaches>(), Mock.Of<ILogger>()),
new MembershipHelper(new TestUmbracoContextAccessor(umbracoContext), Mock.Of<MembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IUserService>(), Mock.Of<IPublicAccessService>(), Mock.Of<AppCaches>(), Mock.Of<ILogger>()),
ServiceContext.CreatePartial());
Assert.Pass();
}

View File

@@ -213,7 +213,7 @@ namespace Umbraco.Tests.Testing
// web
Composition.RegisterUnique(_ => Umbraco.Web.Composing.Current.UmbracoContextAccessor);
Composition.RegisterUnique<PublishedRouter>();
Composition.RegisterUnique<IPublishedRouter, PublishedRouter>();
Composition.WithCollectionBuilder<ContentFinderCollectionBuilder>();
Composition.RegisterUnique<IContentLastChanceFinder, TestLastChanceFinder>();
Composition.RegisterUnique<IVariationContextAccessor, TestVariationContextAccessor>();

View File

@@ -132,7 +132,7 @@ namespace Umbraco.Tests.Web.Mvc
Mock.Of<ITagQuery>(),
Mock.Of<ICultureDictionary>(),
Mock.Of<IUmbracoComponentRenderer>(),
new MembershipHelper(new TestUmbracoContextAccessor(umbracoContext), Mock.Of<MembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IUserService>(), Mock.Of<IPublicAccessService>(), null, Mock.Of<AppCaches>(), Mock.Of<ILogger>()),
new MembershipHelper(new TestUmbracoContextAccessor(umbracoContext), Mock.Of<MembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IUserService>(), Mock.Of<IPublicAccessService>(), Mock.Of<AppCaches>(), Mock.Of<ILogger>()),
ServiceContext.CreatePartial());
var ctrl = new TestSurfaceController(umbracoContext, helper);

View File

@@ -11,7 +11,7 @@ namespace Umbraco.Web.Models.Mapping
internal class ContentUrlResolver : IValueResolver<IContent, ContentItemDisplay, UrlInfo[]>
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly PublishedRouter _publishedRouter;
private readonly IPublishedRouter _publishedRouter;
private readonly ILocalizationService _localizationService;
private readonly ILocalizedTextService _textService;
private readonly IContentService _contentService;
@@ -19,7 +19,7 @@ namespace Umbraco.Web.Models.Mapping
public ContentUrlResolver(
IUmbracoContextAccessor umbracoContextAccessor,
PublishedRouter publishedRouter,
IPublishedRouter publishedRouter,
ILocalizationService localizationService,
ILocalizedTextService textService,
IContentService contentService,

View File

@@ -33,8 +33,7 @@ namespace Umbraco.Web.Mvc
/// <param name="contentId"></param>
public EnsurePublishedContentRequestAttribute(UmbracoContext umbracoContext, int contentId)
{
if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext));
_umbracoContext = umbracoContext;
_umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
_contentId = contentId;
}
@@ -63,8 +62,7 @@ namespace Umbraco.Web.Mvc
/// <param name="dataTokenName"></param>
public EnsurePublishedContentRequestAttribute(UmbracoContext umbracoContext, string dataTokenName)
{
if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext));
_umbracoContext = umbracoContext;
_umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
_dataTokenName = dataTokenName;
}
@@ -74,7 +72,7 @@ namespace Umbraco.Web.Mvc
protected UmbracoContext UmbracoContext => _umbracoContext ?? (_umbracoContext = UmbracoContext.Current);
// TODO: try lazy property injection?
private PublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<PublishedRouter>();
private IPublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<IPublishedRouter>();
/// <summary>
/// Exposes an UmbracoHelper

View File

@@ -377,7 +377,7 @@ namespace Umbraco.Web.Mvc
if ((request.HasTemplate == false && Features.Disabled.DisableTemplates == false)
&& routeDef.HasHijackedRoute == false)
{
request.UpdateOnMissingTemplate(); // request will go 404
request.UpdateToNotFound(); // request will go 404
// HandleHttpResponseStatus returns a value indicating that the request should
// not be processed any further, eg because it has been redirect. then, exit.

View File

@@ -12,7 +12,7 @@ namespace Umbraco.Web.Mvc
public abstract class UmbracoVirtualNodeRouteHandler : IRouteHandler
{
// TODO: try lazy property injection?
private PublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<PublishedRouter>();
private IPublishedRouter PublishedRouter => Current.Factory.GetInstance<IPublishedRouter>();
/// <summary>
/// Returns the UmbracoContext for this route handler

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Web.Routing
{
/// <summary>
/// Routes requests.
/// </summary>
public interface IPublishedRouter
{
// TODO: consider this and RenderRouteHandler - move some code around?
/// <summary>
/// Creates a published request.
/// </summary>
/// <param name="umbracoContext">The current Umbraco context.</param>
/// <param name="uri">The (optional) request Uri.</param>
/// <returns>A published request.</returns>
PublishedRequest CreateRequest(UmbracoContext umbracoContext, Uri uri = null);
/// <summary>
/// Prepares a request for rendering.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>A value indicating whether the request was successfully prepared and can be rendered.</returns>
bool PrepareRequest(PublishedRequest request);
/// <summary>
/// Tries to route a request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>A value indicating whether the request can be routed to a document.</returns>
bool TryRouteRequest(PublishedRequest request);
/// <summary>
/// Gets a template.
/// </summary>
/// <param name="alias">The template alias</param>
/// <returns>The template.</returns>
ITemplate GetTemplate(string alias);
/// <summary>
/// Updates the request to "not found".
/// </summary>
/// <param name="request">The request.</param>
/// <remarks>
/// <para>This method is invoked when the pipeline decides it cannot render
/// the request, for whatever reason, and wants to force it to be re-routed
/// and rendered as if no document were found (404).</para>
/// </remarks>
void UpdateRequestToNotFound(PublishedRequest request);
}
}

View File

@@ -17,7 +17,7 @@ namespace Umbraco.Web.Routing
/// </summary>
public class PublishedRequest
{
private readonly PublishedRouter _publishedRouter;
private readonly IPublishedRouter _publishedRouter;
private bool _readonly; // after prepared
private bool _readonlyUri; // after preparing
@@ -35,7 +35,7 @@ namespace Umbraco.Web.Routing
/// <param name="publishedRouter">The published router.</param>
/// <param name="umbracoContext">The Umbraco context.</param>
/// <param name="uri">The request <c>Uri</c>.</param>
internal PublishedRequest(PublishedRouter publishedRouter, UmbracoContext umbracoContext, Uri uri = null)
internal PublishedRequest(IPublishedRouter publishedRouter, UmbracoContext umbracoContext, Uri uri = null)
{
UmbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
_publishedRouter = publishedRouter ?? throw new ArgumentNullException(nameof(publishedRouter));
@@ -291,11 +291,11 @@ namespace Umbraco.Web.Routing
/// </summary>
public bool HasTemplate => TemplateModel != null;
internal void UpdateOnMissingTemplate()
internal void UpdateToNotFound()
{
var __readonly = _readonly;
_readonly = false;
_publishedRouter.UpdateRequestOnMissingTemplate(this);
_publishedRouter.UpdateRequestToNotFound(this);
_readonly = __readonly;
}

View File

@@ -6,6 +6,7 @@ using System.Globalization;
using System.IO;
using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
@@ -18,8 +19,10 @@ using Umbraco.Web.Security;
namespace Umbraco.Web.Routing
{
// TODO: making sense to have an interface?
public class PublishedRouter
/// <summary>
/// Provides the default <see cref="IPublishedRouter"/> implementation.
/// </summary>
public class PublishedRouter : IPublishedRouter
{
private readonly IWebRoutingSection _webRoutingSection;
private readonly ContentFinderCollection _contentFinders;
@@ -47,15 +50,9 @@ namespace Umbraco.Web.Routing
_profilingLogger = proflog ?? throw new ArgumentNullException(nameof(proflog));
_variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
_logger = proflog;
GetRolesForLogin = s => Roles.Provider.GetRolesForUser(s);
}
// TODO: in 7.7 this is cached in the PublishedContentRequest, which ... makes little sense
// killing it entirely, if we need cache, just implement it properly !!
// this is all so weird
public Func<string, IEnumerable<string>> GetRolesForLogin { get; }
/// <inheritdoc />
public PublishedRequest CreateRequest(UmbracoContext umbracoContext, Uri uri = null)
{
return new PublishedRequest(this, umbracoContext, uri ?? umbracoContext.CleanedUmbracoUrl);
@@ -63,10 +60,8 @@ namespace Umbraco.Web.Routing
#region Request
/// <summary>
/// Tries to route the request.
/// </summary>
internal bool TryRouteRequest(PublishedRequest request)
/// <inheritdoc />
public bool TryRouteRequest(PublishedRequest request)
{
// disabled - is it going to change the routing?
//_pcr.OnPreparing();
@@ -96,12 +91,7 @@ namespace Umbraco.Web.Routing
_variationContextAccessor.VariationContext = new VariationContext(culture);
}
/// <summary>
/// Prepares the request.
/// </summary>
/// <returns>
/// Returns false if the request was not successfully prepared
/// </returns>
/// <inheritdoc />
public bool PrepareRequest(PublishedRequest request)
{
// note - at that point the original legacy module did something do handle IIS custom 404 errors
@@ -213,11 +203,8 @@ namespace Umbraco.Web.Routing
return true;
}
/// <summary>
/// Updates the request when there is no template to render the content.
/// </summary>
/// <remarks>This is called from Mvc when there's a document to render but no template.</remarks>
public void UpdateRequestOnMissingTemplate(PublishedRequest request)
/// <inheritdoc />
public void UpdateRequestToNotFound(PublishedRequest request)
{
// clear content
var content = request.PublishedContent;
@@ -386,11 +373,7 @@ namespace Umbraco.Web.Routing
#region Document and template
/// <summary>
/// Gets a template.
/// </summary>
/// <param name="alias">The template alias</param>
/// <returns>The template.</returns>
/// <inheritdoc />
public ITemplate GetTemplate(string alias)
{
return _services.FileService.GetTemplate(alias);
@@ -607,7 +590,7 @@ namespace Umbraco.Web.Routing
if (loginPageId != request.PublishedContent.Id)
request.PublishedContent = request.UmbracoContext.PublishedSnapshot.Content.GetById(loginPageId);
}
else if (_services.PublicAccessService.HasAccess(request.PublishedContent.Id, _services.ContentService, membershipHelper.CurrentUserName, GetRolesForLogin(membershipHelper.CurrentUserName)) == false)
else if (_services.PublicAccessService.HasAccess(request.PublishedContent.Id, _services.ContentService, membershipHelper.CurrentUserName, membershipHelper.GetCurrentUserRoles()) == false)
{
_logger.Debug<PublishedRouter>("EnsurePublishedContentAccess: Current member has not access, redirect to error page");
var errorPageId = publicAccessAttempt.Result.NoAccessNodeId;

View File

@@ -18,7 +18,7 @@ namespace Umbraco.Web.Routing
/// <para>Contains all the Urls that we can figure out (based upon domains, etc).</para>
/// </remarks>
public static IEnumerable<UrlInfo> GetContentUrls(this IContent content,
PublishedRouter publishedRouter,
IPublishedRouter publishedRouter,
UmbracoContext umbracoContext,
ILocalizationService localizationService,
ILocalizedTextService textService,
@@ -92,7 +92,7 @@ namespace Umbraco.Web.Routing
/// <returns></returns>
private static IEnumerable<UrlInfo> GetContentUrlsByCulture(IContent content,
IEnumerable<string> cultures,
PublishedRouter publishedRouter,
IPublishedRouter publishedRouter,
UmbracoContext umbracoContext,
IContentService contentService,
ILocalizedTextService textService,
@@ -161,7 +161,7 @@ namespace Umbraco.Web.Routing
return UrlInfo.Message(textService.Localize("content/parentCultureNotPublished", new[] {parent.Name}), culture);
}
private static bool DetectCollision(IContent content, string url, string culture, UmbracoContext umbracoContext, PublishedRouter publishedRouter, ILocalizedTextService textService, out UrlInfo urlInfo)
private static bool DetectCollision(IContent content, string url, string culture, UmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, out UrlInfo urlInfo)
{
// test for collisions on the 'main' url
var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute);

View File

@@ -178,7 +178,7 @@ namespace Umbraco.Web.Runtime
composition.RegisterAuto(typeof(UmbracoViewPage<>));
// register published router
composition.RegisterUnique<PublishedRouter>();
composition.RegisterUnique<IPublishedRouter, PublishedRouter>();
composition.Register(_ => Current.Configs.Settings().WebRouting);
// register preview SignalR hub

View File

@@ -31,7 +31,6 @@ namespace Umbraco.Web.Security
private readonly IMemberTypeService _memberTypeService;
private readonly IUserService _userService;
private readonly IPublicAccessService _publicAccessService;
private readonly PublishedRouter _publishedRouter;
private readonly AppCaches _appCaches;
private readonly ILogger _logger;
@@ -46,7 +45,6 @@ namespace Umbraco.Web.Security
IMemberTypeService memberTypeService,
IUserService userService,
IPublicAccessService publicAccessService,
PublishedRouter publishedRouter,
AppCaches appCaches,
ILogger logger
)
@@ -57,7 +55,6 @@ namespace Umbraco.Web.Security
_memberTypeService = memberTypeService;
_userService = userService;
_publicAccessService = publicAccessService;
_publishedRouter = publishedRouter;
_appCaches = appCaches;
_logger = logger;
@@ -116,7 +113,7 @@ namespace Umbraco.Web.Security
{
return UmbracoContext.PublishedRequest == null
? _publicAccessService.HasAccess(path, CurrentUserName, roleProvider.GetRolesForUser)
: _publicAccessService.HasAccess(path, CurrentUserName, _publishedRouter.GetRolesForLogin);
: _publicAccessService.HasAccess(path, CurrentUserName, GetUserRoles);
}
/// <summary>
@@ -514,6 +511,24 @@ namespace Umbraco.Web.Security
}
#endregion
/// <summary>
/// Gets the current user's roles.
/// </summary>
/// <remarks>Roles are cached per user name, at request level.</remarks>
public IEnumerable<string> GetCurrentUserRoles()
=> GetUserRoles(CurrentUserName);
/// <summary>
/// Gets a user's roles.
/// </summary>
/// <remarks>Roles are cached per user name, at request level.</remarks>
public IEnumerable<string> GetUserRoles(string userName)
{
// optimize by caching per-request (v7 cached per PublishedRequest, in PublishedRouter)
var key = "Umbraco.Web.Security.MembershipHelper__Roles__" + userName;
return _appCaches.RequestCache.GetCacheItem(key, () => Roles.Provider.GetRolesForUser(userName));
}
/// <summary>
/// Returns the login status model of the currently logged in member, if no member is logged in it returns null;
/// </summary>
@@ -618,7 +633,7 @@ namespace Umbraco.Web.Security
var provider = _membershipProvider;
string username;
if (provider.IsUmbracoMembershipProvider())
{
var member = GetCurrentPersistedMember();
@@ -626,7 +641,7 @@ namespace Umbraco.Web.Security
if (member == null)
return false;
username = member.Username;
// If types defined, check member is of one of those types
var allowTypesList = allowTypes as IList<string> ?? allowTypes.ToList();
if (allowTypesList.Any(allowType => allowType != string.Empty))

View File

@@ -36,7 +36,7 @@ namespace Umbraco.Web.Templates
}
private IFileService FileService => Current.Services.FileService; // TODO: inject
private PublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<PublishedRouter>(); // TODO: inject
private IPublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<IPublishedRouter>(); // TODO: inject
/// <summary>

View File

@@ -183,6 +183,7 @@
<Compile Include="Models\ContentEditing\MacroDisplay.cs" />
<Compile Include="Models\ContentEditing\MacroParameterDisplay.cs" />
<Compile Include="Models\TemplateQuery\QueryConditionExtensions.cs" />
<Compile Include="Routing\IPublishedRouter.cs" />
<Compile Include="Services\DashboardService.cs" />
<Compile Include="Services\IDashboardService.cs" />
<Compile Include="Models\Link.cs" />

View File

@@ -45,7 +45,7 @@ namespace Umbraco.Web
private readonly UrlProviderCollection _urlProviders;
private readonly IRuntimeState _runtime;
private readonly ILogger _logger;
private readonly PublishedRouter _publishedRouter;
private readonly IPublishedRouter _publishedRouter;
private readonly IVariationContextAccessor _variationContextAccessor;
public UmbracoInjectedModule(
@@ -56,7 +56,7 @@ namespace Umbraco.Web
UrlProviderCollection urlProviders,
IRuntimeState runtime,
ILogger logger,
PublishedRouter publishedRouter,
IPublishedRouter publishedRouter,
IVariationContextAccessor variationContextAccessor)
{
_combinedRouteCollection = new Lazy<RouteCollection>(CreateRouteCollection);