Merge pull request #7750 from umbraco/netcore/feature/untangle-membership

Netcore: Untangle membership helper and trim Web even more
This commit is contained in:
Bjarke Berg
2020-03-04 08:20:25 +01:00
committed by GitHub
54 changed files with 441 additions and 552 deletions

View File

@@ -7,4 +7,5 @@ namespace Umbraco.Core.Cookie
void SetCookieValue(string cookieName, string value);
bool HasCookie(string cookieName);
}
}

View File

@@ -0,0 +1,13 @@
using System;
using Umbraco.Web.Routing;
namespace Umbraco.Core.Request
{
public interface IRequestAccessor
{
string GetRequestValue(string name);
string GetQueryStringValue(string culture);
event EventHandler<UmbracoRequestEventArgs> EndRequest;
event EventHandler<RoutableAttemptEventArgs> RouteAttempt;
}
}

View File

@@ -4,6 +4,7 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Models.PublishedContent;
using System.Globalization;
using Umbraco.Core.Request;
namespace Umbraco.Web.Routing
{
@@ -16,14 +17,14 @@ namespace Umbraco.Web.Routing
public class ContentFinderByIdPath : IContentFinder
{
private readonly ILogger _logger;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IRequestAccessor _requestAccessor;
private readonly IWebRoutingSection _webRoutingSection;
public ContentFinderByIdPath(IWebRoutingSection webRoutingSection, ILogger logger, IHttpContextAccessor httpContextAccessor)
public ContentFinderByIdPath(IWebRoutingSection webRoutingSection, ILogger logger, IRequestAccessor requestAccessor)
{
_webRoutingSection = webRoutingSection ?? throw new System.ArgumentNullException(nameof(webRoutingSection));
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
_httpContextAccessor = httpContextAccessor;
_requestAccessor = requestAccessor;
}
/// <summary>
@@ -56,12 +57,14 @@ namespace Umbraco.Web.Routing
if (node != null)
{
var httpContext = _httpContextAccessor.GetRequiredHttpContext();
var cultureFromQuerystring = _requestAccessor.GetQueryStringValue("culture");
//if we have a node, check if we have a culture in the query string
if (httpContext.Request.QueryString.ContainsKey("culture"))
if (!string.IsNullOrEmpty(cultureFromQuerystring))
{
//we're assuming it will match a culture, if an invalid one is passed in, an exception will throw (there is no TryGetCultureInfo method), i think this is ok though
frequest.Culture = CultureInfo.GetCultureInfo(httpContext.Request.QueryString["culture"]);
frequest.Culture = CultureInfo.GetCultureInfo(cultureFromQuerystring);
}
frequest.PublishedContent = node;

View File

@@ -1,4 +1,6 @@
namespace Umbraco.Web.Routing
using Umbraco.Core.Request;
namespace Umbraco.Web.Routing
{
/// <summary>
/// This looks up a document by checking for the umbPageId of a request/query string
@@ -9,17 +11,17 @@
/// </remarks>
public class ContentFinderByPageIdQuery : IContentFinder
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IRequestAccessor _requestAccessor;
public ContentFinderByPageIdQuery(IHttpContextAccessor httpContextAccessor)
public ContentFinderByPageIdQuery(IRequestAccessor requestAccessor)
{
_httpContextAccessor = httpContextAccessor;
_requestAccessor = requestAccessor;
}
public bool TryFindContent(IPublishedRequest frequest)
{
int pageId;
if (int.TryParse(_httpContextAccessor.GetRequiredHttpContext().Request["umbPageID"], out pageId))
if (int.TryParse(_requestAccessor.GetRequestValue("umbPageID"), out pageId))
{
var doc = frequest.UmbracoContext.Content.GetById(pageId);

View File

@@ -4,13 +4,12 @@ using System.Threading;
using System.Globalization;
using System.IO;
using Umbraco.Core;
using Umbraco.Web.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Request;
using Umbraco.Core.Services;
using Umbraco.Web.Macros;
using Umbraco.Web.Security;
namespace Umbraco.Web.Routing
@@ -23,13 +22,17 @@ namespace Umbraco.Web.Routing
private readonly IWebRoutingSection _webRoutingSection;
private readonly ContentFinderCollection _contentFinders;
private readonly IContentLastChanceFinder _contentLastChanceFinder;
private readonly ServiceContext _services;
private readonly IProfilingLogger _profilingLogger;
private readonly IVariationContextAccessor _variationContextAccessor;
private readonly ILogger _logger;
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IPublishedUrlProvider _publishedUrlProvider;
private readonly IRequestAccessor _requestAccessor;
private readonly IPublishedValueFallback _publishedValueFallback;
private readonly IPublicAccessChecker _publicAccessChecker;
private readonly IFileService _fileService;
private readonly IContentTypeService _contentTypeService;
private readonly IPublicAccessService _publicAccessService;
/// <summary>
/// Initializes a new instance of the <see cref="PublishedRouter"/> class.
@@ -39,22 +42,30 @@ namespace Umbraco.Web.Routing
ContentFinderCollection contentFinders,
IContentLastChanceFinder contentLastChanceFinder,
IVariationContextAccessor variationContextAccessor,
ServiceContext services,
IProfilingLogger proflog,
IUmbracoSettingsSection umbracoSettingsSection,
IHttpContextAccessor httpContextAccessor,
IPublishedUrlProvider publishedUrlProvider)
IPublishedUrlProvider publishedUrlProvider,
IRequestAccessor requestAccessor,
IPublishedValueFallback publishedValueFallback,
IPublicAccessChecker publicAccessChecker,
IFileService fileService,
IContentTypeService contentTypeService,
IPublicAccessService publicAccessService)
{
_webRoutingSection = webRoutingSection ?? throw new ArgumentNullException(nameof(webRoutingSection));
_contentFinders = contentFinders ?? throw new ArgumentNullException(nameof(contentFinders));
_contentLastChanceFinder = contentLastChanceFinder ?? throw new ArgumentNullException(nameof(contentLastChanceFinder));
_services = services ?? throw new ArgumentNullException(nameof(services));
_profilingLogger = proflog ?? throw new ArgumentNullException(nameof(proflog));
_variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
_logger = proflog;
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
_httpContextAccessor = httpContextAccessor;
_publishedUrlProvider = publishedUrlProvider;
_requestAccessor = requestAccessor;
_publishedValueFallback = publishedValueFallback;
_publicAccessChecker = publicAccessChecker;
_fileService = fileService;
_contentTypeService = contentTypeService;
_publicAccessService = publicAccessService;
}
/// <inheritdoc />
@@ -358,7 +369,7 @@ namespace Umbraco.Web.Routing
/// <inheritdoc />
public ITemplate GetTemplate(string alias)
{
return _services.FileService.GetTemplate(alias);
return _fileService.GetTemplate(alias);
}
/// <summary>
@@ -498,7 +509,7 @@ namespace Umbraco.Web.Routing
var redirect = false;
var valid = false;
IPublishedContent internalRedirectNode = null;
var internalRedirectId = request.PublishedContent.Value(Constants.Conventions.Content.InternalRedirectId, defaultValue: -1);
var internalRedirectId = request.PublishedContent.Value(_publishedValueFallback, Constants.Conventions.Content.InternalRedirectId, defaultValue: -1);
if (internalRedirectId > 0)
{
@@ -508,7 +519,7 @@ namespace Umbraco.Web.Routing
}
else
{
var udiInternalRedirectId = request.PublishedContent.Value<GuidUdi>(Constants.Conventions.Content.InternalRedirectId);
var udiInternalRedirectId = request.PublishedContent.Value<GuidUdi>(_publishedValueFallback, Constants.Conventions.Content.InternalRedirectId);
if (udiInternalRedirectId != null)
{
// try and get the redirect node from a UDI Guid
@@ -555,58 +566,34 @@ namespace Umbraco.Web.Routing
var path = request.PublishedContent.Path;
var publicAccessAttempt = _services.PublicAccessService.IsProtected(path);
var publicAccessAttempt = _publicAccessService.IsProtected(path);
if (publicAccessAttempt)
{
_logger.Debug<PublishedRouter>("EnsurePublishedContentAccess: Page is protected, check for access");
var membershipHelper = Current.Factory.GetInstance<MembershipHelper>();
if (membershipHelper.IsLoggedIn() == false)
var status = _publicAccessChecker.HasMemberAccessToContent(request.PublishedContent.Id);
switch (status)
{
_logger.Debug<PublishedRouter>("EnsurePublishedContentAccess: Not logged in, redirect to login page");
var loginPageId = publicAccessAttempt.Result.LoginNodeId;
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, membershipHelper.GetCurrentUserRoles()) == false)
{
_logger.Debug<PublishedRouter>("EnsurePublishedContentAccess: Current member has not access, redirect to error page");
var errorPageId = publicAccessAttempt.Result.NoAccessNodeId;
if (errorPageId != request.PublishedContent.Id)
request.PublishedContent = request.UmbracoContext.PublishedSnapshot.Content.GetById(errorPageId);
}
else
{
// grab the current member
var member = membershipHelper.GetCurrentMember();
// if the member has the "approved" and/or "locked out" properties, make sure they're correctly set before allowing access
var memberIsActive = true;
if (member != null)
{
if (member.HasProperty(Constants.Conventions.Member.IsApproved) == false)
memberIsActive = member.Value<bool>(Constants.Conventions.Member.IsApproved);
if (member.HasProperty(Constants.Conventions.Member.IsLockedOut) == false)
memberIsActive = member.Value<bool>(Constants.Conventions.Member.IsLockedOut) == false;
}
if (memberIsActive == false)
{
_logger.Debug<PublishedRouter>(
"Current member is either unapproved or locked out, redirect to error page");
var errorPageId = publicAccessAttempt.Result.NoAccessNodeId;
if (errorPageId != request.PublishedContent.Id)
request.PublishedContent =
request.UmbracoContext.PublishedSnapshot.Content.GetById(errorPageId);
}
else
{
case PublicAccessStatus.NotLoggedIn:
_logger.Debug<PublishedRouter>("EnsurePublishedContentAccess: Not logged in, redirect to login page");
SetPublishedContentAsOtherPage(request, publicAccessAttempt.Result.LoginNodeId);
break;
case PublicAccessStatus.AccessDenied:
_logger.Debug<PublishedRouter>("EnsurePublishedContentAccess: Current member has not access, redirect to error page");
SetPublishedContentAsOtherPage(request, publicAccessAttempt.Result.NoAccessNodeId);
break;
case PublicAccessStatus.LockedOut:
_logger.Debug<PublishedRouter>("Current member is locked out, redirect to error page");
SetPublishedContentAsOtherPage(request, publicAccessAttempt.Result.NoAccessNodeId);
break;
case PublicAccessStatus.NotApproved:
_logger.Debug<PublishedRouter>("Current member is unapproved, redirect to error page");
SetPublishedContentAsOtherPage(request, publicAccessAttempt.Result.NoAccessNodeId);
break;
case PublicAccessStatus.AccessAccepted:
_logger.Debug<PublishedRouter>("Current member has access");
}
break;
}
}
else
@@ -615,6 +602,12 @@ namespace Umbraco.Web.Routing
}
}
private static void SetPublishedContentAsOtherPage(IPublishedRequest request, int errorPageId)
{
if (errorPageId != request.PublishedContent.Id)
request.PublishedContent = request.UmbracoContext.PublishedSnapshot.Content.GetById(errorPageId);
}
/// <summary>
/// Finds a template for the current node, if any.
/// </summary>
@@ -637,7 +630,7 @@ namespace Umbraco.Web.Routing
var useAltTemplate = request.IsInitialPublishedContent
|| (_webRoutingSection.InternalRedirectPreservesTemplate && request.IsInternalRedirectPublishedContent);
var altTemplate = useAltTemplate
? _httpContextAccessor.GetRequiredHttpContext().Request[Constants.Conventions.Url.AltTemplate]
? _requestAccessor.GetRequestValue(Constants.Conventions.Url.AltTemplate)
: null;
if (string.IsNullOrWhiteSpace(altTemplate))
@@ -674,10 +667,15 @@ namespace Umbraco.Web.Routing
_logger.Debug<PublishedRouter>("FindTemplate: Look for alternative template alias={AltTemplate}", altTemplate);
// IsAllowedTemplate deals both with DisableAlternativeTemplates and ValidateAlternativeTemplates settings
if (request.PublishedContent.IsAllowedTemplate(altTemplate))
if (request.PublishedContent.IsAllowedTemplate(
_fileService,
_contentTypeService,
_umbracoSettingsSection.WebRouting.DisableAlternativeTemplates,
_umbracoSettingsSection.WebRouting.ValidateAlternativeTemplates,
altTemplate))
{
// allowed, use
var template = _services.FileService.GetTemplate(altTemplate);
var template = _fileService.GetTemplate(altTemplate);
if (template != null)
{
@@ -731,7 +729,7 @@ namespace Umbraco.Web.Routing
if (templateId == null)
throw new InvalidOperationException("The template is not set, the page cannot render.");
var template = _services.FileService.GetTemplate(templateId.Value);
var template = _fileService.GetTemplate(templateId.Value);
if (template == null)
throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render.");
_logger.Debug<PublishedRouter>("GetTemplateModel: Got template id={TemplateId} alias={TemplateAlias}", template.Id, template.Alias);
@@ -750,7 +748,7 @@ namespace Umbraco.Web.Routing
if (request.PublishedContent.HasProperty(Constants.Conventions.Content.Redirect) == false)
return;
var redirectId = request.PublishedContent.Value(Constants.Conventions.Content.Redirect, defaultValue: -1);
var redirectId = request.PublishedContent.Value(_publishedValueFallback, Constants.Conventions.Content.Redirect, defaultValue: -1);
var redirectUrl = "#";
if (redirectId > 0)
{
@@ -759,7 +757,7 @@ namespace Umbraco.Web.Routing
else
{
// might be a UDI instead of an int Id
var redirectUdi = request.PublishedContent.Value<GuidUdi>(Constants.Conventions.Content.Redirect);
var redirectUdi = request.PublishedContent.Value<GuidUdi>(_publishedValueFallback, Constants.Conventions.Content.Redirect);
if (redirectUdi != null)
redirectUrl = _publishedUrlProvider.GetUrl(redirectUdi.Guid);
}

View File

@@ -0,0 +1,7 @@
namespace Umbraco.Core.Security
{
public interface IMemberUserKeyProvider
{
object GetMemberProviderUserKey();
}
}

View File

@@ -0,0 +1,7 @@
namespace Umbraco.Web.Security
{
public interface IPublicAccessChecker
{
PublicAccessStatus HasMemberAccessToContent(int publishedContentId);
}
}

View File

@@ -0,0 +1,11 @@
namespace Umbraco.Web.Security
{
public enum PublicAccessStatus
{
NotLoggedIn,
AccessDenied,
NotApproved,
LockedOut,
AccessAccepted
}
}

View File

@@ -0,0 +1,8 @@
namespace Umbraco.Core.Session
{
public interface ISessionManager
{
object GetSessionValue(string sessionName);
void SetSessionValue(string sessionName, object value);
}
}

View File

@@ -3,8 +3,10 @@ namespace Umbraco.Core.Sync
/// <summary>
/// An <see cref="IServerMessenger"/> implementation that works by storing messages in the database.
/// </summary>
public interface IBatchedDatabaseServerMessenger : IServerMessenger
public interface IBatchedDatabaseServerMessenger : IDatabaseServerMessenger
{
void FlushBatch();
DatabaseServerMessengerOptions Options { get; }
void Startup();
}
}

View File

@@ -0,0 +1,7 @@
namespace Umbraco.Core.Sync
{
public interface IDatabaseServerMessenger: IServerMessenger
{
void Sync();
}
}

View File

@@ -1,21 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Sync;
using Umbraco.Web.Routing;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Scoping;
using Umbraco.Web.Composing;
using System.ComponentModel;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Request;
namespace Umbraco.Web
{
@@ -29,19 +25,30 @@ namespace Umbraco.Web
{
private readonly IUmbracoDatabaseFactory _databaseFactory;
private readonly IRequestCache _requestCache;
private readonly IRequestAccessor _requestAccessor;
public BatchedDatabaseServerMessenger(
IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, DatabaseServerMessengerOptions options, IHostingEnvironment hostingEnvironment, CacheRefresherCollection cacheRefreshers, IRequestCache requestCache)
IRuntimeState runtime,
IUmbracoDatabaseFactory databaseFactory,
IScopeProvider scopeProvider,
ISqlContext sqlContext,
IProfilingLogger proflog,
DatabaseServerMessengerOptions options,
IHostingEnvironment hostingEnvironment,
CacheRefresherCollection cacheRefreshers,
IRequestCache requestCache,
IRequestAccessor requestAccessor)
: base(runtime, scopeProvider, sqlContext, proflog, true, options, hostingEnvironment, cacheRefreshers)
{
_databaseFactory = databaseFactory;
_requestCache = requestCache;
_requestAccessor = requestAccessor;
}
// invoked by DatabaseServerRegistrarAndMessengerComponent
internal void Startup()
public void Startup()
{
UmbracoModule.EndRequest += UmbracoModule_EndRequest;
_requestAccessor.EndRequest += UmbracoModule_EndRequest;
if (_databaseFactory.CanConnect == false)
{
@@ -104,7 +111,7 @@ namespace Umbraco.Web
protected ICollection<RefreshInstructionEnvelope> GetBatch(bool create)
{
var key = typeof (BatchedDatabaseServerMessenger).Name;
var key = nameof(BatchedDatabaseServerMessenger);
if (!_requestCache.IsAvailable) return null;

View File

@@ -4,6 +4,7 @@ using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
using Umbraco.Core.Request;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Changes;
using Umbraco.Core.Sync;
@@ -82,7 +83,7 @@ namespace Umbraco.Web.Compose
{
private object _locker = new object();
private readonly DatabaseServerRegistrar _registrar;
private readonly BatchedDatabaseServerMessenger _messenger;
private readonly IBatchedDatabaseServerMessenger _messenger;
private readonly IRuntimeState _runtime;
private readonly ILogger _logger;
private readonly IServerRegistrationService _registrationService;
@@ -91,13 +92,23 @@ namespace Umbraco.Web.Compose
private bool _started;
private IBackgroundTask[] _tasks;
private IndexRebuilder _indexRebuilder;
private readonly IRequestAccessor _requestAccessor;
public DatabaseServerRegistrarAndMessengerComponent(IRuntimeState runtime, IServerRegistrar serverRegistrar, IServerMessenger serverMessenger, IServerRegistrationService registrationService, ILogger logger, IHostingEnvironment hostingEnvironment, IndexRebuilder indexRebuilder)
public DatabaseServerRegistrarAndMessengerComponent(
IRuntimeState runtime,
IServerRegistrar serverRegistrar,
IServerMessenger serverMessenger,
IServerRegistrationService registrationService,
ILogger logger,
IHostingEnvironment hostingEnvironment,
IndexRebuilder indexRebuilder,
IRequestAccessor requestAccessor)
{
_runtime = runtime;
_logger = logger;
_registrationService = registrationService;
_indexRebuilder = indexRebuilder;
_requestAccessor = requestAccessor;
// create task runner for DatabaseServerRegistrar
_registrar = serverRegistrar as DatabaseServerRegistrar;
@@ -108,7 +119,7 @@ namespace Umbraco.Web.Compose
}
// create task runner for BatchedDatabaseServerMessenger
_messenger = serverMessenger as BatchedDatabaseServerMessenger;
_messenger = serverMessenger as IBatchedDatabaseServerMessenger;
if (_messenger != null)
{
_processTaskRunner = new BackgroundTaskRunner<IBackgroundTask>("ServerInstProcess",
@@ -120,7 +131,7 @@ namespace Umbraco.Web.Compose
{
//We will start the whole process when a successful request is made
if (_registrar != null || _messenger != null)
UmbracoModule.RouteAttempt += RegisterBackgroundTasksOnce;
_requestAccessor.RouteAttempt += RegisterBackgroundTasksOnce;
// must come last, as it references some _variables
_messenger?.Startup();
@@ -137,7 +148,7 @@ namespace Umbraco.Web.Compose
/// <remarks>
/// We require this because:
/// - ApplicationContext.UmbracoApplicationUrl is initialized by UmbracoModule in BeginRequest
/// - RegisterServer is called on UmbracoModule.RouteAttempt which is triggered in ProcessRequest
/// - RegisterServer is called on _requestAccessor.RouteAttempt which is triggered in ProcessRequest
/// we are safe, UmbracoApplicationUrl has been initialized
/// </remarks>
private void RegisterBackgroundTasksOnce(object sender, RoutableAttemptEventArgs e)
@@ -146,7 +157,7 @@ namespace Umbraco.Web.Compose
{
case EnsureRoutableOutcome.IsRoutable:
case EnsureRoutableOutcome.NotDocumentRequest:
UmbracoModule.RouteAttempt -= RegisterBackgroundTasksOnce;
_requestAccessor.RouteAttempt -= RegisterBackgroundTasksOnce;
RegisterBackgroundTasks();
break;
}
@@ -196,11 +207,11 @@ namespace Umbraco.Web.Compose
private class InstructionProcessTask : RecurringTaskBase
{
private readonly DatabaseServerMessenger _messenger;
private readonly IDatabaseServerMessenger _messenger;
private readonly ILogger _logger;
public InstructionProcessTask(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
DatabaseServerMessenger messenger, ILogger logger)
IDatabaseServerMessenger messenger, ILogger logger)
: base(runner, delayMilliseconds, periodMilliseconds)
{
_messenger = messenger;

View File

@@ -2,7 +2,6 @@
using Umbraco.Core.Cookie;
using Umbraco.Core.Migrations;
namespace Umbraco.Web.Migrations.PostMigrations
{
/// <summary>

View File

@@ -6,6 +6,7 @@ using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
using Umbraco.Web.PublishedCache;
@@ -26,12 +27,14 @@ namespace Umbraco.Web.Routing
private readonly IUmbracoSettingsSection _umbracoSettings;
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
private readonly IRedirectUrlService _redirectUrlService;
private readonly IVariationContextAccessor _variationContextAccessor;
public RedirectTrackingComponent(IUmbracoSettingsSection umbracoSettings, IPublishedSnapshotAccessor publishedSnapshotAccessor, IRedirectUrlService redirectUrlService)
public RedirectTrackingComponent(IUmbracoSettingsSection umbracoSettings, IPublishedSnapshotAccessor publishedSnapshotAccessor, IRedirectUrlService redirectUrlService, IVariationContextAccessor variationContextAccessor)
{
_umbracoSettings = umbracoSettings;
_publishedSnapshotAccessor = publishedSnapshotAccessor;
_redirectUrlService = redirectUrlService;
_variationContextAccessor = variationContextAccessor;
}
public void Initialize()
@@ -99,12 +102,12 @@ namespace Umbraco.Web.Routing
{
var contentCache = _publishedSnapshotAccessor.PublishedSnapshot.Content;
var entityContent = contentCache.GetById(entity.Id);
if (entityContent == null) return;
if (entityContent == null) return;
// get the default affected cultures by going up the tree until we find the first culture variant entity (default to no cultures)
// get the default affected cultures by going up the tree until we find the first culture variant entity (default to no cultures)
var defaultCultures = entityContent.AncestorsOrSelf()?.FirstOrDefault(a => a.Cultures.Any())?.Cultures.Keys.ToArray()
?? new[] { (string)null };
foreach (var x in entityContent.DescendantsOrSelf())
foreach (var x in entityContent.DescendantsOrSelf(_variationContextAccessor))
{
// if this entity defines specific cultures, use those instead of the default ones
var cultures = x.Cultures.Any() ? x.Cultures.Keys : defaultCultures;

View File

@@ -9,6 +9,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Request;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
@@ -37,6 +38,7 @@ namespace Umbraco.Web.Scheduling
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
private readonly IIOHelper _ioHelper;
private readonly IServerMessenger _serverMessenger;
private readonly IRequestAccessor _requestAccessor;
private BackgroundTaskRunner<IBackgroundTask> _keepAliveRunner;
private BackgroundTaskRunner<IBackgroundTask> _publishingRunner;
@@ -54,7 +56,7 @@ namespace Umbraco.Web.Scheduling
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
IScopeProvider scopeProvider, IUmbracoContextFactory umbracoContextFactory, IProfilingLogger logger,
IHostingEnvironment hostingEnvironment, IHealthChecks healthChecksConfig,
IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, IServerMessenger serverMessenger)
IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, IServerMessenger serverMessenger, IRequestAccessor requestAccessor)
{
_runtime = runtime;
_contentService = contentService;
@@ -70,6 +72,7 @@ namespace Umbraco.Web.Scheduling
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
_ioHelper = ioHelper;
_serverMessenger = serverMessenger;
_requestAccessor = requestAccessor;
}
public void Initialize()
@@ -83,7 +86,7 @@ namespace Umbraco.Web.Scheduling
_healthCheckRunner = new BackgroundTaskRunner<IBackgroundTask>("HealthCheckNotifier", _logger, _hostingEnvironment);
// we will start the whole process when a successful request is made
UmbracoModule.RouteAttempt += RegisterBackgroundTasksOnce;
_requestAccessor.RouteAttempt += RegisterBackgroundTasksOnce;
}
public void Terminate()
@@ -97,7 +100,7 @@ namespace Umbraco.Web.Scheduling
{
case EnsureRoutableOutcome.IsRoutable:
case EnsureRoutableOutcome.NotDocumentRequest:
UmbracoModule.RouteAttempt -= RegisterBackgroundTasksOnce;
_requestAccessor.RouteAttempt -= RegisterBackgroundTasksOnce;
RegisterBackgroundTasks();
break;
}

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Core.Sync
// but only processes instructions coming from remote servers,
// thus ensuring that instructions run only once
//
public class DatabaseServerMessenger : ServerMessengerBase
public class DatabaseServerMessenger : ServerMessengerBase, IDatabaseServerMessenger
{
private readonly IRuntimeState _runtime;
private readonly ManualResetEvent _syncIdle;
@@ -126,10 +126,6 @@ namespace Umbraco.Core.Sync
const int weight = 10;
//TODO Why do we have interface if we expect to be exact type!!!?
// if (!(_runtime is RuntimeState runtime))
// throw new NotSupportedException($"Unsupported IRuntimeState implementation {_runtime.GetType().FullName}, expecting {typeof(RuntimeState).FullName}.");
var registered = _runtime.MainDom.Register(
() =>
{

View File

@@ -4,7 +4,6 @@ using System.Linq;
using Newtonsoft.Json;
using Umbraco.Composing;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Sync

View File

@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Web;
using Moq;
@@ -20,14 +21,17 @@ namespace Umbraco.Tests.Cache
public class DeepCloneAppCacheTests : RuntimeAppCacheTests
{
private DeepCloneAppCache _provider;
private ObjectCacheAppCache _memberCache;
protected override int GetTotalItemCount => HttpRuntime.Cache.Count;
protected override int GetTotalItemCount => _memberCache.MemoryCache.Count();
public override void Setup()
{
base.Setup();
var typeFinder = new TypeFinder(Mock.Of<ILogger>());
_provider = new DeepCloneAppCache(new WebCachingAppCache(HttpRuntime.Cache, typeFinder));
_memberCache = new ObjectCacheAppCache(typeFinder);
_provider = new DeepCloneAppCache(_memberCache);
}
internal override IAppCache AppCache => _provider;

View File

@@ -1,55 +0,0 @@
using System;
using System.Diagnostics;
using System.Web;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Web.Cache;
namespace Umbraco.Tests.Cache
{
[TestFixture]
public class WebCachingAppCacheTests : RuntimeAppCacheTests
{
private WebCachingAppCache _appCache;
protected override int GetTotalItemCount => HttpRuntime.Cache.Count;
public override void Setup()
{
base.Setup();
var typeFinder = new TypeFinder(Mock.Of<ILogger>());
_appCache = new WebCachingAppCache(HttpRuntime.Cache, typeFinder);
}
internal override IAppCache AppCache => _appCache;
internal override IAppPolicyCache AppPolicyCache => _appCache;
[Test]
public void DoesNotCacheExceptions()
{
string value;
Assert.Throws<Exception>(() => { value = (string)_appCache.Get("key", () => GetValue(1)); });
Assert.Throws<Exception>(() => { value = (string)_appCache.Get("key", () => GetValue(2)); });
// does not throw
value = (string)_appCache.Get("key", () => GetValue(3));
Assert.AreEqual("succ3", value);
// cache
value = (string)_appCache.Get("key", () => GetValue(4));
Assert.AreEqual("succ3", value);
}
private static string GetValue(int i)
{
Debug.Print("get" + i);
if (i < 3)
throw new Exception("fail");
return "succ" + i;
}
}
}

View File

@@ -1,10 +1,8 @@
using Moq;
using NUnit.Framework;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Request;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
namespace Umbraco.Tests.Routing
@@ -20,7 +18,7 @@ namespace Umbraco.Tests.Routing
var umbracoContext = GetUmbracoContext(urlAsString);
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
var lookup = new ContentFinderByIdPath(Factory.GetInstance<IUmbracoSettingsSection>().WebRouting, Logger, HttpContextAccessor);
var lookup = new ContentFinderByIdPath(Factory.GetInstance<IUmbracoSettingsSection>().WebRouting, Logger, Factory.GetInstance<IRequestAccessor>());
var result = lookup.TryFindContent(frequest);

View File

@@ -1,5 +1,6 @@
using Moq;
using NUnit.Framework;
using Umbraco.Core.Request;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
@@ -20,15 +21,10 @@ namespace Umbraco.Tests.Routing
var httpContext = GetHttpContextFactory(urlAsString).HttpContext;
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
mockHttpContextAccessor.Setup(x => x.HttpContext).Returns(httpContext);
var lookup = new ContentFinderByPageIdQuery(mockHttpContextAccessor.Object);
var mockRequestAccessor = new Mock<IRequestAccessor>();
mockRequestAccessor.Setup(x => x.GetRequestValue("umbPageID")).Returns(httpContext.Request.QueryString["umbPageID"]);
//we need to manually stub the return output of HttpContext.Request["umbPageId"]
var requestMock = Mock.Get(httpContext.Request);
requestMock.Setup(x => x["umbPageID"])
.Returns(httpContext.Request.QueryString["umbPageID"]);
var lookup = new ContentFinderByPageIdQuery(mockRequestAccessor.Object);
var result = lookup.TryFindContent(frequest);

View File

@@ -49,8 +49,8 @@ namespace Umbraco.Tests.Routing
public class TestRuntime : WebRuntime
{
public TestRuntime(UmbracoApplicationBase umbracoApplication, Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
: base(umbracoApplication, configs, umbracoVersion, ioHelper, Mock.Of<ILogger>(), Mock.Of<IProfiler>(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom)
public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
: base(configs, umbracoVersion, ioHelper, Mock.Of<ILogger>(), Mock.Of<IProfiler>(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom)
{
}

View File

@@ -10,7 +10,9 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Request;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
using Umbraco.Core.Strings;
using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers.Stubs;
@@ -19,6 +21,7 @@ using Umbraco.Web;
using Umbraco.Web.Composing;
using Umbraco.Web.Models.PublishedContent;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
namespace Umbraco.Tests.TestHelpers
{
@@ -97,12 +100,16 @@ namespace Umbraco.Tests.TestHelpers
contentFinders ?? new ContentFinderCollection(Enumerable.Empty<IContentFinder>()),
new TestLastChanceFinder(),
new TestVariationContextAccessor(),
container?.TryGetInstance<ServiceContext>() ?? ServiceContext.CreatePartial(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()),
container?.TryGetInstance<IUmbracoSettingsSection>() ?? Current.Factory.GetInstance<IUmbracoSettingsSection>(),
Mock.Of<IHttpContextAccessor>(),
Mock.Of<IPublishedUrlProvider>()
);
Mock.Of<IPublishedUrlProvider>(),
Mock.Of<IRequestAccessor>(),
container?.GetInstance<IPublishedValueFallback>() ?? Current.Factory.GetInstance<IPublishedValueFallback>(),
container?.GetInstance<IPublicAccessChecker>()?? Current.Factory.GetInstance<IPublicAccessChecker>(),
container?.GetInstance<IFileService>()?? Current.Factory.GetInstance<IFileService>(),
container?.GetInstance<IContentTypeService>() ?? Current.Factory.GetInstance<IContentTypeService>(),
container?.GetInstance<IPublicAccessService>() ?? Current.Factory.GetInstance<IPublicAccessService>()
);
}
}
}

View File

@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Web.Routing;
using System.Web.Security;
using System.Xml.Linq;
using Examine;
using Moq;
@@ -51,12 +52,15 @@ using Umbraco.Web.Templates;
using Umbraco.Web.PropertyEditors;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Identity;
using Umbraco.Core.Request;
using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Net;
using Umbraco.Tests.LegacyXmlPublishedCache;
using Umbraco.Web.AspNet;
using Umbraco.Web.Install;
using Umbraco.Web.Security;
using Umbraco.Web.Security.Providers;
using Umbraco.Web.Trees;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Tests.Testing
@@ -203,6 +207,18 @@ namespace Umbraco.Tests.Testing
Composition.RegisterUnique(ipResolver);
Composition.RegisterUnique<IPasswordHasher, AspNetPasswordHasher>();
Composition.RegisterUnique(TestHelper.ShortStringHelper);
Composition.RegisterUnique<IRequestAccessor, AspNetRequestAccessor>();
Composition.RegisterUnique<IPublicAccessChecker, PublicAccessChecker>();
var memberService = Mock.Of<IMemberService>();
var memberTypeService = Mock.Of<IMemberTypeService>();
var membershipProvider = new MembersMembershipProvider(memberService, memberTypeService, Mock.Of<IUmbracoVersion>(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver());
var membershipHelper = new MembershipHelper(Mock.Of<IHttpContextAccessor>(), Mock.Of<IPublishedMemberCache>(), membershipProvider, Mock.Of<RoleProvider>(), memberService, memberTypeService, Mock.Of<IPublicAccessService>(), AppCaches.Disabled, logger, ShortStringHelper, Mock.Of<IEntityService>());
Composition.RegisterUnique(membershipHelper);
TestObjects = new TestObjects(register);

View File

@@ -322,7 +322,6 @@
<Compile Include="Cache\ObjectAppCacheTests.cs" />
<Compile Include="Cache\AppCacheTests.cs" />
<Compile Include="Cache\HttpRequestAppCacheTests.cs" />
<Compile Include="Cache\WebCachingAppCacheTests.cs" />
<Compile Include="Cache\RuntimeAppCacheTests.cs" />
<Compile Include="Configurations\UmbracoSettings\ContentElementDefaultTests.cs" />
<Compile Include="Configurations\UmbracoSettings\ContentElementTests.cs" />

View File

@@ -1,38 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<processing preserveExifMetaData="true" fixGamma="false" interceptAllRequests="false" allowCacheBuster="true">
<plugins>
<plugin name="Gamma" type="ImageProcessor.Web.Processors.Gamma, ImageProcessor.Web" />
<plugin name="Gamma" type="ImageProcessor.Web.Processors.Gamma, ImageProcessor.Web" />
<plugin name="Alpha" type="ImageProcessor.Web.Processors.Alpha, ImageProcessor.Web" /><plugin name="AutoRotate" type="ImageProcessor.Web.Processors.AutoRotate, ImageProcessor.Web" enabled="true" /><plugin name="Background" type="ImageProcessor.Web.Processors.Background, ImageProcessor.Web">
<settings>
<setting key="VirtualPath" value="~/images/imageprocessor/background/" />
@@ -63,4 +35,4 @@
<setting key="MaxHeight" value="5000" />
</settings>
</plugin><plugin name="Rotate" type="ImageProcessor.Web.Processors.Rotate, ImageProcessor.Web" /><plugin name="RotateBounded" type="ImageProcessor.Web.Processors.RotateBounded, ImageProcessor.Web" /><plugin name="RoundedCorners" type="ImageProcessor.Web.Processors.RoundedCorners, ImageProcessor.Web" /><plugin name="Saturation" type="ImageProcessor.Web.Processors.Saturation, ImageProcessor.Web" /><plugin name="Tint" type="ImageProcessor.Web.Processors.Tint, ImageProcessor.Web" /><plugin name="Vignette" type="ImageProcessor.Web.Processors.Vignette, ImageProcessor.Web" /><plugin name="Watermark" type="ImageProcessor.Web.Processors.Watermark, ImageProcessor.Web" /></plugins><presets>
</presets></processing>
</presets></processing>

View File

@@ -0,0 +1,43 @@
using System;
using Umbraco.Core.Request;
using Umbraco.Web.Routing;
namespace Umbraco.Web.AspNet
{
public class AspNetRequestAccessor : IRequestAccessor
{
private readonly IHttpContextAccessor _httpContextAccessor;
public AspNetRequestAccessor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
UmbracoModule.EndRequest += OnEndRequest;
UmbracoModule.RouteAttempt += OnRouteAttempt;
}
public string GetRequestValue(string name)
{
return _httpContextAccessor.GetRequiredHttpContext().Request[name];
}
public string GetQueryStringValue(string name)
{
return _httpContextAccessor.GetRequiredHttpContext().Request.QueryString[name];
}
private void OnEndRequest(object sender, UmbracoRequestEventArgs args)
{
EndRequest?.Invoke(sender, args);
}
private void OnRouteAttempt(object sender, RoutableAttemptEventArgs args)
{
RouteAttempt?.Invoke(sender, args);
}
public event EventHandler<UmbracoRequestEventArgs> EndRequest;
public event EventHandler<RoutableAttemptEventArgs> RouteAttempt;
}
}

View File

@@ -1,11 +0,0 @@
using System.Web;
using Umbraco.Core;
using Umbraco.Net;
namespace Umbraco.Web
{
internal class AspNetSessionIdResolver : ISessionIdResolver
{
public string SessionId => HttpContext.Current?.Session?.SessionID;
}
}

View File

@@ -0,0 +1,26 @@
using System.Web;
using Umbraco.Core.Session;
using Umbraco.Net;
namespace Umbraco.Web.AspNet
{
public class AspNetSessionManager: ISessionManager, ISessionIdResolver
{
public AspNetSessionManager()
{
}
public object GetSessionValue(string sessionName)
{
return HttpContext.Current.Session[sessionName];
}
public void SetSessionValue(string sessionName, object value)
{
HttpContext.Current.Session[sessionName] = value;
}
public string SessionId => HttpContext.Current?.Session?.SessionID;
}
}

View File

@@ -1,213 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web.Caching;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
namespace Umbraco.Web.Cache
{
/// <summary>
/// Implements <see cref="IAppPolicyCache"/> on top of a <see cref="System.Web.Caching.Cache"/>.
/// </summary>
/// <remarks>The underlying cache is expected to be HttpRuntime.Cache.</remarks>
internal class WebCachingAppCache : FastDictionaryAppCacheBase, IAppPolicyCache
{
// locker object that supports upgradeable read locking
// does not need to support recursion if we implement the cache correctly and ensure
// that methods cannot be reentrant, ie we do NOT create values while holding a lock.
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
private readonly System.Web.Caching.Cache _cache;
/// <summary>
/// Initializes a new instance of the <see cref="WebCachingAppCache"/> class.
/// </summary>
public WebCachingAppCache(System.Web.Caching.Cache cache, ITypeFinder typeFinder) : base(typeFinder)
{
_cache = cache;
}
/// <inheritdoc />
public override object Get(string key, Func<object> factory)
{
return Get(key, factory, null, dependentFiles: null);
}
/// <inheritdoc />
public object Get(string key, Func<object> factory, TimeSpan? timeout, bool isSliding = false, string[] dependentFiles = null)
{
CacheDependency dependency = null;
if (dependentFiles != null && dependentFiles.Any())
{
dependency = new CacheDependency(dependentFiles);
}
return GetImpl(key, factory, timeout, isSliding, dependency);
}
/// <inheritdoc />
public void Insert(string key, Func<object> factory, TimeSpan? timeout = null, bool isSliding = false, string[] dependentFiles = null)
{
CacheDependency dependency = null;
if (dependentFiles != null && dependentFiles.Any())
{
dependency = new CacheDependency(dependentFiles);
}
InsertImpl(key, factory, timeout, isSliding, dependency);
}
#region Dictionary
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
{
const string prefix = CacheItemPrefix + "-";
return _cache.Cast<DictionaryEntry>()
.Where(x => x.Key is string && ((string)x.Key).StartsWith(prefix));
}
protected override void RemoveEntry(string key)
{
_cache.Remove(key);
}
protected override object GetEntry(string key)
{
return _cache.Get(key);
}
#endregion
#region Lock
protected override void EnterReadLock()
{
_locker.EnterReadLock();
}
protected override void EnterWriteLock()
{
_locker.EnterWriteLock();
}
protected override void ExitReadLock()
{
if (_locker.IsReadLockHeld)
_locker.ExitReadLock();
}
protected override void ExitWriteLock()
{
if (_locker.IsWriteLockHeld)
_locker.ExitWriteLock();
}
#endregion
private object GetImpl(string key, Func<object> factory, TimeSpan? timeout, bool isSliding = false, CacheDependency dependency = null)
{
key = GetCacheKey(key);
// NOTE - because we don't know what getCacheItem does, how long it will take and whether it will hang,
// getCacheItem should run OUTSIDE of the global application lock else we run into lock contention and
// nasty performance issues.
// So.... we insert a Lazy<object> in the cache while holding the global application lock, and then rely
// on the Lazy lock to ensure that getCacheItem runs once and everybody waits on it, while the global
// application lock has been released.
// NOTE
// The Lazy value creation may produce a null value.
// Must make sure (for backward compatibility) that we pretend they are not in the cache.
// So if we find an entry in the cache that already has its value created and is null,
// pretend it was not there. If value is not already created, wait... and return null, that's
// what prior code did.
// NOTE
// The Lazy value creation may throw.
// So... the null value _will_ be in the cache but never returned
Lazy<object> result;
// Fast!
// Only one thread can enter an UpgradeableReadLock at a time, but it does not prevent other
// threads to enter a ReadLock in the meantime -- only upgrading to WriteLock will prevent all
// reads. We first try with a normal ReadLock for maximum concurrency and take the penalty of
// having to re-lock in case there's no value. Would need to benchmark to figure out whether
// it's worth it, though...
try
{
_locker.EnterReadLock();
result = _cache.Get(key) as Lazy<object>; // null if key not found
}
finally
{
if (_locker.IsReadLockHeld)
_locker.ExitReadLock();
}
var value = result == null ? null : SafeLazy.GetSafeLazyValue(result);
if (value != null) return value;
using (var lck = new UpgradeableReadLock(_locker))
{
result = _cache.Get(key) as Lazy<object>; // null if key not found
// cannot create value within the lock, so if result.IsValueCreated is false, just
// do nothing here - means that if creation throws, a race condition could cause
// more than one thread to reach the return statement below and throw - accepted.
if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
result = SafeLazy.GetSafeLazy(factory);
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
lck.UpgradeToWriteLock();
//NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update!
_cache.Insert(key, result, dependency, absolute, sliding, CacheItemPriority.Normal, null);
}
}
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
// exceptions (but try again and again) and silently eat them - however at
// some point we have to report them - so need to re-throw here
// this does not throw anymore
//return result.Value;
value = result.Value; // will not throw (safe lazy)
if (value is SafeLazy.ExceptionHolder eh) eh.Exception.Throw(); // throw once!
return value;
}
private void InsertImpl(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheDependency dependency = null)
{
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
// and make sure we don't store a null value.
var result = SafeLazy.GetSafeLazy(getCacheItem);
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
if (value == null) return; // do not store null values (backward compat)
cacheKey = GetCacheKey(cacheKey);
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
try
{
_locker.EnterWriteLock();
//NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update!
_cache.Insert(cacheKey, result, dependency, absolute, sliding, CacheItemPriority.Normal, null);
}
finally
{
if (_locker.IsWriteLockHeld)
_locker.ExitWriteLock();
}
}
}
}

View File

@@ -96,7 +96,7 @@ namespace Umbraco.Web
}
if (cacheByMember)
{
var helper = Current.Factory.GetInstance<MembershipHelper>();
var helper = Current.MembershipHelper;
var currentMember = helper.GetCurrentMember();
cacheKey.AppendFormat("m{0}-", currentMember?.Id ?? 0);
}

48
src/Umbraco.Web/Macros/MacroRenderer.cs Executable file → Normal file
View File

@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -12,10 +11,11 @@ using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Macros;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Request;
using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Web.Security;
using Umbraco.Core.Session;
namespace Umbraco.Web.Macros
{
@@ -29,10 +29,25 @@ namespace Umbraco.Web.Macros
private readonly IMacroService _macroService;
private readonly IIOHelper _ioHelper;
private readonly ICookieManager _cookieManager;
private readonly IUserService _userService;
private readonly IMemberUserKeyProvider _memberUserKeyProvider;
private readonly ISessionManager _sessionManager;
private readonly IRequestAccessor _requestAccessor;
private readonly IHttpContextAccessor _httpContextAccessor;
public MacroRenderer(IProfilingLogger plogger, IUmbracoContextAccessor umbracoContextAccessor, IContentSection contentSection, ILocalizedTextService textService, AppCaches appCaches, IMacroService macroService, IUserService userService, IHttpContextAccessor httpContextAccessor, IIOHelper ioHelper, ICookieManager cookieManager)
public MacroRenderer(
IProfilingLogger plogger,
IUmbracoContextAccessor umbracoContextAccessor,
IContentSection contentSection,
ILocalizedTextService textService,
AppCaches appCaches,
IMacroService macroService,
IIOHelper ioHelper,
ICookieManager cookieManager,
IMemberUserKeyProvider memberUserKeyProvider,
ISessionManager sessionManager,
IRequestAccessor requestAccessor,
IHttpContextAccessor httpContextAccessor)
{
_plogger = plogger ?? throw new ArgumentNullException(nameof(plogger));
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
@@ -42,7 +57,9 @@ namespace Umbraco.Web.Macros
_macroService = macroService ?? throw new ArgumentNullException(nameof(macroService));
_ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
_cookieManager = cookieManager;
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_memberUserKeyProvider = memberUserKeyProvider;
_sessionManager = sessionManager;
_requestAccessor = requestAccessor;
_httpContextAccessor = httpContextAccessor;
}
@@ -63,12 +80,9 @@ namespace Umbraco.Web.Macros
{
object key = 0;
if (_httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false)
if (_umbracoContextAccessor.UmbracoContext.Security.IsAuthenticated())
{
//ugh, membershipproviders :(
var provider = MembershipProviderExtensions.GetMembersMembershipProvider();
var member = MembershipProviderExtensions.GetCurrentUser(provider);
key = member?.ProviderUserKey ?? 0;
key = _memberUserKeyProvider.GetMemberProviderUserKey() ?? 0;
}
id.AppendFormat("m{0}-", key);
@@ -127,10 +141,8 @@ namespace Umbraco.Web.Macros
// do not cache if it should cache by member and there's not member
if (model.CacheByMember)
{
var provider = MembershipProviderExtensions.GetMembersMembershipProvider();
var member = MembershipProviderExtensions.GetCurrentUser(provider);
var key = member?.ProviderUserKey;
if (key == null) return;
var key = _memberUserKeyProvider.GetMemberProviderUserKey();
if (key is null) return;
}
// remember when we cache the content
@@ -364,8 +376,6 @@ namespace Umbraco.Web.Macros
return attributeValue;
}
var context = _httpContextAccessor.HttpContext;
foreach (var token in tokens)
{
var isToken = token.Length > 4 && token[0] == '[' && token[token.Length - 1] == ']' && validTypes.Contains(token[1]);
@@ -383,10 +393,10 @@ namespace Umbraco.Web.Macros
switch (type)
{
case '@':
attributeValue = context?.Request[name];
attributeValue = _requestAccessor.GetRequestValue(name);
break;
case '%':
attributeValue = context?.Session[name]?.ToString();
attributeValue = _sessionManager.GetSessionValue(name)?.ToString();
if (string.IsNullOrEmpty(attributeValue))
attributeValue = _cookieManager.GetCookieValue(name);
break;

View File

@@ -0,0 +1,17 @@
using Umbraco.Core.Security;
using Umbraco.Web.Security;
namespace Umbraco.Web.Macros
{
internal class MemberUserKeyProvider : IMemberUserKeyProvider
{
public object GetMemberProviderUserKey()
{
//ugh, membershipproviders :(
var provider = MembershipProviderExtensions.GetMembersMembershipProvider();
var member = MembershipProviderExtensions.GetCurrentUser(provider);
return member?.ProviderUserKey;
}
}
}

View File

@@ -5,7 +5,6 @@ using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Identity;

View File

@@ -1,7 +1,5 @@
using System.ComponentModel.DataAnnotations;
using Umbraco.Core;
using Umbraco.Web.Security;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Web.Models
{
@@ -16,26 +14,9 @@ namespace Umbraco.Web.Models
/// <returns></returns>
public static LoginStatusModel CreateModel()
{
return new LoginStatusModel(false);
return new LoginStatusModel();
}
private LoginStatusModel(bool doLookup)
{
if (doLookup && Current.UmbracoContext != null)
{
var helper = Current.Factory.GetInstance<MembershipHelper>();
var model = helper.GetCurrentLoginStatus();
if (model != null)
{
Name = model.Name;
Username = model.Username;
Email = model.Email;
IsLoggedIn = true;
}
}
}
/// <summary>
/// The name of the member
/// </summary>

View File

@@ -1,18 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Mapping;
using System.Web.Mvc;
using Umbraco.Core.Models;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.ContentApps;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Trees;
using Umbraco.Web.WebApi;
using UserProfile = Umbraco.Web.Models.ContentEditing.UserProfile;
namespace Umbraco.Web.Models.Mapping
{

View File

@@ -1,5 +1,4 @@
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Web.Models.ContentEditing;

View File

@@ -3,9 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using Umbraco.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Web.Models
@@ -28,7 +25,7 @@ namespace Umbraco.Web.Models
MemberProperties = new List<UmbracoProperty>();
if (doLookup && Current.UmbracoContext != null)
{
var helper = Current.Factory.GetInstance<MembershipHelper>();
var helper = Current.MembershipHelper;
var model = helper.GetCurrentMemberProfileModel();
MemberProperties = model.MemberProperties;
}

View File

@@ -1,13 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Web.Security;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Web.Models
{
@@ -20,22 +15,16 @@ namespace Umbraco.Web.Models
/// <returns></returns>
public static RegisterModel CreateModel()
{
return new RegisterModel(false);
return new RegisterModel();
}
private RegisterModel(bool doLookup)
private RegisterModel()
{
MemberTypeAlias = Constants.Conventions.MemberTypes.DefaultAlias;
UsernameIsEmail = true;
MemberProperties = new List<UmbracoProperty>();
LoginOnSuccess = true;
CreatePersistentLoginCookie = true;
if (doLookup && Current.UmbracoContext != null)
{
var helper = Current.Factory.GetInstance<MembershipHelper>();
var model = helper.CreateRegistrationModel(MemberTypeAlias);
MemberProperties = model.MemberProperties;
}
}

View File

@@ -48,9 +48,9 @@ namespace Umbraco.Web.Mvc
}
}
var helper = Current.Factory.GetInstance<MembershipHelper>();
var helper = Current.MembershipHelper;
return helper.IsMemberAuthorized(AllowType.Split(','), AllowGroup.Split(','), members);
}
/// <summary>

View File

@@ -1,5 +1,4 @@
using System.Linq;
using System.Web;
using System.Web.Security;
using Examine;
using Microsoft.AspNet.SignalR;
@@ -7,13 +6,11 @@ using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Cookie;
using Umbraco.Core.Dashboards;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Events;
using Umbraco.Core.Hosting;
using Umbraco.Core.Install;
using Umbraco.Core.Migrations.PostMigrations;
using Umbraco.Core.Models.Identity;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Runtime;
@@ -49,6 +46,9 @@ using Current = Umbraco.Web.Composing.Current;
using Umbraco.Web.PropertyEditors;
using Umbraco.Examine;
using Umbraco.Core.Models;
using Umbraco.Core.Request;
using Umbraco.Core.Session;
using Umbraco.Web.AspNet;
using Umbraco.Web.AspNet;
using Umbraco.Web.Models;
@@ -65,8 +65,14 @@ namespace Umbraco.Web.Runtime
composition.Register<UmbracoInjectedModule>();
composition.Register<IIpResolver, AspNetIpResolver>();
composition.Register<IUserAgentProvider, AspNetUserAgentProvider>();
composition.Register<ISessionIdResolver, AspNetSessionIdResolver>();
composition.Register<AspNetSessionManager>(Lifetime.Singleton);
composition.Register<ISessionIdResolver>(factory => factory.GetInstance<AspNetSessionManager>(), Lifetime.Singleton);
composition.Register<ISessionManager>(factory => factory.GetInstance<AspNetSessionManager>(), Lifetime.Singleton);
composition.Register<IRequestAccessor, AspNetRequestAccessor>(Lifetime.Singleton);
composition.Register<IHostingEnvironment, AspNetHostingEnvironment>();
composition.Register<IBackOfficeInfo, AspNetBackOfficeInfo>();
composition.Register<IUmbracoApplicationLifetime, AspNetUmbracoApplicationLifetime>(Lifetime.Singleton);
@@ -76,6 +82,7 @@ namespace Umbraco.Web.Runtime
composition.RegisterUnique<IHttpContextAccessor, AspNetHttpContextAccessor>(); // required for hybrid accessors
composition.RegisterUnique<ICookieManager, AspNetCookieManager>();
composition.ComposeWebMappingProfiles();
//register the install components
@@ -88,6 +95,8 @@ namespace Umbraco.Web.Runtime
composition.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetInstance<IMemberService>()));
composition.Register<MembershipHelper>(Lifetime.Request);
composition.Register<IPublishedMemberCache>(factory => factory.GetInstance<IUmbracoContext>().PublishedSnapshot.Members);
composition.RegisterUnique<IMemberUserKeyProvider, MemberUserKeyProvider>();
composition.RegisterUnique<IPublicAccessChecker, PublicAccessChecker>();
// register accessors for cultures
composition.RegisterUnique<IDefaultCultureAccessor, DefaultCultureAccessor>();
@@ -118,6 +127,7 @@ namespace Umbraco.Web.Runtime
composition.RegisterUnique<ITemplateRenderer, TemplateRenderer>();
composition.RegisterUnique<IMacroRenderer, MacroRenderer>();
composition.RegisterUnique<IUmbracoComponentRenderer, UmbracoComponentRenderer>();
composition.RegisterUnique<HtmlLocalLinkParser>();

View File

@@ -9,7 +9,6 @@ using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Runtime;
using Umbraco.Web.Cache;
using Umbraco.Web.Composing;
using Umbraco.Web.Logging;
using Current = Umbraco.Web.Composing.Current;
@@ -22,7 +21,6 @@ namespace Umbraco.Web.Runtime
/// <remarks>On top of CoreRuntime, handles all of the web-related runtime aspects of Umbraco.</remarks>
public class WebRuntime : CoreRuntime
{
private readonly UmbracoApplicationBase _umbracoApplication;
private BuildManagerTypeFinder _typeFinder;
/// <summary>
@@ -30,7 +28,6 @@ namespace Umbraco.Web.Runtime
/// </summary>
/// <param name="umbracoApplication"></param>
public WebRuntime(
UmbracoApplicationBase umbracoApplication,
Configs configs,
IUmbracoVersion umbracoVersion,
IIOHelper ioHelper,
@@ -42,8 +39,6 @@ namespace Umbraco.Web.Runtime
IMainDom mainDom):
base(configs, umbracoVersion, ioHelper, logger, profiler ,new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom)
{
_umbracoApplication = umbracoApplication;
Profiler = GetWebProfiler();
}
@@ -102,7 +97,7 @@ namespace Umbraco.Web.Runtime
protected override AppCaches GetAppCaches() => new AppCaches(
// we need to have the dep clone runtime cache provider to ensure
// all entities are cached properly (cloned in and cloned out)
new DeepCloneAppCache(new WebCachingAppCache(HttpRuntime.Cache, TypeFinder)),
new DeepCloneAppCache(new ObjectCacheAppCache(TypeFinder)),
// we need request based cache when running in web-based context
new HttpRequestAppCache(() => HttpContext.Current?.Items, TypeFinder),
new IsolatedCaches(type =>

View File

@@ -1,9 +1,6 @@
using System;
using System.ComponentModel;
using System.Net.Mail;
using System.Net.Mail;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.Security
{

View File

@@ -0,0 +1,54 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Services;
namespace Umbraco.Web.Security
{
public class PublicAccessChecker : IPublicAccessChecker
{
//TODO: This is lazy to avoid circular dependency. We don't care right now because all membership is going to be changed.
private readonly Lazy<MembershipHelper> _membershipHelper;
private readonly IPublicAccessService _publicAccessService;
private readonly IContentService _contentService;
public PublicAccessChecker(Lazy<MembershipHelper> membershipHelper, IPublicAccessService publicAccessService, IContentService contentService)
{
_membershipHelper = membershipHelper;
_publicAccessService = publicAccessService;
_contentService = contentService;
}
public PublicAccessStatus HasMemberAccessToContent(int publishedContentId)
{
var membershipHelper = _membershipHelper.Value;
if (membershipHelper.IsLoggedIn() == false)
{
return PublicAccessStatus.NotLoggedIn;
}
var username = membershipHelper.CurrentUserName;
var userRoles = membershipHelper.GetCurrentUserRoles();
if (_publicAccessService.HasAccess(publishedContentId, _contentService, username, userRoles) == false)
{
return PublicAccessStatus.AccessDenied;
}
var member = membershipHelper.GetCurrentMember();
if (member.HasProperty(Constants.Conventions.Member.IsApproved) == false)
{
return PublicAccessStatus.NotApproved;
}
if (member.HasProperty(Constants.Conventions.Member.IsLockedOut) &&
member.Value<bool>(Constants.Conventions.Member.IsApproved))
{
return PublicAccessStatus.LockedOut;
}
return PublicAccessStatus.AccessAccepted;
}
}
}

View File

@@ -10,7 +10,7 @@ using Microsoft.Owin.Security.Cookies;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Security;
using Constants = Umbraco.Core.Constants;
namespace Umbraco.Web.Security

View File

@@ -2,16 +2,15 @@ using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.Routing;
using Umbraco.Core.Strings;
namespace Umbraco.Web.Templates
{
@@ -46,10 +45,11 @@ namespace Umbraco.Web.Templates
{
if (writer == null) throw new ArgumentNullException(nameof(writer));
var umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
// instantiate a request and process
// important to use CleanedUmbracoUrl - lowercase path-only version of the current url, though this isn't going to matter
// terribly much for this implementation since we are just creating a doc content request to modify it's properties manually.
var contentRequest = _publishedRouter.CreateRequest(_umbracoContextAccessor.UmbracoContext);
var contentRequest = _publishedRouter.CreateRequest(umbracoContext);
var doc = contentRequest.UmbracoContext.Content.GetById(pageId);
@@ -62,7 +62,7 @@ namespace Umbraco.Web.Templates
//in some cases the UmbracoContext will not have a PublishedRequest assigned to it if we are not in the
//execution of a front-end rendered page. In this case set the culture to the default.
//set the culture to the same as is currently rendering
if (_umbracoContextAccessor.UmbracoContext.PublishedRequest == null)
if (umbracoContext.PublishedRequest == null)
{
var defaultLanguage = _languageService.GetAllLanguages().FirstOrDefault();
contentRequest.Culture = defaultLanguage == null
@@ -71,7 +71,7 @@ namespace Umbraco.Web.Templates
}
else
{
contentRequest.Culture = _umbracoContextAccessor.UmbracoContext.PublishedRequest.Culture;
contentRequest.Culture = umbracoContext.PublishedRequest.Culture;
}
//set the doc that was found by id

View File

@@ -134,10 +134,11 @@
<Compile Include="AppBuilderExtensions.cs" />
<Compile Include="AreaRegistrationContextExtensions.cs" />
<Compile Include="AspNet\AspNetHostingEnvironment.cs" />
<Compile Include="AspNet\AspNetRequestAccessor.cs" />
<Compile Include="AspNet\AspNetSessionManager.cs" />
<Compile Include="AspNet\AspNetUserAgentProvider.cs" />
<Compile Include="AspNet\FrameworkMarchal.cs" />
<Compile Include="AspNet\AspNetUmbracoApplicationLifetime.cs" />
<Compile Include="Cache\WebCachingAppCache.cs" />
<Compile Include="Compose\AuditEventsComponent.cs" />
<Compile Include="Compose\AuditEventsComposer.cs" />
<Compile Include="Compose\BackOfficeUserAuditEventsComponent.cs" />
@@ -166,6 +167,8 @@
<Compile Include="Logging\WebProfilerComponent.cs" />
<Compile Include="Logging\WebProfilerComposer.cs" />
<Compile Include="Logging\WebProfilerProvider.cs" />
<Compile Include="Macros\MacroRenderer.cs" />
<Compile Include="Macros\MemberUserKeyProvider.cs" />
<Compile Include="Models\Identity\BackOfficeIdentityUser.cs" />
<Compile Include="Models\Identity\IdentityMapDefinition.cs" />
<Compile Include="Models\Identity\IdentityUser.cs" />
@@ -185,12 +188,9 @@
<Compile Include="AspNet\AspNetHttpContextAccessor.cs" />
<Compile Include="AspNet\AspNetIpResolver.cs" />
<Compile Include="AspNet\AspNetPasswordHasher.cs" />
<Compile Include="AspNet\AspNetSessionIdResolver.cs" />
<Compile Include="Profiling\WebProfilingController.cs" />
<Compile Include="RoutableDocumentFilter.cs" />
<Compile Include="Runtime\AspNetUmbracoBootPermissionChecker.cs" />
<Compile Include="Scheduling\SchedulerComponent.cs" />
<Compile Include="Scheduling\SchedulerComposer.cs" />
<Compile Include="Security\BackOfficeUserStore.cs" />
<Compile Include="Security\BackOfficeUserValidator.cs" />
<Compile Include="Security\ConfiguredPasswordValidator.cs" />
@@ -200,6 +200,7 @@
<Compile Include="Security\MembershipProviderBase.cs" />
<Compile Include="Security\MembershipProviderExtensions.cs" />
<Compile Include="Security\PasswordSecurity.cs" />
<Compile Include="Security\PublicAccessChecker.cs" />
<Compile Include="Security\UmbracoBackOfficeIdentity.cs" />
<Compile Include="Security\UmbracoEmailMessage.cs" />
<Compile Include="Security\UmbracoMembershipProviderBase.cs" />
@@ -214,7 +215,6 @@
<Compile Include="ViewDataExtensions.cs" />
<Compile Include="WebApi\Filters\AdminUsersAuthorizeAttribute.cs" />
<Compile Include="WebApi\Filters\OnlyLocalRequestsAttribute.cs" />
<Compile Include="Routing\RedirectTrackingComposer.cs" />
<Compile Include="Runtime\WebInitialComposer.cs" />
<Compile Include="Security\ActiveDirectoryBackOfficeUserPasswordChecker.cs" />
<Compile Include="Security\BackOfficeClaimsIdentityFactory.cs" />
@@ -273,7 +273,6 @@
<Compile Include="Editors\MemberGroupController.cs" />
<Compile Include="Composing\CompositionExtensions\Controllers.cs" />
<Compile Include="HealthCheck\HealthCheckController.cs" />
<Compile Include="Macros\MacroRenderer.cs" />
<Compile Include="HtmlHelperBackOfficeExtensions.cs" />
<Compile Include="Composing\ModuleInjector.cs" />
<Compile Include="Mvc\FilteredControllerFactoryCollection.cs" />
@@ -305,7 +304,6 @@
<Compile Include="Editors\Filters\MediaItemSaveValidationAttribute.cs" />
<Compile Include="Editors\Filters\MemberSaveValidationAttribute.cs" />
<Compile Include="WebApi\SessionHttpControllerRouteHandler.cs" />
<Compile Include="WebApi\UmbracoApiControllerTypeCollection.cs" />
<Compile Include="WebApi\UmbracoApiControllerTypeCollectionBuilder.cs" />
<Compile Include="WebApi\UnhandedExceptionLoggerConfigurationAttribute.cs" />
<Compile Include="WebApi\UnhandledExceptionLogger.cs" />
@@ -322,7 +320,6 @@
<Compile Include="Mvc\UmbracoRequireHttpsAttribute.cs" />
<Compile Include="Mvc\ValidateMvcAngularAntiForgeryTokenAttribute.cs" />
<Compile Include="OwinMiddlewareConfiguredEventArgs.cs" />
<Compile Include="Routing\RedirectTrackingComponent.cs" />
<Compile Include="Editors\RedirectUrlManagementController.cs" />
<Compile Include="DefaultEventMessagesFactory.cs" />
<Compile Include="Security\ExternalSignInAutoLinkOptions.cs" />
@@ -343,7 +340,6 @@
<Compile Include="IUmbracoComponentRenderer.cs" />
<Compile Include="Mvc\ProfilingView.cs" />
<Compile Include="Mvc\ProfilingViewEngine.cs" />
<Compile Include="BatchedDatabaseServerMessenger.cs" />
<Compile Include="CacheHelperExtensions.cs" />
<Compile Include="Editors\AuthenticationController.cs" />
<Compile Include="Controllers\UmbProfileController.cs" />
@@ -526,9 +522,6 @@
<Compile Include="Mvc\PluginControllerMetadata.cs" />
<Compile Include="Mvc\UmbracoPageResult.cs" />
<Compile Include="RouteCollectionExtensions.cs" />
<Compile Include="Routing\ContentFinderByPageIdQuery.cs" />
<Compile Include="Routing\PublishedRouter.cs" />
<Compile Include="Compose\DatabaseServerRegistrarAndMessengerComponent.cs" />
<Compile Include="Templates\TemplateRenderer.cs" />
<Compile Include="Trees\PartialViewMacrosTreeController.cs" />
<Compile Include="Trees\PartialViewsTreeController.cs" />
@@ -553,7 +546,6 @@
<Compile Include="WebApi\Filters\UmbracoUserTimeoutFilterAttribute.cs" />
<Compile Include="Runtime\WebRuntime.cs" />
<Compile Include="Mvc\ControllerExtensions.cs" />
<Compile Include="Routing\ContentFinderByIdPath.cs" />
<Compile Include="TypeLoaderExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>

View File

@@ -30,7 +30,7 @@ namespace Umbraco.Web
var mainDom = new MainDom(logger, hostingEnvironment, mainDomLock);
return new WebRuntime(this, configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom);
return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom);
}
}
}

View File

@@ -11,6 +11,7 @@ using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Logging.Serilog;
using Umbraco.Web.AspNet;
using Umbraco.Web.Hosting;
using Current = Umbraco.Web.Composing.Current;
@@ -39,7 +40,7 @@ namespace Umbraco.Web
var ioHelper = new IOHelper(hostingEnvironment);
var configs = configFactory.Create(ioHelper);
var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, new AspNetSessionIdResolver(), () => _factory?.GetInstance<IRequestCache>(), coreDebug, ioHelper, new FrameworkMarchal());
var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, new AspNetSessionManager(), () => _factory?.GetInstance<IRequestCache>(), coreDebug, ioHelper, new FrameworkMarchal());
var backOfficeInfo = new AspNetBackOfficeInfo(configs.Global(), ioHelper, configs.Settings(), logger);
var profiler = new LogProfiler(logger);
Umbraco.Composing.Current.Initialize(logger, configs, ioHelper, hostingEnvironment, backOfficeInfo, profiler);

View File

@@ -46,7 +46,7 @@ namespace Umbraco.Web.WebApi
}
}
var helper = Current.Factory.GetInstance<MembershipHelper>();
var helper = Current.MembershipHelper;
return helper.IsMemberAuthorized(AllowType.Split(','), AllowGroup.Split(','), members);
}