Adds new event so we know when umbraco routes a value, ensure the IUmbracoWebsiteSecurity is initialized for front-end requests, cleans up some of the routing middleware, adds lots of notes
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Umbraco.Cms.Core.Web;
|
||||
|
||||
33
src/Umbraco.Core/Events/UmbracoRoutedRequest.cs
Normal file
33
src/Umbraco.Core/Events/UmbracoRoutedRequest.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Notification raised when Umbraco routes a front-end request.
|
||||
/// </summary>
|
||||
public class UmbracoRoutedRequest : INotification
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoRequestBegin"/> class.
|
||||
/// </summary>
|
||||
public UmbracoRoutedRequest(IUmbracoContext umbracoContext)
|
||||
{
|
||||
if (!umbracoContext.IsFrontEndUmbracoRequest())
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(UmbracoRoutedRequest)} is only valid for Umbraco front-end requests");
|
||||
}
|
||||
|
||||
UmbracoContext = umbracoContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IUmbracoContext"/>
|
||||
/// </summary>
|
||||
public IUmbracoContext UmbracoContext { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
|
||||
@@ -18,12 +18,15 @@ namespace Umbraco.Cms.Core
|
||||
{
|
||||
private readonly IRequestCache _requestCache;
|
||||
|
||||
// TODO: Do they need to be static?? These are singleton instances IMO they shouldn't be static
|
||||
// ReSharper disable StaticMemberInGenericType
|
||||
private static readonly object Locker = new object();
|
||||
private static bool _registered;
|
||||
private static readonly object s_locker = new object();
|
||||
private static bool s_registered;
|
||||
// ReSharper restore StaticMemberInGenericType
|
||||
|
||||
protected abstract string ItemKey { get; }
|
||||
private string _itemKey;
|
||||
|
||||
protected string ItemKey => _itemKey ?? (_itemKey = GetType().FullName);
|
||||
|
||||
// read
|
||||
// http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html
|
||||
@@ -43,34 +46,42 @@ namespace Umbraco.Cms.Core
|
||||
private T NonContextValue
|
||||
{
|
||||
get => CallContext<T>.GetData(ItemKey);
|
||||
set
|
||||
{
|
||||
CallContext<T>.SetData(ItemKey, value);
|
||||
}
|
||||
set => CallContext<T>.SetData(ItemKey, value);
|
||||
}
|
||||
|
||||
protected HybridAccessorBase(IRequestCache requestCache)
|
||||
{
|
||||
_requestCache = requestCache ?? throw new ArgumentNullException(nameof(requestCache));
|
||||
|
||||
lock (Locker)
|
||||
lock (s_locker)
|
||||
{
|
||||
// register the itemKey once with SafeCallContext
|
||||
if (_registered) return;
|
||||
_registered = true;
|
||||
if (s_registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_registered = true;
|
||||
}
|
||||
|
||||
// ReSharper disable once VirtualMemberCallInConstructor
|
||||
var itemKey = ItemKey; // virtual
|
||||
SafeCallContext.Register(() =>
|
||||
{
|
||||
var value = CallContext<T>.GetData(itemKey);
|
||||
T value = CallContext<T>.GetData(itemKey);
|
||||
return value;
|
||||
}, o =>
|
||||
{
|
||||
if (o == null) return;
|
||||
var value = o as T;
|
||||
if (value == null) throw new ArgumentException($"Expected type {typeof(T).FullName}, got {o.GetType().FullName}", nameof(o));
|
||||
if (o == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(o is T value))
|
||||
{
|
||||
throw new ArgumentException($"Expected type {typeof(T).FullName}, got {o.GetType().FullName}", nameof(o));
|
||||
}
|
||||
|
||||
CallContext<T>.SetData(itemKey, value);
|
||||
});
|
||||
}
|
||||
@@ -93,9 +104,13 @@ namespace Umbraco.Cms.Core
|
||||
NonContextValue = value;
|
||||
}
|
||||
else if (value == null)
|
||||
{
|
||||
_requestCache.Remove(ItemKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
_requestCache.Set(ItemKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
|
||||
namespace Umbraco.Cms.Core
|
||||
{
|
||||
public class HybridEventMessagesAccessor : HybridAccessorBase<EventMessages>, IEventMessagesAccessor
|
||||
{
|
||||
protected override string ItemKey => "Umbraco.Core.Events.HybridEventMessagesAccessor";
|
||||
|
||||
public HybridEventMessagesAccessor(IRequestCache requestCache)
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models.PublishedContent
|
||||
{
|
||||
@@ -11,9 +11,6 @@ namespace Umbraco.Cms.Core.Models.PublishedContent
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string ItemKey => "Umbraco.Web.HybridVariationContextAccessor";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="VariationContext"/> object.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
|
||||
namespace Umbraco.Cms.Core.Security
|
||||
{
|
||||
@@ -11,9 +11,6 @@ namespace Umbraco.Cms.Core.Security
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string ItemKey => "Umbraco.Web.HybridBackofficeSecurityAccessor";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IBackOfficeSecurity"/> object.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
|
||||
namespace Umbraco.Cms.Core.Security
|
||||
{
|
||||
@@ -12,9 +12,6 @@ namespace Umbraco.Cms.Core.Security
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string ItemKey => "Umbraco.Web.HybridUmbracoWebsiteSecurityAccessor";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IUmbracoWebsiteSecurity"/> object.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Cms.Core
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates and manages <see cref="IBackOfficeSecurity"/> instances.
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Cms.Core.Models.Security;
|
||||
|
||||
namespace Umbraco.Cms.Core.Security
|
||||
{
|
||||
// TODO: I think we can kill this whole thing, the logic can just be in the controllers
|
||||
public interface IUmbracoWebsiteSecurity
|
||||
{
|
||||
/// <summary>
|
||||
@@ -35,18 +36,10 @@ namespace Umbraco.Cms.Core.Security
|
||||
/// <returns>Result of update profile operation.</returns>
|
||||
Task<UpdateMemberProfileResult> UpdateMemberProfileAsync(ProfileModel model);
|
||||
|
||||
/// <summary>
|
||||
/// A helper method to perform the validation and logging in of a member.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns>Result of login operation.</returns>
|
||||
// TODO: Kill this, we will just use the MemberManager / MemberSignInManager
|
||||
Task<bool> LoginAsync(string username, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Check if a member is logged in
|
||||
/// </summary>
|
||||
/// <returns>True if logged in, false if not.</returns>
|
||||
// TODO: Kill this, we will just use the MemberManager
|
||||
bool IsLoggedIn();
|
||||
|
||||
/// <summary>
|
||||
@@ -55,9 +48,7 @@ namespace Umbraco.Cms.Core.Security
|
||||
/// <returns>Instance of <see cref="LoginStatusModel"/></returns>
|
||||
Task<LoginStatusModel> GetCurrentLoginStatusAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Logs out the current member.
|
||||
/// </summary>
|
||||
// TODO: Kill this, we will just use the MemberManager
|
||||
Task LogOutAsync();
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
|
||||
namespace Umbraco.Cms.Core.Web
|
||||
{
|
||||
@@ -14,9 +14,6 @@ namespace Umbraco.Cms.Core.Web
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string ItemKey => "Umbraco.Web.HybridUmbracoContextAccessor";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="UmbracoContext"/> object.
|
||||
/// </summary>
|
||||
|
||||
@@ -12,6 +12,7 @@ using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.HostedServices
|
||||
{
|
||||
@@ -106,7 +107,11 @@ namespace Umbraco.Cms.Infrastructure.HostedServices
|
||||
// - batched messenger should not depend on a current HttpContext
|
||||
// but then what should be its "scope"? could we attach it to scopes?
|
||||
// - and we should definitively *not* have to flush it here (should be auto)
|
||||
//
|
||||
|
||||
// TODO: This dependency chain is broken and needs to be fixed.
|
||||
// This is required to be called before EnsureUmbracoContext else the UmbracoContext's IBackOfficeSecurity instance is null
|
||||
// This is a very ugly Temporal Coupling which also means that developers can no longer just use IUmbracoContextFactory the
|
||||
// way it was intended.
|
||||
_backofficeSecurityFactory.EnsureBackOfficeSecurity();
|
||||
using UmbracoContextReference contextReference = _umbracoContextFactory.EnsureUmbracoContext();
|
||||
try
|
||||
|
||||
@@ -14,7 +14,6 @@ using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
@@ -25,6 +24,7 @@ using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Web.BackOffice.Controllers;
|
||||
using Umbraco.Cms.Web.Common.Controllers;
|
||||
using Umbraco.Cms.Web.Website.Controllers;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Extensions;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
@@ -122,6 +122,10 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: This dependency chain is broken and needs to be fixed.
|
||||
// This is required to be called before EnsureUmbracoContext else the UmbracoContext's IBackOfficeSecurity instance is null
|
||||
// This is a very ugly Temporal Coupling which also means that developers can no longer just use IUmbracoContextFactory the
|
||||
// way it was intended.
|
||||
backofficeSecurityFactory.EnsureBackOfficeSecurity();
|
||||
umbracoContextFactory.EnsureUmbracoContext();
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.DependencyInjection;
|
||||
using Umbraco.Cms.Tests.Integration.Extensions;
|
||||
using Umbraco.Cms.Tests.Integration.Implementations;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Extensions;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
@@ -25,6 +24,7 @@ using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Web.BackOffice.Filters;
|
||||
using Umbraco.Cms.Web.BackOffice.ModelBinders;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Extensions;
|
||||
using DataType = Umbraco.Cms.Core.Models.DataType;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure;
|
||||
using Umbraco.Cms.Infrastructure.HostedServices;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices
|
||||
{
|
||||
|
||||
@@ -53,6 +53,7 @@ using Umbraco.Cms.Web.Common.Routing;
|
||||
using Umbraco.Cms.Web.Common.Security;
|
||||
using Umbraco.Cms.Web.Common.Templates;
|
||||
using Umbraco.Cms.Web.Common.UmbracoContext;
|
||||
using Umbraco.Core.Security;
|
||||
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
@@ -263,6 +264,7 @@ namespace Umbraco.Extensions
|
||||
builder.Services.AddUnique<IUmbracoContextFactory, UmbracoContextFactory>();
|
||||
builder.Services.AddUnique<IBackOfficeSecurityFactory, BackOfficeSecurityFactory>();
|
||||
builder.Services.AddUnique<IBackOfficeSecurityAccessor, HybridBackofficeSecurityAccessor>();
|
||||
builder.AddNotificationHandler<UmbracoRoutedRequest, UmbracoWebsiteSecurityFactory>();
|
||||
builder.Services.AddUnique<IUmbracoWebsiteSecurityAccessor, HybridUmbracoWebsiteSecurityAccessor>();
|
||||
|
||||
var umbracoApiControllerTypes = builder.TypeLoader.GetUmbracoApiControllers().ToList();
|
||||
|
||||
@@ -10,9 +10,11 @@ using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Logging;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Web.Common.Profiler;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.Middleware
|
||||
@@ -83,27 +85,26 @@ namespace Umbraco.Cms.Web.Common.Middleware
|
||||
|
||||
EnsureContentCacheInitialized();
|
||||
|
||||
_backofficeSecurityFactory.EnsureBackOfficeSecurity(); // Needs to be before UmbracoContext, TODO: Why?
|
||||
// TODO: This dependency chain is broken and needs to be fixed.
|
||||
// This is required to be called before EnsureUmbracoContext else the UmbracoContext's IBackOfficeSecurity instance is null
|
||||
// This is ugly Temporal Coupling which also means that developers can no longer just use IUmbracoContextFactory the
|
||||
// way it was intended.
|
||||
_backofficeSecurityFactory.EnsureBackOfficeSecurity();
|
||||
UmbracoContextReference umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext();
|
||||
|
||||
Uri currentApplicationUrl = GetApplicationUrlFromCurrentRequest(context.Request);
|
||||
_hostingEnvironment.EnsureApplicationMainUrl(currentApplicationUrl);
|
||||
|
||||
|
||||
bool isFrontEndRequest = umbracoContextReference.UmbracoContext.IsFrontEndUmbracoRequest();
|
||||
|
||||
var pathAndQuery = context.Request.GetEncodedPathAndQuery();
|
||||
|
||||
try
|
||||
{
|
||||
if (isFrontEndRequest)
|
||||
{
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out Guid httpRequestId, _requestCache);
|
||||
_logger.LogTrace("Begin request [{HttpRequestId}]: {RequestUrl}", httpRequestId, pathAndQuery);
|
||||
}
|
||||
// Verbose log start of every request
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out Guid httpRequestId, _requestCache);
|
||||
_logger.LogTrace("Begin request [{HttpRequestId}]: {RequestUrl}", httpRequestId, pathAndQuery);
|
||||
|
||||
try
|
||||
{
|
||||
{
|
||||
await _eventAggregator.PublishAsync(new UmbracoRequestBegin(umbracoContextReference.UmbracoContext));
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -126,11 +127,10 @@ namespace Umbraco.Cms.Web.Common.Middleware
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (isFrontEndRequest)
|
||||
{
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out Guid httpRequestId, _requestCache);
|
||||
_logger.LogTrace("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, pathAndQuery, DateTime.Now.Subtract(umbracoContextReference.UmbracoContext.ObjectCreated).TotalMilliseconds);
|
||||
}
|
||||
// Verbose log end of every request (in v8 we didn't log the end request of ALL requests, only the front-end which was
|
||||
// strange since we always logged the beginning, so now we just log start/end of all requests)
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out Guid httpRequestId, _requestCache);
|
||||
_logger.LogTrace("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, pathAndQuery, DateTime.Now.Subtract(umbracoContextReference.UmbracoContext.ObjectCreated).TotalMilliseconds);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Umbraco.Cms.Core;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.Security
|
||||
{
|
||||
// TODO: This is only for the back office, does it need to be in common?
|
||||
// TODO: This is only for the back office, does it need to be in common? YES currently UmbracoContext has an transitive dependency on this which needs to be fixed/reviewed.
|
||||
|
||||
public class BackOfficeSecurityFactory: IBackOfficeSecurityFactory
|
||||
{
|
||||
@@ -14,11 +14,11 @@ namespace Umbraco.Cms.Web.Common.Security
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public BackOfficeSecurityFactory(
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IUserService userService,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_backOfficeSecurityAccessor = backofficeSecurityAccessor;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_userService = userService;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@@ -11,9 +11,8 @@ using Umbraco.Cms.Core.Models.Security;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
namespace Umbraco.Cms.Web.Website.Security
|
||||
namespace Umbraco.Cms.Web.Common.Security
|
||||
{
|
||||
public class UmbracoWebsiteSecurity : IUmbracoWebsiteSecurity
|
||||
{
|
||||
@@ -36,7 +35,7 @@ namespace Umbraco.Cms.Web.Website.Security
|
||||
/// <inheritdoc/>
|
||||
public RegisterModel CreateRegistrationModel(string memberTypeAlias = null)
|
||||
{
|
||||
var providedOrDefaultMemberTypeAlias = memberTypeAlias ?? Constants.Conventions.MemberTypes.DefaultAlias;
|
||||
var providedOrDefaultMemberTypeAlias = memberTypeAlias ?? Core.Constants.Conventions.MemberTypes.DefaultAlias;
|
||||
var memberType = _memberTypeService.Get(providedOrDefaultMemberTypeAlias);
|
||||
if (memberType == null)
|
||||
{
|
||||
@@ -114,7 +113,7 @@ namespace Umbraco.Cms.Web.Website.Security
|
||||
|
||||
public Task<RegisterMemberStatus> RegisterMemberAsync(RegisterModel model, bool logMemberIn = true)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -0,0 +1,46 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures that the <see cref="IUmbracoWebsiteSecurity"/> is populated on a front-end request
|
||||
/// </summary>
|
||||
internal sealed class UmbracoWebsiteSecurityFactory : INotificationHandler<UmbracoRoutedRequest>
|
||||
{
|
||||
private readonly IUmbracoWebsiteSecurityAccessor _umbracoWebsiteSecurityAccessor;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IMemberService _memberService;
|
||||
private readonly IMemberTypeService _memberTypeService;
|
||||
private readonly IShortStringHelper _shortStringHelper;
|
||||
|
||||
public UmbracoWebsiteSecurityFactory(
|
||||
IUmbracoWebsiteSecurityAccessor umbracoWebsiteSecurityAccessor,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IMemberService memberService,
|
||||
IMemberTypeService memberTypeService,
|
||||
IShortStringHelper shortStringHelper)
|
||||
{
|
||||
_umbracoWebsiteSecurityAccessor = umbracoWebsiteSecurityAccessor;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_memberService = memberService;
|
||||
_memberTypeService = memberTypeService;
|
||||
_shortStringHelper = shortStringHelper;
|
||||
}
|
||||
|
||||
public void Handle(UmbracoRoutedRequest notification)
|
||||
{
|
||||
if (_umbracoWebsiteSecurityAccessor.WebsiteSecurity is null)
|
||||
{
|
||||
_umbracoWebsiteSecurityAccessor.WebsiteSecurity = new UmbracoWebsiteSecurity(
|
||||
_httpContextAccessor,
|
||||
_memberService,
|
||||
_memberTypeService,
|
||||
_shortStringHelper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,13 @@ namespace Umbraco.Cms.Web.Website.Controllers
|
||||
{
|
||||
private readonly IUmbracoWebsiteSecurityAccessor _websiteSecurityAccessor;
|
||||
|
||||
public UmbLoginController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory,
|
||||
ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider,
|
||||
public UmbLoginController(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IUmbracoDatabaseFactory databaseFactory,
|
||||
ServiceContext services,
|
||||
AppCaches appCaches,
|
||||
IProfilingLogger profilingLogger,
|
||||
IPublishedUrlProvider publishedUrlProvider,
|
||||
IUmbracoWebsiteSecurityAccessor websiteSecurityAccessor)
|
||||
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
|
||||
{
|
||||
@@ -36,9 +41,6 @@ namespace Umbraco.Cms.Web.Website.Controllers
|
||||
return CurrentUmbracoPage();
|
||||
}
|
||||
|
||||
// TODO: This is supposed to be for members! not users
|
||||
//throw new NotImplementedException("Implement this for members");
|
||||
|
||||
if (await _websiteSecurityAccessor.WebsiteSecurity.LoginAsync(model.Username, model.Password) == false)
|
||||
{
|
||||
// Don't add a field level error, just model level.
|
||||
|
||||
@@ -2,8 +2,10 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Infrastructure.DependencyInjection;
|
||||
using Umbraco.Cms.Web.Common.Routing;
|
||||
using Umbraco.Cms.Web.Common.Security;
|
||||
using Umbraco.Cms.Web.Website.Collections;
|
||||
using Umbraco.Cms.Web.Website.Controllers;
|
||||
using Umbraco.Cms.Web.Website.Routing;
|
||||
@@ -40,7 +42,7 @@ namespace Umbraco.Extensions
|
||||
builder.Services.AddSingleton<IUmbracoRenderingDefaults, UmbracoRenderingDefaults>();
|
||||
builder.Services.AddSingleton<IRoutableDocumentFilter, RoutableDocumentFilter>();
|
||||
|
||||
builder.Services.AddSingleton<FrontEndRoutes>();
|
||||
builder.Services.AddSingleton<FrontEndRoutes>();
|
||||
|
||||
builder
|
||||
.AddDistributedCache()
|
||||
|
||||
@@ -13,6 +13,7 @@ using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
@@ -48,6 +49,7 @@ namespace Umbraco.Cms.Web.Website.Routing
|
||||
private readonly IRoutableDocumentFilter _routableDocumentFilter;
|
||||
private readonly IDataProtectionProvider _dataProtectionProvider;
|
||||
private readonly IControllerActionSearcher _controllerActionSearcher;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoRouteValueTransformer"/> class.
|
||||
@@ -62,7 +64,8 @@ namespace Umbraco.Cms.Web.Website.Routing
|
||||
IUmbracoRouteValuesFactory routeValuesFactory,
|
||||
IRoutableDocumentFilter routableDocumentFilter,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
IControllerActionSearcher controllerActionSearcher)
|
||||
IControllerActionSearcher controllerActionSearcher,
|
||||
IEventAggregator eventAggregator)
|
||||
{
|
||||
if (globalSettings is null)
|
||||
{
|
||||
@@ -79,6 +82,7 @@ namespace Umbraco.Cms.Web.Website.Routing
|
||||
_routableDocumentFilter = routableDocumentFilter ?? throw new ArgumentNullException(nameof(routableDocumentFilter));
|
||||
_dataProtectionProvider = dataProtectionProvider;
|
||||
_controllerActionSearcher = controllerActionSearcher;
|
||||
_eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -117,6 +121,10 @@ namespace Umbraco.Cms.Web.Website.Routing
|
||||
// Store the route values as a httpcontext feature
|
||||
httpContext.Features.Set(umbracoRouteValues);
|
||||
|
||||
// publish an event that we've routed a request
|
||||
// TODO: does this occur on 404 or have we already returned?
|
||||
await _eventAggregator.PublishAsync(new UmbracoRoutedRequest(_umbracoContextAccessor.UmbracoContext));
|
||||
|
||||
// Need to check if there is form data being posted back to an Umbraco URL
|
||||
PostedDataProxyInfo postedInfo = GetFormInfo(httpContext, values);
|
||||
if (postedInfo != null)
|
||||
|
||||
Reference in New Issue
Block a user