diff --git a/src/Umbraco.Infrastructure/BackOffice/IdentityUser.cs b/src/Umbraco.Core/Models/Identity/IdentityUser.cs
similarity index 98%
rename from src/Umbraco.Infrastructure/BackOffice/IdentityUser.cs
rename to src/Umbraco.Core/Models/Identity/IdentityUser.cs
index 9de30360ae..093e42c1e7 100644
--- a/src/Umbraco.Infrastructure/BackOffice/IdentityUser.cs
+++ b/src/Umbraco.Core/Models/Identity/IdentityUser.cs
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
-using Umbraco.Core.Models.Identity;
-namespace Umbraco.Core.BackOffice
+namespace Umbraco.Core.Models.Identity
{
///
/// Default IUser implementation
diff --git a/src/Umbraco.Web/Security/BackOfficeClaimsPrincipalFactory.cs b/src/Umbraco.Infrastructure/BackOffice/BackOfficeClaimsPrincipalFactory.cs
similarity index 95%
rename from src/Umbraco.Web/Security/BackOfficeClaimsPrincipalFactory.cs
rename to src/Umbraco.Infrastructure/BackOffice/BackOfficeClaimsPrincipalFactory.cs
index fe22981831..a463a84d4b 100644
--- a/src/Umbraco.Web/Security/BackOfficeClaimsPrincipalFactory.cs
+++ b/src/Umbraco.Infrastructure/BackOffice/BackOfficeClaimsPrincipalFactory.cs
@@ -4,10 +4,9 @@ using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
-using Umbraco.Core.Security;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
-namespace Umbraco.Web.Security
+namespace Umbraco.Core.BackOffice
{
public class BackOfficeClaimsPrincipalFactory : UserClaimsPrincipalFactory
where TUser : BackOfficeIdentityUser
diff --git a/src/Umbraco.Infrastructure/BackOffice/BackOfficeIdentityUser.cs b/src/Umbraco.Infrastructure/BackOffice/BackOfficeIdentityUser.cs
index 4eca7a5e57..ea160ef1cf 100644
--- a/src/Umbraco.Infrastructure/BackOffice/BackOfficeIdentityUser.cs
+++ b/src/Umbraco.Infrastructure/BackOffice/BackOfficeIdentityUser.cs
@@ -89,8 +89,8 @@ namespace Umbraco.Core.BackOffice
///
public bool HasIdentity => _hasIdentity;
- public int[] CalculatedMediaStartNodeIds { get; internal set; }
- public int[] CalculatedContentStartNodeIds { get; internal set; }
+ public int[] CalculatedMediaStartNodeIds { get; set; }
+ public int[] CalculatedContentStartNodeIds { get; set; }
public override int Id
{
@@ -257,7 +257,7 @@ namespace Umbraco.Core.BackOffice
///
/// Based on the user's lockout end date, this will determine if they are locked out
///
- internal bool IsLockedOut
+ public bool IsLockedOut
{
get
{
@@ -269,7 +269,7 @@ namespace Umbraco.Core.BackOffice
///
/// This is a 1:1 mapping with IUser.IsApproved
///
- internal bool IsApproved { get; set; }
+ public bool IsApproved { get; set; }
///
/// Overridden to make the retrieval lazy
diff --git a/src/Umbraco.Infrastructure/BackOffice/UserLoginInfoWrapper.cs b/src/Umbraco.Infrastructure/BackOffice/UserLoginInfoWrapper.cs
index ab6af35519..a441d0299a 100644
--- a/src/Umbraco.Infrastructure/BackOffice/UserLoginInfoWrapper.cs
+++ b/src/Umbraco.Infrastructure/BackOffice/UserLoginInfoWrapper.cs
@@ -3,7 +3,7 @@ using Umbraco.Core.Models.Identity;
namespace Umbraco.Core.BackOffice
{
- internal class UserLoginInfoWrapper : IUserLoginInfo
+ public class UserLoginInfoWrapper : IUserLoginInfo
{
private readonly UserLoginInfo _info;
diff --git a/src/Umbraco.Tests/Security/NopLookupNormalizerTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/NopLookupNormalizerTests.cs
similarity index 97%
rename from src/Umbraco.Tests/Security/NopLookupNormalizerTests.cs
rename to src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/NopLookupNormalizerTests.cs
index 2abecbb4dd..1c4e08a4de 100644
--- a/src/Umbraco.Tests/Security/NopLookupNormalizerTests.cs
+++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/NopLookupNormalizerTests.cs
@@ -1,6 +1,6 @@
using System;
using NUnit.Framework;
-using Umbraco.Web.Security;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Tests.Security
{
diff --git a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs
index 3b61f31b66..51fce283f8 100644
--- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs
+++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs
@@ -1,16 +1,9 @@
using System;
-using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Moq;
using NUnit.Framework;
using Umbraco.Extensions;
using Umbraco.Core.BackOffice;
-using Umbraco.Core.Cache;
-using Umbraco.Core.Composing;
-using Umbraco.Tests.Integration.Extensions;
-using Umbraco.Tests.Integration.Implementations;
using Umbraco.Tests.Integration.Testing;
namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Extensions
@@ -27,6 +20,15 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Extensions
Assert.AreEqual(typeof(BackOfficeUserStore), userStore.GetType());
}
+ [Test]
+ public void AddUmbracoBackOfficeIdentity_ExpectBackOfficeClaimsPrincipalFactoryResolvable()
+ {
+ var principalFactory = Services.GetService>();
+
+ Assert.IsNotNull(principalFactory);
+ Assert.AreEqual(typeof(BackOfficeClaimsPrincipalFactory), principalFactory.GetType());
+ }
+
[Test]
public void AddUmbracoBackOfficeIdentity_ExpectBackOfficeUserManagerResolvable()
{
diff --git a/src/Umbraco.Tests/Security/BackOfficeClaimsPrincipalFactoryTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/BackOfficeClaimsPrincipalFactoryTests.cs
similarity index 95%
rename from src/Umbraco.Tests/Security/BackOfficeClaimsPrincipalFactoryTests.cs
rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/BackOfficeClaimsPrincipalFactoryTests.cs
index b7b516318c..3c01f89554 100644
--- a/src/Umbraco.Tests/Security/BackOfficeClaimsPrincipalFactoryTests.cs
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/BackOfficeClaimsPrincipalFactoryTests.cs
@@ -7,13 +7,12 @@ using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.Membership;
-using Umbraco.Core.Security;
-using Umbraco.Web.Models.Identity;
-using Umbraco.Web.Security;
+using Umbraco.Extensions;
-namespace Umbraco.Tests.Security
+namespace Umbraco.Tests.UnitTests.Umbraco.Core.BackOffice
{
[TestFixture]
public class BackOfficeClaimsPrincipalFactoryTests
@@ -131,7 +130,7 @@ namespace Umbraco.Tests.Security
const string expectedClaimType = ClaimTypes.Role;
const string expectedClaimValue = "b87309fb-4caf-48dc-b45a-2b752d051508";
- _testUser.Roles.Add(new Core.Models.Identity.IdentityUserRole{RoleId = expectedClaimValue});
+ _testUser.Roles.Add(new global::Umbraco.Core.Models.Identity.IdentityUserRole{RoleId = expectedClaimValue});
_mockUserManager.Setup(x => x.SupportsUserRole).Returns(true);
_mockUserManager.Setup(x => x.GetRolesAsync(_testUser)).ReturnsAsync(new[] {expectedClaimValue});
@@ -148,7 +147,7 @@ namespace Umbraco.Tests.Security
const string expectedClaimType = "custom";
const string expectedClaimValue = "val";
- _testUser.Claims.Add(new Core.Models.Identity.IdentityUserClaim {ClaimType = expectedClaimType, ClaimValue = expectedClaimValue});
+ _testUser.Claims.Add(new global::Umbraco.Core.Models.Identity.IdentityUserClaim {ClaimType = expectedClaimType, ClaimValue = expectedClaimValue});
_mockUserManager.Setup(x => x.SupportsUserClaim).Returns(true);
_mockUserManager.Setup(x => x.GetClaimsAsync(_testUser)).ReturnsAsync(
new List {new Claim(expectedClaimType, expectedClaimValue)});
diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/NopLookupNormalizerTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/NopLookupNormalizerTests.cs
new file mode 100644
index 0000000000..e492b060b5
--- /dev/null
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/NopLookupNormalizerTests.cs
@@ -0,0 +1,56 @@
+using System;
+using NUnit.Framework;
+using Umbraco.Core.BackOffice;
+
+namespace Umbraco.Tests.UnitTests.Umbraco.Core.BackOffice
+{
+ public class NopLookupNormalizerTests
+ {
+ [Test]
+ [TestCase(null)]
+ [TestCase("")]
+ [TestCase(" ")]
+ public void NormalizeName_When_Name_Null_Or_Whitespace_Expect_Same_Returned(string name)
+ {
+ var sut = new NopLookupNormalizer();
+
+ var normalizedName = sut.NormalizeName(name);
+
+ Assert.AreEqual(name, normalizedName);
+ }
+
+ [Test]
+ public void NormalizeName_Expect_Input_Returned()
+ {
+ var name = Guid.NewGuid().ToString();
+ var sut = new NopLookupNormalizer();
+
+ var normalizedName = sut.NormalizeName(name);
+
+ Assert.AreEqual(name, normalizedName);
+ }
+ [Test]
+ [TestCase(null)]
+ [TestCase("")]
+ [TestCase(" ")]
+ public void NormalizeEmail_When_Name_Null_Or_Whitespace_Expect_Same_Returned(string email)
+ {
+ var sut = new NopLookupNormalizer();
+
+ var normalizedEmail = sut.NormalizeEmail(email);
+
+ Assert.AreEqual(email, normalizedEmail);
+ }
+
+ [Test]
+ public void NormalizeEmail_Expect_Input_Returned()
+ {
+ var email = $"{Guid.NewGuid()}@umbraco";
+ var sut = new NopLookupNormalizer();
+
+ var normalizedEmail = sut.NormalizeEmail(email);
+
+ Assert.AreEqual(email, normalizedEmail);
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Security/UmbracoBackOfficeIdentityTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/UmbracoBackOfficeIdentityTests.cs
similarity index 97%
rename from src/Umbraco.Tests/Security/UmbracoBackOfficeIdentityTests.cs
rename to src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/UmbracoBackOfficeIdentityTests.cs
index 9c16d0c35a..5d0cec0e6e 100644
--- a/src/Umbraco.Tests/Security/UmbracoBackOfficeIdentityTests.cs
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/BackOffice/UmbracoBackOfficeIdentityTests.cs
@@ -1,16 +1,11 @@
using System;
using System.Linq;
using System.Security.Claims;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web.Security;
-using Newtonsoft.Json;
using NUnit.Framework;
using Umbraco.Core;
-using Umbraco.Core.Security;
-using Umbraco.Core.Services;
+using Umbraco.Core.BackOffice;
-namespace Umbraco.Tests.Security
+namespace Umbraco.Tests.UnitTests.Umbraco.Core.BackOffice
{
[TestFixture]
public class UmbracoBackOfficeIdentityTests
diff --git a/src/Umbraco.Tests/Security/BackOfficeUserManagerTests.cs b/src/Umbraco.Tests/Security/BackOfficeUserManagerTests.cs
index 30ed101297..99a2b323dd 100644
--- a/src/Umbraco.Tests/Security/BackOfficeUserManagerTests.cs
+++ b/src/Umbraco.Tests/Security/BackOfficeUserManagerTests.cs
@@ -6,11 +6,11 @@ using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Owin.Security.DataProtection;
using Moq;
using NUnit.Framework;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.Membership;
using Umbraco.Net;
-using Umbraco.Web.Models.Identity;
-using Umbraco.Web.Security;
+using BackOfficeUserManager = Umbraco.Web.Security.BackOfficeUserManager;
namespace Umbraco.Tests.Security
{
diff --git a/src/Umbraco.Tests/Security/OwinDataProtectorTokenProviderTests.cs b/src/Umbraco.Tests/Security/OwinDataProtectorTokenProviderTests.cs
index 5e9b731aa9..7b1ca53104 100644
--- a/src/Umbraco.Tests/Security/OwinDataProtectorTokenProviderTests.cs
+++ b/src/Umbraco.Tests/Security/OwinDataProtectorTokenProviderTests.cs
@@ -6,9 +6,9 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Owin.Security.DataProtection;
using Moq;
using NUnit.Framework;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.Membership;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Security;
namespace Umbraco.Tests.Security
diff --git a/src/Umbraco.Tests/Security/UmbracoSecurityStampValidatorTests.cs b/src/Umbraco.Tests/Security/UmbracoSecurityStampValidatorTests.cs
index 92fa032271..4adfe15ad7 100644
--- a/src/Umbraco.Tests/Security/UmbracoSecurityStampValidatorTests.cs
+++ b/src/Umbraco.Tests/Security/UmbracoSecurityStampValidatorTests.cs
@@ -11,18 +11,19 @@ using Microsoft.Owin.Security.Cookies;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.Membership;
using Umbraco.Net;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Security;
+
namespace Umbraco.Tests.Security
{
public class UmbracoSecurityStampValidatorTests
{
private Mock _mockOwinContext;
- private Mock> _mockUserManager;
+ private Mock> _mockUserManager;
private Mock _mockSignInManager;
private AuthenticationTicket _testAuthTicket;
@@ -34,7 +35,7 @@ namespace Umbraco.Tests.Security
public void OnValidateIdentity_When_GetUserIdCallback_Is_Null_Expect_ArgumentNullException()
{
Assert.Throws(() => UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MaxValue, null, null));
}
@@ -42,7 +43,7 @@ namespace Umbraco.Tests.Security
public async Task OnValidateIdentity_When_Validation_Interval_Not_Met_Expect_No_Op()
{
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MaxValue, null, identity => throw new Exception());
_testAuthTicket.Properties.IssuedUtc = DateTimeOffset.UtcNow;
@@ -61,11 +62,11 @@ namespace Umbraco.Tests.Security
public void OnValidateIdentity_When_Time_To_Validate_But_No_UserManager_Expect_InvalidOperationException()
{
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MinValue, null, identity => throw new Exception());
- _mockOwinContext.Setup(x => x.Get>(It.IsAny()))
- .Returns((BackOfficeUserManager) null);
+ _mockOwinContext.Setup(x => x.Get>(It.IsAny()))
+ .Returns((Umbraco.Web.Security.BackOfficeUserManager) null);
var context = new CookieValidateIdentityContext(
_mockOwinContext.Object,
@@ -79,7 +80,7 @@ namespace Umbraco.Tests.Security
public void OnValidateIdentity_When_Time_To_Validate_But_No_SignInManager_Expect_InvalidOperationException()
{
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MinValue, null, identity => throw new Exception());
_mockOwinContext.Setup(x => x.Get(It.IsAny()))
@@ -99,7 +100,7 @@ namespace Umbraco.Tests.Security
var userId = Guid.NewGuid().ToString();
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MinValue, null, identity => userId);
_mockUserManager.Setup(x => x.FindByIdAsync(userId))
@@ -122,7 +123,7 @@ namespace Umbraco.Tests.Security
var userId = Guid.NewGuid().ToString();
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MinValue, null, identity => userId);
_mockUserManager.Setup(x => x.FindByIdAsync(userId)).ReturnsAsync(_testUser);
@@ -145,7 +146,7 @@ namespace Umbraco.Tests.Security
var userId = Guid.NewGuid().ToString();
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MinValue, null, identity => userId);
_mockUserManager.Setup(x => x.FindByIdAsync(userId)).ReturnsAsync(_testUser);
@@ -169,7 +170,7 @@ namespace Umbraco.Tests.Security
var userId = Guid.NewGuid().ToString();
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MinValue, null, identity => userId);
_mockUserManager.Setup(x => x.FindByIdAsync(userId)).ReturnsAsync(_testUser);
@@ -193,7 +194,7 @@ namespace Umbraco.Tests.Security
var expectedIdentity = new ClaimsIdentity(new List {new Claim("sub", "bob")});
var regenFuncCalled = false;
- Func, BackOfficeIdentityUser, Task> regenFunc =
+ Func, BackOfficeIdentityUser, Task> regenFunc =
(signInManager, userManager, user) =>
{
regenFuncCalled = true;
@@ -201,7 +202,7 @@ namespace Umbraco.Tests.Security
};
var func = UmbracoSecurityStampValidator
- .OnValidateIdentity, BackOfficeIdentityUser>(
+ .OnValidateIdentity, BackOfficeIdentityUser>(
TimeSpan.MinValue, regenFunc, identity => userId);
_mockUserManager.Setup(x => x.FindByIdAsync(userId)).ReturnsAsync(_testUser);
@@ -249,7 +250,7 @@ namespace Umbraco.Tests.Security
new AuthenticationProperties());
_testOptions = new CookieAuthenticationOptions { AuthenticationType = _testAuthType };
- _mockUserManager = new Mock>(
+ _mockUserManager = new Mock>(
new Mock().Object,
new Mock().Object,
new Mock>().Object,
@@ -266,7 +267,7 @@ namespace Umbraco.Tests.Security
new Mock().Object);
_mockOwinContext = new Mock();
- _mockOwinContext.Setup(x => x.Get>(It.IsAny()))
+ _mockOwinContext.Setup(x => x.Get>(It.IsAny()))
.Returns(_mockUserManager.Object);
_mockOwinContext.Setup(x => x.Get(It.IsAny()))
.Returns(_mockSignInManager.Object);
diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/AuthenticateEverythingMiddleware.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/AuthenticateEverythingMiddleware.cs
index 5031d178bf..72941633e7 100644
--- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/AuthenticateEverythingMiddleware.cs
+++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/AuthenticateEverythingMiddleware.cs
@@ -4,7 +4,7 @@ using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;
using Owin;
-using Umbraco.Core.Security;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Tests.TestHelpers.ControllerTesting
{
diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs
index 66310caea9..793d31a5d3 100644
--- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs
+++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs
@@ -8,6 +8,7 @@ using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
using System.Web.Security;
using Moq;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Dictionary;
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 77aba483d7..22f5348501 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -147,10 +147,8 @@
-
-
@@ -275,7 +273,6 @@
-
diff --git a/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs
index 8c40085e50..80deb5a800 100644
--- a/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs
+++ b/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs
@@ -28,7 +28,6 @@ using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.ControllerTesting;
@@ -46,8 +45,8 @@ using Umbraco.Web.Routing;
using Umbraco.Core.Media;
using Umbraco.Net;
using Umbraco.Persistance.SqlCe;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Security;
+using BackOfficeIdentityUser = Umbraco.Core.BackOffice.BackOfficeIdentityUser;
namespace Umbraco.Tests.Web.Controllers
{
diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
index bce46b3129..d776749e6b 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
@@ -14,7 +14,6 @@ using Umbraco.Core.WebAssets;
using Umbraco.Net;
using Umbraco.Web.BackOffice.ActionResults;
using Umbraco.Web.BackOffice.Filters;
-using Umbraco.Web.BackOffice.Identity;
using Umbraco.Web.Common.ActionResults;
using Umbraco.Web.WebAssets;
diff --git a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeServiceCollectionExtensions.cs
index 9d3e2a9e3f..4325e10622 100644
--- a/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeServiceCollectionExtensions.cs
+++ b/src/Umbraco.Web.BackOffice/Extensions/UmbracoBackOfficeServiceCollectionExtensions.cs
@@ -2,6 +2,7 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
using Umbraco.Core;
using Umbraco.Core.BackOffice;
using Umbraco.Core.Mapping;
@@ -14,14 +15,17 @@ namespace Umbraco.Extensions
{
public static void AddUmbracoBackOfficeIdentity(this IServiceCollection services)
{
+ services.AddDataProtection();
+
// UmbracoMapper - hack?
- services.AddSingleton();
- services.AddSingleton(s => new MapDefinitionCollection(new[] {s.GetService()}));
- services.AddSingleton();
+ services.TryAddSingleton();
+ services.TryAddSingleton(s => new MapDefinitionCollection(new[] {s.GetService()}));
+ services.TryAddSingleton();
- services.AddScoped();
+ services.TryAddScoped();
- services.AddIdentity(options =>
+ services.AddIdentityCore();
+ services.AddIdentityCore(options =>
{
options.User.RequireUniqueEmail = true;
@@ -43,9 +47,12 @@ namespace Umbraco.Extensions
})
.AddDefaultTokenProviders()
.AddUserStore()
- .AddUserManager();
+ .AddUserManager()
+ .AddClaimsPrincipalFactory>();
+
+ services.AddScoped();
+ services.TryAddScoped>();
- // .AddClaimsPrincipalFactory>() // TODO: extract custom claims principal factory
}
}
}
diff --git a/src/Umbraco.Web/Compose/AuditEventsComponent.cs b/src/Umbraco.Web/Compose/AuditEventsComponent.cs
index bd2520aa90..51c47233c7 100644
--- a/src/Umbraco.Web/Compose/AuditEventsComponent.cs
+++ b/src/Umbraco.Web/Compose/AuditEventsComponent.cs
@@ -8,10 +8,9 @@ using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Net;
-using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
-using Umbraco.Web.Security;
+using Umbraco.Extensions;
namespace Umbraco.Core.Compose
{
diff --git a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs
index 21a242ee17..44d86df59c 100644
--- a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs
+++ b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs
@@ -1,7 +1,7 @@
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Composing;
using Umbraco.Core.Mapping;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Models.Mapping;
namespace Umbraco.Web.Composing.CompositionExtensions
diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs
index 009d970fd5..b38bbbb19d 100644
--- a/src/Umbraco.Web/Editors/AuthenticationController.cs
+++ b/src/Umbraco.Web/Editors/AuthenticationController.cs
@@ -19,15 +19,14 @@ using Umbraco.Web.Mvc;
using Umbraco.Web.Security;
using Umbraco.Web.WebApi;
using Umbraco.Web.WebApi.Filters;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using IUser = Umbraco.Core.Models.Membership.IUser;
using Umbraco.Core.Mapping;
-using Umbraco.Web.Models.Identity;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Hosting;
-using Umbraco.Core.IO;
using Umbraco.Web.Routing;
namespace Umbraco.Web.Editors
@@ -41,7 +40,7 @@ namespace Umbraco.Web.Editors
[IsBackOffice]
public class AuthenticationController : UmbracoApiController
{
- private BackOfficeUserManager _userManager;
+ private Security.BackOfficeUserManager _userManager;
private BackOfficeSignInManager _signInManager;
private readonly IUserPasswordConfiguration _passwordConfiguration;
private readonly IHostingEnvironment _hostingEnvironment;
@@ -72,8 +71,8 @@ namespace Umbraco.Web.Editors
_requestAccessor = requestAccessor ?? throw new ArgumentNullException(nameof(securitySettings));
}
- protected BackOfficeUserManager UserManager => _userManager
- ?? (_userManager = TryGetOwinContext().Result.GetBackOfficeUserManager());
+ protected Security.BackOfficeUserManager UserManager => _userManager
+ ?? (_userManager = TryGetOwinContext().Result.GetBackOfficeUserManager());
protected BackOfficeSignInManager SignInManager => _signInManager
?? (_signInManager = TryGetOwinContext().Result.GetBackOfficeSignInManager());
diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs
index 825b67767a..782dea61ac 100644
--- a/src/Umbraco.Web/Editors/BackOfficeController.cs
+++ b/src/Umbraco.Web/Editors/BackOfficeController.cs
@@ -20,7 +20,6 @@ using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Core.Services;
using Umbraco.Web.Features;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Security;
using Constants = Umbraco.Core.Constants;
using JArray = Newtonsoft.Json.Linq.JArray;
@@ -32,6 +31,7 @@ using Umbraco.Core.Runtime;
using Umbraco.Core.WebAssets;
using Umbraco.Web.Trees;
using Umbraco.Web.WebAssets;
+using BackOfficeIdentityUser = Umbraco.Core.BackOffice.BackOfficeIdentityUser;
namespace Umbraco.Web.Editors
{
diff --git a/src/Umbraco.Web/Editors/PasswordChanger.cs b/src/Umbraco.Web/Editors/PasswordChanger.cs
index b6757f76cc..10a5248045 100644
--- a/src/Umbraco.Web/Editors/PasswordChanger.cs
+++ b/src/Umbraco.Web/Editors/PasswordChanger.cs
@@ -2,12 +2,10 @@
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
-using Umbraco.Core.Models.Identity;
-using Umbraco.Core.Security;
using Umbraco.Web.Models;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Security;
using IUser = Umbraco.Core.Models.Membership.IUser;
@@ -34,7 +32,7 @@ namespace Umbraco.Web.Editors
IUser currentUser,
IUser savingUser,
ChangingPasswordModel passwordModel,
- BackOfficeUserManager userMgr)
+ Security.BackOfficeUserManager userMgr)
{
if (passwordModel == null) throw new ArgumentNullException(nameof(passwordModel));
if (userMgr == null) throw new ArgumentNullException(nameof(userMgr));
diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs
index e695139b8c..8a3156dd2d 100644
--- a/src/Umbraco.Web/Editors/UsersController.cs
+++ b/src/Umbraco.Web/Editors/UsersController.cs
@@ -11,6 +11,7 @@ using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
@@ -24,7 +25,6 @@ using Umbraco.Core.Strings;
using Umbraco.Web.Editors.Filters;
using Umbraco.Web.Models;
using Umbraco.Web.Models.ContentEditing;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
using Umbraco.Web.WebApi.Filters;
diff --git a/src/Umbraco.Web/Models/Identity/BackOfficeIdentityUser.cs b/src/Umbraco.Web/Models/Identity/BackOfficeIdentityUser.cs
deleted file mode 100644
index 21c965aa3d..0000000000
--- a/src/Umbraco.Web/Models/Identity/BackOfficeIdentityUser.cs
+++ /dev/null
@@ -1,434 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Collections.Specialized;
-using System.ComponentModel;
-using System.Linq;
-using Umbraco.Core;
-using Umbraco.Core.Configuration;
-using Umbraco.Core.Models.Entities;
-using Umbraco.Core.Models.Identity;
-using Umbraco.Core.Models.Membership;
-
-namespace Umbraco.Web.Models.Identity
-{
- public class BackOfficeIdentityUser : IdentityUser, IdentityUserClaim>, IRememberBeingDirty
- {
- private string _email;
- private string _userName;
- private int _id;
- private bool _hasIdentity;
- private DateTime? _lastLoginDateUtc;
- private bool _emailConfirmed;
- private string _name;
- private int _accessFailedCount;
- private string _passwordHash;
- private string _culture;
- private ObservableCollection _logins;
- private Lazy> _getLogins;
- private IReadOnlyUserGroup[] _groups;
- private string[] _allowedSections;
- private int[] _startMediaIds;
- private int[] _startContentIds;
- private DateTime? _lastPasswordChangeDateUtc;
-
- ///
- /// Used to construct a new instance without an identity
- ///
- ///
- /// This is allowed to be null (but would need to be filled in if trying to persist this instance)
- ///
- ///
- public static BackOfficeIdentityUser CreateNew(IGlobalSettings globalSettings, string username, string email, string culture)
- {
- if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(username));
- if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(culture));
-
- var user = new BackOfficeIdentityUser(globalSettings, Array.Empty());
- user.DisableChangeTracking();
- user._userName = username;
- user._email = email;
- //we are setting minvalue here because the default is "0" which is the id of the admin user
- //which we cannot allow because the admin user will always exist
- user._id = int.MinValue;
- user._hasIdentity = false;
- user._culture = culture;
- user.EnableChangeTracking();
- return user;
- }
-
- private BackOfficeIdentityUser(IGlobalSettings globalSettings, IReadOnlyUserGroup[] groups)
- {
- _startMediaIds = Array.Empty();
- _startContentIds = Array.Empty();
- _allowedSections = Array.Empty();
- _culture = globalSettings.DefaultUILanguage;
-
- // must initialize before setting groups
- _roles = new ObservableCollection>();
- _roles.CollectionChanged += _roles_CollectionChanged;
-
- // use the property setters - they do more than just setting a field
- Groups = groups;
- }
-
- ///
- /// Creates an existing user with the specified groups
- ///
- ///
- ///
- ///
- public BackOfficeIdentityUser(IGlobalSettings globalSettings, int userId, IEnumerable groups)
- : this(globalSettings, groups.ToArray())
- {
- // use the property setters - they do more than just setting a field
- Id = userId;
- }
-
- ///
- /// Returns true if an Id has been set on this object this will be false if the object is new and not persisted to the database
- ///
- public bool HasIdentity => _hasIdentity;
-
- public int[] CalculatedMediaStartNodeIds { get; internal set; }
- public int[] CalculatedContentStartNodeIds { get; internal set; }
-
- public override int Id
- {
- get => _id;
- set
- {
- _id = value;
- _hasIdentity = true;
- }
- }
-
- ///
- /// Override Email so we can track changes to it
- ///
- public override string Email
- {
- get => _email;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _email, nameof(Email));
- }
-
- ///
- /// Override UserName so we can track changes to it
- ///
- public override string UserName
- {
- get => _userName;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _userName, nameof(UserName));
- }
-
- ///
- /// LastPasswordChangeDateUtc so we can track changes to it
- ///
- public override DateTime? LastPasswordChangeDateUtc
- {
- get { return _lastPasswordChangeDateUtc; }
- set { _beingDirty.SetPropertyValueAndDetectChanges(value, ref _lastPasswordChangeDateUtc, nameof(LastPasswordChangeDateUtc)); }
- }
-
- ///
- /// Override LastLoginDateUtc so we can track changes to it
- ///
- public override DateTime? LastLoginDateUtc
- {
- get => _lastLoginDateUtc;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _lastLoginDateUtc, nameof(LastLoginDateUtc));
- }
-
- ///
- /// Override EmailConfirmed so we can track changes to it
- ///
- public override bool EmailConfirmed
- {
- get => _emailConfirmed;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _emailConfirmed, nameof(EmailConfirmed));
- }
-
- ///
- /// Gets/sets the user's real name
- ///
- public string Name
- {
- get => _name;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name));
- }
-
- ///
- /// Override AccessFailedCount so we can track changes to it
- ///
- public override int AccessFailedCount
- {
- get => _accessFailedCount;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _accessFailedCount, nameof(AccessFailedCount));
- }
-
- ///
- /// Override PasswordHash so we can track changes to it
- ///
- public override string PasswordHash
- {
- get => _passwordHash;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _passwordHash, nameof(PasswordHash));
- }
-
-
- ///
- /// Content start nodes assigned to the User (not ones assigned to the user's groups)
- ///
- public int[] StartContentIds
- {
- get => _startContentIds;
- set
- {
- if (value == null) value = new int[0];
- _beingDirty.SetPropertyValueAndDetectChanges(value, ref _startContentIds, nameof(StartContentIds), StartIdsComparer);
- }
- }
-
- ///
- /// Media start nodes assigned to the User (not ones assigned to the user's groups)
- ///
- public int[] StartMediaIds
- {
- get => _startMediaIds;
- set
- {
- if (value == null) value = new int[0];
- _beingDirty.SetPropertyValueAndDetectChanges(value, ref _startMediaIds, nameof(StartMediaIds), StartIdsComparer);
- }
- }
-
- ///
- /// This is a readonly list of the user's allowed sections which are based on it's user groups
- ///
- public string[] AllowedSections
- {
- get { return _allowedSections ?? (_allowedSections = _groups.SelectMany(x => x.AllowedSections).Distinct().ToArray()); }
- }
-
- public string Culture
- {
- get => _culture;
- set => _beingDirty.SetPropertyValueAndDetectChanges(value, ref _culture, nameof(Culture));
- }
-
- public IReadOnlyUserGroup[] Groups
- {
- get => _groups;
- set
- {
- //so they recalculate
- _allowedSections = null;
-
- _groups = value;
-
- //now clear all roles and re-add them
- _roles.CollectionChanged -= _roles_CollectionChanged;
- _roles.Clear();
- foreach (var identityUserRole in _groups.Select(x => new IdentityUserRole
- {
- RoleId = x.Alias,
- UserId = Id.ToString()
- }))
- {
- _roles.Add(identityUserRole);
- }
- _roles.CollectionChanged += _roles_CollectionChanged;
-
- _beingDirty.SetPropertyValueAndDetectChanges(value, ref _groups, nameof(Groups), GroupsComparer);
- }
- }
-
- ///
- /// Lockout is always enabled
- ///
- public override bool LockoutEnabled
- {
- get { return true; }
- set
- {
- //do nothing
- }
- }
-
- ///
- /// Based on the user's lockout end date, this will determine if they are locked out
- ///
- internal bool IsLockedOut
- {
- get
- {
- var isLocked = LockoutEndDateUtc.HasValue && LockoutEndDateUtc.Value.ToLocalTime() >= DateTime.Now;
- return isLocked;
- }
- }
-
- ///
- /// This is a 1:1 mapping with IUser.IsApproved
- ///
- internal bool IsApproved { get; set; }
-
- ///
- /// Overridden to make the retrieval lazy
- ///
- public override ICollection Logins
- {
- get
- {
- if (_getLogins != null && _getLogins.IsValueCreated == false)
- {
- _logins = new ObservableCollection();
- foreach (var l in _getLogins.Value)
- {
- _logins.Add(l);
- }
- //now assign events
- _logins.CollectionChanged += Logins_CollectionChanged;
- }
- return _logins;
- }
- }
-
- void Logins_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- _beingDirty.OnPropertyChanged(nameof(Logins));
- }
-
- private void _roles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- _beingDirty.OnPropertyChanged(nameof(Roles));
- }
-
- private readonly ObservableCollection> _roles;
-
- ///
- /// helper method to easily add a role without having to deal with IdentityUserRole{T}
- ///
- ///
- ///
- /// Adding a role this way will not reflect on the user's group's collection or it's allowed sections until the user is persisted
- ///
- public void AddRole(string role)
- {
- Roles.Add(new IdentityUserRole
- {
- UserId = Id.ToString(),
- RoleId = role
- });
- }
-
- ///
- /// Override Roles because the value of these are the user's group aliases
- ///
- public override ICollection> Roles => _roles;
-
- ///
- /// Used to set a lazy call back to populate the user's Login list
- ///
- ///
- public void SetLoginsCallback(Lazy> callback)
- {
- _getLogins = callback ?? throw new ArgumentNullException(nameof(callback));
- }
-
- #region BeingDirty
-
- private readonly BeingDirty _beingDirty = new BeingDirty();
-
- ///
- public bool IsDirty()
- {
- return _beingDirty.IsDirty();
- }
-
- ///
- public bool IsPropertyDirty(string propName)
- {
- return _beingDirty.IsPropertyDirty(propName);
- }
-
- ///
- public IEnumerable GetDirtyProperties()
- {
- return _beingDirty.GetDirtyProperties();
- }
-
- ///
- public void ResetDirtyProperties()
- {
- _beingDirty.ResetDirtyProperties();
- }
-
- ///
- public bool WasDirty()
- {
- return _beingDirty.WasDirty();
- }
-
- ///
- public bool WasPropertyDirty(string propertyName)
- {
- return _beingDirty.WasPropertyDirty(propertyName);
- }
-
- ///
- public void ResetWereDirtyProperties()
- {
- _beingDirty.ResetWereDirtyProperties();
- }
-
- ///
- public void ResetDirtyProperties(bool rememberDirty)
- {
- _beingDirty.ResetDirtyProperties(rememberDirty);
- }
-
- ///
- public IEnumerable GetWereDirtyProperties()
- => _beingDirty.GetWereDirtyProperties();
-
- ///
- /// Disables change tracking.
- ///
- public void DisableChangeTracking()
- {
- _beingDirty.DisableChangeTracking();
- }
-
- ///
- /// Enables change tracking.
- ///
- public void EnableChangeTracking()
- {
- _beingDirty.EnableChangeTracking();
- }
-
- public event PropertyChangedEventHandler PropertyChanged
- {
- add
- {
- _beingDirty.PropertyChanged += value;
- }
- remove
- {
- _beingDirty.PropertyChanged -= value;
- }
- }
-
- #endregion
-
- //Custom comparer for enumerables
- private static readonly DelegateEqualityComparer GroupsComparer = new DelegateEqualityComparer(
- (groups, enumerable) => groups.Select(x => x.Alias).UnsortedSequenceEqual(enumerable.Select(x => x.Alias)),
- groups => groups.GetHashCode());
-
- private static readonly DelegateEqualityComparer StartIdsComparer = new DelegateEqualityComparer(
- (groups, enumerable) => groups.UnsortedSequenceEqual(enumerable),
- groups => groups.GetHashCode());
-
- }
-}
diff --git a/src/Umbraco.Web/Models/Identity/IdentityMapDefinition.cs b/src/Umbraco.Web/Models/Identity/IdentityMapDefinition.cs
deleted file mode 100644
index 7c20c6108a..0000000000
--- a/src/Umbraco.Web/Models/Identity/IdentityMapDefinition.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using System;
-using Umbraco.Core;
-using Umbraco.Core.Configuration;
-using Umbraco.Core.Mapping;
-using Umbraco.Core.Models;
-using Umbraco.Core.Models.Membership;
-using Umbraco.Core.Services;
-
-namespace Umbraco.Web.Models.Identity
-{
- public class IdentityMapDefinition : IMapDefinition
- {
- private readonly ILocalizedTextService _textService;
- private readonly IEntityService _entityService;
- private readonly IGlobalSettings _globalSettings;
-
- public IdentityMapDefinition(ILocalizedTextService textService, IEntityService entityService, IGlobalSettings globalSettings)
- {
- _textService = textService;
- _entityService = entityService;
- _globalSettings = globalSettings;
- }
-
- public void DefineMaps(UmbracoMapper mapper)
- {
- mapper.Define(
- (source, context) =>
- {
- var target = new BackOfficeIdentityUser(_globalSettings, source.Id, source.Groups);
- target.DisableChangeTracking();
- return target;
- },
- (source, target, context) =>
- {
- Map(source, target);
- target.ResetDirtyProperties(true);
- target.EnableChangeTracking();
- });
- }
-
- // Umbraco.Code.MapAll -Id -Groups -LockoutEnabled -PhoneNumber -PhoneNumberConfirmed -TwoFactorEnabled
- private void Map(IUser source, BackOfficeIdentityUser target)
- {
- // well, the ctor has been fixed
- /*
- // these two are already set in ctor but BackOfficeIdentityUser ctor is CompletelyBroken
- target.Id = source.Id;
- target.Groups = source.Groups.ToArray();
- */
-
- target.CalculatedMediaStartNodeIds = source.CalculateMediaStartNodeIds(_entityService);
- target.CalculatedContentStartNodeIds = source.CalculateContentStartNodeIds(_entityService);
- target.Email = source.Email;
- target.UserName = source.Username;
- target.LastPasswordChangeDateUtc = source.LastPasswordChangeDate.ToUniversalTime();
- target.LastLoginDateUtc = source.LastLoginDate.ToUniversalTime();
- target.EmailConfirmed = source.EmailConfirmedDate.HasValue;
- target.Name = source.Name;
- target.AccessFailedCount = source.FailedPasswordAttempts;
- target.PasswordHash = GetPasswordHash(source.RawPasswordValue);
- target.StartContentIds = source.StartContentIds;
- target.StartMediaIds = source.StartMediaIds;
- target.Culture = source.GetUserCulture(_textService, _globalSettings).ToString(); // project CultureInfo to string
- target.IsApproved = source.IsApproved;
- target.SecurityStamp = source.SecurityStamp;
- target.LockoutEndDateUtc = source.IsLockedOut ? DateTime.MaxValue.ToUniversalTime() : (DateTime?) null;
-
- // this was in AutoMapper but does not have a setter anyways
- //target.AllowedSections = source.AllowedSections.ToArray(),
-
- // these were marked as ignored for AutoMapper but don't have a setter anyways
- //target.Logins =;
- //target.Claims =;
- //target.Roles =;
- }
-
- private static string GetPasswordHash(string storedPass)
- {
- return storedPass.StartsWith(Constants.Security.EmptyPasswordPrefix) ? null : storedPass;
- }
- }
-}
diff --git a/src/Umbraco.Web/Models/Identity/IdentityUser.cs b/src/Umbraco.Web/Models/Identity/IdentityUser.cs
deleted file mode 100644
index 7bd077e879..0000000000
--- a/src/Umbraco.Web/Models/Identity/IdentityUser.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Umbraco.Core.Models.Identity;
-
-namespace Umbraco.Web.Models.Identity
-{
- ///
- /// Default IUser implementation
- ///
- ///
- ///
- /// This class normally exists inside of the EntityFramework library, not sure why MS chose to explicitly put it there but we don't want
- /// references to that so we will create our own here
- ///
- public class IdentityUser
- where TLogin : IIdentityUserLogin
- //NOTE: Making our role id a string
- where TRole : IdentityUserRole
- where TClaim : IdentityUserClaim
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public IdentityUser()
- {
- Claims = new List();
- Roles = new List();
- Logins = new List();
- }
-
- ///
- /// Last login date
- ///
- public virtual DateTime? LastLoginDateUtc { get; set; }
-
- ///
- /// Email
- ///
- public virtual string Email { get; set; }
-
- ///
- /// True if the email is confirmed, default is false
- ///
- public virtual bool EmailConfirmed { get; set; }
-
- ///
- /// The salted/hashed form of the user password
- ///
- public virtual string PasswordHash { get; set; }
-
- ///
- /// A random value that should change whenever a users credentials have changed (password changed, login removed)
- ///
- public virtual string SecurityStamp { get; set; }
-
- ///
- /// PhoneNumber for the user
- ///
- public virtual string PhoneNumber { get; set; }
-
- ///
- /// True if the phone number is confirmed, default is false
- ///
- public virtual bool PhoneNumberConfirmed { get; set; }
-
- ///
- /// Is two factor enabled for the user
- ///
- public virtual bool TwoFactorEnabled { get; set; }
-
- ///
- /// DateTime in UTC when lockout ends, any time in the past is considered not locked out.
- ///
- public virtual DateTime? LockoutEndDateUtc { get; set; }
-
- ///
- /// DateTime in UTC when the password was last changed.
- ///
- public virtual DateTime? LastPasswordChangeDateUtc { get; set; }
-
- ///
- /// Is lockout enabled for this user
- ///
- public virtual bool LockoutEnabled { get; set; }
-
- ///
- /// Used to record failures for the purposes of lockout
- ///
- public virtual int AccessFailedCount { get; set; }
-
- ///
- /// Navigation property for user roles
- ///
- public virtual ICollection Roles { get; }
-
- ///
- /// Navigation property for user claims
- ///
- public virtual ICollection Claims { get; }
-
- ///
- /// Navigation property for user logins
- ///
- public virtual ICollection Logins { get; }
-
- ///
- /// User ID (Primary Key)
- ///
- public virtual TKey Id { get; set; }
-
- ///
- /// User name
- ///
- public virtual string UserName { get; set; }
- }
-}
diff --git a/src/Umbraco.Web/Models/Identity/UserLoginInfoWrapper.cs b/src/Umbraco.Web/Models/Identity/UserLoginInfoWrapper.cs
deleted file mode 100644
index 336b4c9e72..0000000000
--- a/src/Umbraco.Web/Models/Identity/UserLoginInfoWrapper.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using Microsoft.AspNetCore.Identity;
-using Umbraco.Core.Models.Identity;
-
-namespace Umbraco.Web.Models.Identity
-{
- internal class UserLoginInfoWrapper : IUserLoginInfo
- {
- private readonly UserLoginInfo _info;
-
- public static IUserLoginInfo Wrap(UserLoginInfo info) => new UserLoginInfoWrapper(info);
-
- private UserLoginInfoWrapper(UserLoginInfo info)
- {
- _info = info;
- }
-
- public string LoginProvider
- {
- get => _info.LoginProvider;
- set => _info.LoginProvider = value;
- }
-
- public string ProviderKey
- {
- get => _info.ProviderKey;
- set => _info.ProviderKey = value;
- }
- }
-}
diff --git a/src/Umbraco.Web/OwinExtensions.cs b/src/Umbraco.Web/OwinExtensions.cs
index 52c1187707..67e9375ab5 100644
--- a/src/Umbraco.Web/OwinExtensions.cs
+++ b/src/Umbraco.Web/OwinExtensions.cs
@@ -3,8 +3,8 @@ using System.Web;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Umbraco.Core;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Security;
+using BackOfficeIdentityUser = Umbraco.Core.BackOffice.BackOfficeIdentityUser;
namespace Umbraco.Web
{
diff --git a/src/Umbraco.Web/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs b/src/Umbraco.Web/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs
index af7aebce3a..930cabeee3 100644
--- a/src/Umbraco.Web/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs
+++ b/src/Umbraco.Web/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs
@@ -1,8 +1,8 @@
using System;
using System.DirectoryServices.AccountManagement;
using System.Threading.Tasks;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
-using Umbraco.Web.Models.Identity;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/AppBuilderExtensions.cs b/src/Umbraco.Web/Security/AppBuilderExtensions.cs
index 3f129f941d..6254dabeb9 100644
--- a/src/Umbraco.Web/Security/AppBuilderExtensions.cs
+++ b/src/Umbraco.Web/Security/AppBuilderExtensions.cs
@@ -11,6 +11,7 @@ using Microsoft.Owin.Security.DataHandler;
using Microsoft.Owin.Security.DataProtection;
using Owin;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
@@ -19,7 +20,6 @@ using Umbraco.Core.Mapping;
using Umbraco.Net;
using Umbraco.Core.Services;
using Umbraco.Web.Composing;
-using Umbraco.Web.Models.Identity;
using Constants = Umbraco.Core.Constants;
namespace Umbraco.Web.Security
diff --git a/src/Umbraco.Web/Security/AuthenticationExtensions.cs b/src/Umbraco.Web/Security/AuthenticationExtensions.cs
index 7d76eaa7be..ee3b69c389 100644
--- a/src/Umbraco.Web/Security/AuthenticationExtensions.cs
+++ b/src/Umbraco.Web/Security/AuthenticationExtensions.cs
@@ -12,8 +12,9 @@ using Microsoft.Owin;
using Microsoft.Owin.Security;
using Newtonsoft.Json;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
+using Umbraco.Extensions;
using Umbraco.Web.Composing;
-using Umbraco.Core.Security;
using Constants = Umbraco.Core.Constants;
namespace Umbraco.Web.Security
@@ -333,38 +334,6 @@ namespace Umbraco.Web.Security
return secureDataFormat.Unprotect(formsCookie);
}
- ///
- /// This will return the current back office identity if the IPrincipal is the correct type
- ///
- ///
- ///
- public static UmbracoBackOfficeIdentity GetUmbracoIdentity(this IPrincipal user)
- {
- //If it's already a UmbracoBackOfficeIdentity
- if (user.Identity is UmbracoBackOfficeIdentity backOfficeIdentity) return backOfficeIdentity;
-
- //Check if there's more than one identity assigned and see if it's a UmbracoBackOfficeIdentity and use that
- if (user is ClaimsPrincipal claimsPrincipal)
- {
- backOfficeIdentity = claimsPrincipal.Identities.OfType().FirstOrDefault();
- if (backOfficeIdentity != null) return backOfficeIdentity;
- }
-
- //Otherwise convert to a UmbracoBackOfficeIdentity if it's auth'd and has the back office session
- if (user.Identity is ClaimsIdentity claimsIdentity && claimsIdentity.IsAuthenticated && claimsIdentity.HasClaim(x => x.Type == Constants.Security.SessionIdClaimType))
- {
- try
- {
- return UmbracoBackOfficeIdentity.FromClaimsIdentity(claimsIdentity);
- }
- catch (InvalidOperationException)
- {
- }
- }
-
- return null;
- }
-
///
/// Ensures that the thread culture is set based on the back office user's culture
///
diff --git a/src/Umbraco.Web/Security/BackOfficeCookieAuthenticationProvider.cs b/src/Umbraco.Web/Security/BackOfficeCookieAuthenticationProvider.cs
index 01f8dc4e96..35edb251f9 100644
--- a/src/Umbraco.Web/Security/BackOfficeCookieAuthenticationProvider.cs
+++ b/src/Umbraco.Web/Security/BackOfficeCookieAuthenticationProvider.cs
@@ -4,10 +4,8 @@ using System.Threading.Tasks;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Umbraco.Core;
-using Umbraco.Web.Composing;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
-using Umbraco.Core.IO;
-using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Hosting;
@@ -77,12 +75,12 @@ namespace Umbraco.Web.Security
Expires = DateTime.Now.AddYears(-1),
Path = "/"
});
- context.Response.Cookies.Append(Core.Constants.Web.PreviewCookieName, "", new CookieOptions
+ context.Response.Cookies.Append(Constants.Web.PreviewCookieName, "", new CookieOptions
{
Expires = DateTime.Now.AddYears(-1),
Path = "/"
});
- context.Response.Cookies.Append(Core.Constants.Security.BackOfficeExternalCookieName, "", new CookieOptions
+ context.Response.Cookies.Append(Constants.Security.BackOfficeExternalCookieName, "", new CookieOptions
{
Expires = DateTime.Now.AddYears(-1),
Path = "/"
diff --git a/src/Umbraco.Web/Security/BackOfficeSignInManager.cs b/src/Umbraco.Web/Security/BackOfficeSignInManager.cs
index bbb4328fc3..5e172d2d77 100644
--- a/src/Umbraco.Web/Security/BackOfficeSignInManager.cs
+++ b/src/Umbraco.Web/Security/BackOfficeSignInManager.cs
@@ -8,9 +8,9 @@ using Microsoft.Owin;
using Microsoft.Owin.Logging;
using Microsoft.Owin.Security;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
-using Umbraco.Core.Security;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/BackOfficeUserManager.cs b/src/Umbraco.Web/Security/BackOfficeUserManager.cs
index a143029327..ed2df536e7 100644
--- a/src/Umbraco.Web/Security/BackOfficeUserManager.cs
+++ b/src/Umbraco.Web/Security/BackOfficeUserManager.cs
@@ -8,12 +8,12 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Owin.Security.DataProtection;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Mapping;
using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Net;
-using Umbraco.Web.Models.Identity;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/BackOfficeUserManagerMarker.cs b/src/Umbraco.Web/Security/BackOfficeUserManagerMarker.cs
index b3eb9da3d5..d9d3f0e6f6 100644
--- a/src/Umbraco.Web/Security/BackOfficeUserManagerMarker.cs
+++ b/src/Umbraco.Web/Security/BackOfficeUserManagerMarker.cs
@@ -1,6 +1,6 @@
using System;
using Microsoft.Owin;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/BackOfficeUserStore.cs b/src/Umbraco.Web/Security/BackOfficeUserStore.cs
index 6f401163aa..d9d1900951 100644
--- a/src/Umbraco.Web/Security/BackOfficeUserStore.cs
+++ b/src/Umbraco.Web/Security/BackOfficeUserStore.cs
@@ -6,14 +6,13 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Identity;
using Umbraco.Core.Models.Membership;
-using Umbraco.Core.Security;
using Umbraco.Core.Services;
-using Umbraco.Web.Models.Identity;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/BackOfficeUserValidator.cs b/src/Umbraco.Web/Security/BackOfficeUserValidator.cs
index 94e9c2e0bd..951bdee4ed 100644
--- a/src/Umbraco.Web/Security/BackOfficeUserValidator.cs
+++ b/src/Umbraco.Web/Security/BackOfficeUserValidator.cs
@@ -1,6 +1,6 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/ExternalSignInAutoLinkOptions.cs b/src/Umbraco.Web/Security/ExternalSignInAutoLinkOptions.cs
index abe5aeb196..fc84cd270d 100644
--- a/src/Umbraco.Web/Security/ExternalSignInAutoLinkOptions.cs
+++ b/src/Umbraco.Web/Security/ExternalSignInAutoLinkOptions.cs
@@ -1,7 +1,7 @@
using System;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Web.Composing;
-using Umbraco.Web.Models.Identity;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/FixWindowsAuthMiddlware.cs b/src/Umbraco.Web/Security/FixWindowsAuthMiddlware.cs
index 30038e1f31..9bad4bec17 100644
--- a/src/Umbraco.Web/Security/FixWindowsAuthMiddlware.cs
+++ b/src/Umbraco.Web/Security/FixWindowsAuthMiddlware.cs
@@ -4,7 +4,7 @@ using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.Owin;
using Umbraco.Core;
-using Umbraco.Core.Security;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/IBackOfficeUserManagerMarker.cs b/src/Umbraco.Web/Security/IBackOfficeUserManagerMarker.cs
index bfe2590eb8..2b1f9927f2 100644
--- a/src/Umbraco.Web/Security/IBackOfficeUserManagerMarker.cs
+++ b/src/Umbraco.Web/Security/IBackOfficeUserManagerMarker.cs
@@ -1,5 +1,5 @@
using Microsoft.Owin;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/IBackOfficeUserPasswordChecker.cs b/src/Umbraco.Web/Security/IBackOfficeUserPasswordChecker.cs
index 9b9e7443be..2fae308eb0 100644
--- a/src/Umbraco.Web/Security/IBackOfficeUserPasswordChecker.cs
+++ b/src/Umbraco.Web/Security/IBackOfficeUserPasswordChecker.cs
@@ -1,6 +1,5 @@
using System.Threading.Tasks;
-using Umbraco.Core.Models.Identity;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/IUserSessionStore.cs b/src/Umbraco.Web/Security/IUserSessionStore.cs
deleted file mode 100644
index 06b7c2f165..0000000000
--- a/src/Umbraco.Web/Security/IUserSessionStore.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Identity;
-
-namespace Umbraco.Core.Security
-{
- ///
- /// An IUserStore interface part to implement if the store supports validating user session Ids
- ///
- ///
- public interface IUserSessionStore : IUserStore
- where TUser : class
- {
- Task ValidateSessionIdAsync(string userId, string sessionId);
- }
-}
diff --git a/src/Umbraco.Web/Security/IdentityAuditEventArgs.cs b/src/Umbraco.Web/Security/IdentityAuditEventArgs.cs
index 5847250b41..d37974276c 100644
--- a/src/Umbraco.Web/Security/IdentityAuditEventArgs.cs
+++ b/src/Umbraco.Web/Security/IdentityAuditEventArgs.cs
@@ -1,5 +1,6 @@
using System;
using System.Threading;
+using Umbraco.Extensions;
namespace Umbraco.Web.Security
diff --git a/src/Umbraco.Web/Security/NopLookupNormalizer.cs b/src/Umbraco.Web/Security/NopLookupNormalizer.cs
deleted file mode 100644
index 08aa8d548a..0000000000
--- a/src/Umbraco.Web/Security/NopLookupNormalizer.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Microsoft.AspNetCore.Identity;
-
-namespace Umbraco.Web.Security
-{
- ///
- /// No-op lookup normalizer to maintain compatibility with ASP.NET Identity 2
- ///
- public class NopLookupNormalizer : ILookupNormalizer
- {
- public string NormalizeName(string name) => name;
-
- public string NormalizeEmail(string email) => email;
- }
-}
diff --git a/src/Umbraco.Web/Security/OwinDataProtectorTokenProvider.cs b/src/Umbraco.Web/Security/OwinDataProtectorTokenProvider.cs
index 15bd4dfd75..72e12b8621 100644
--- a/src/Umbraco.Web/Security/OwinDataProtectorTokenProvider.cs
+++ b/src/Umbraco.Web/Security/OwinDataProtectorTokenProvider.cs
@@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Owin.Security.DataProtection;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs b/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs
index 2f9648d1f7..799edb5f60 100644
--- a/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs
+++ b/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs
@@ -1,12 +1,10 @@
using System.Security.Claims;
using System.Threading.Tasks;
-using System.Web;
using Microsoft.Owin;
using Umbraco.Core;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
-using Umbraco.Core.IO;
-using Umbraco.Core.Security;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/UmbracoBackOfficeIdentity.cs b/src/Umbraco.Web/Security/UmbracoBackOfficeIdentity.cs
deleted file mode 100644
index c3697d5e9e..0000000000
--- a/src/Umbraco.Web/Security/UmbracoBackOfficeIdentity.cs
+++ /dev/null
@@ -1,232 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Claims;
-using Umbraco.Web;
-
-namespace Umbraco.Core.Security
-{
-
- ///
- /// A custom user identity for the Umbraco backoffice
- ///
- ///
- /// This inherits from FormsIdentity for backwards compatibility reasons since we still support the forms auth cookie, in v8 we can
- /// change over to 'pure' asp.net identity and just inherit from ClaimsIdentity.
- ///
- [Serializable]
- public class UmbracoBackOfficeIdentity : ClaimsIdentity
- {
- public static UmbracoBackOfficeIdentity FromClaimsIdentity(ClaimsIdentity identity)
- {
- return new UmbracoBackOfficeIdentity(identity);
- }
-
- ///
- /// Creates a new UmbracoBackOfficeIdentity
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public UmbracoBackOfficeIdentity(int userId, string username, string realName,
- IEnumerable startContentNodes, IEnumerable startMediaNodes, string culture,
- string sessionId, string securityStamp, IEnumerable allowedApps, IEnumerable roles)
- : base(Enumerable.Empty(), Constants.Security.BackOfficeAuthenticationType) //this ctor is used to ensure the IsAuthenticated property is true
- {
- if (allowedApps == null) throw new ArgumentNullException(nameof(allowedApps));
- if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(username));
- if (string.IsNullOrWhiteSpace(realName)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(realName));
- if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(culture));
- if (string.IsNullOrWhiteSpace(sessionId)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(sessionId));
- if (string.IsNullOrWhiteSpace(securityStamp)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(securityStamp));
- AddRequiredClaims(userId, username, realName, startContentNodes, startMediaNodes, culture, sessionId, securityStamp, allowedApps, roles);
- }
-
- ///
- /// Creates a new UmbracoBackOfficeIdentity
- ///
- ///
- /// The original identity created by the ClaimsIdentityFactory
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public UmbracoBackOfficeIdentity(ClaimsIdentity childIdentity,
- int userId, string username, string realName,
- IEnumerable startContentNodes, IEnumerable startMediaNodes, string culture,
- string sessionId, string securityStamp, IEnumerable allowedApps, IEnumerable roles)
- : base(childIdentity.Claims, Constants.Security.BackOfficeAuthenticationType)
- {
- if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(username));
- if (string.IsNullOrWhiteSpace(realName)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(realName));
- if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(culture));
- if (string.IsNullOrWhiteSpace(sessionId)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(sessionId));
- if (string.IsNullOrWhiteSpace(securityStamp)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(securityStamp));
- Actor = childIdentity;
- AddRequiredClaims(userId, username, realName, startContentNodes, startMediaNodes, culture, sessionId, securityStamp, allowedApps, roles);
- }
-
- ///
- /// Create a back office identity based on an existing claims identity
- ///
- ///
- private UmbracoBackOfficeIdentity(ClaimsIdentity identity)
- : base(identity.Claims, Constants.Security.BackOfficeAuthenticationType)
- {
- Actor = identity;
-
- //validate that all claims exist
- foreach (var t in RequiredBackOfficeIdentityClaimTypes)
- {
- //if the identity doesn't have the claim, or the claim value is null
- if (identity.HasClaim(x => x.Type == t) == false || identity.HasClaim(x => x.Type == t && x.Value.IsNullOrWhiteSpace()))
- {
- throw new InvalidOperationException("Cannot create a " + typeof(UmbracoBackOfficeIdentity) + " from " + typeof(ClaimsIdentity) + " since the required claim " + t + " is missing");
- }
- }
- }
-
- public const string Issuer = Constants.Security.BackOfficeAuthenticationType;
-
- ///
- /// Returns the required claim types for a back office identity
- ///
- ///
- /// This does not include the role claim type or allowed apps type since that is a collection and in theory could be empty
- ///
- public static IEnumerable RequiredBackOfficeIdentityClaimTypes => new[]
- {
- ClaimTypes.NameIdentifier, //id
- ClaimTypes.Name, //username
- ClaimTypes.GivenName,
- Constants.Security.StartContentNodeIdClaimType,
- Constants.Security.StartMediaNodeIdClaimType,
- ClaimTypes.Locality,
- Constants.Security.SessionIdClaimType,
- Constants.Web.SecurityStampClaimType
- };
-
- ///
- /// Adds claims based on the ctor data
- ///
- private void AddRequiredClaims(int userId, string username, string realName,
- IEnumerable startContentNodes, IEnumerable startMediaNodes, string culture,
- string sessionId, string securityStamp, IEnumerable allowedApps, IEnumerable roles)
- {
- //This is the id that 'identity' uses to check for the user id
- if (HasClaim(x => x.Type == ClaimTypes.NameIdentifier) == false)
- AddClaim(new Claim(ClaimTypes.NameIdentifier, userId.ToInvariantString(), ClaimValueTypes.Integer32, Issuer, Issuer, this));
-
- if (HasClaim(x => x.Type == ClaimTypes.Name) == false)
- AddClaim(new Claim(ClaimTypes.Name, username, ClaimValueTypes.String, Issuer, Issuer, this));
-
- if (HasClaim(x => x.Type == ClaimTypes.GivenName) == false)
- AddClaim(new Claim(ClaimTypes.GivenName, realName, ClaimValueTypes.String, Issuer, Issuer, this));
-
- if (HasClaim(x => x.Type == Constants.Security.StartContentNodeIdClaimType) == false && startContentNodes != null)
- {
- foreach (var startContentNode in startContentNodes)
- {
- AddClaim(new Claim(Constants.Security.StartContentNodeIdClaimType, startContentNode.ToInvariantString(), ClaimValueTypes.Integer32, Issuer, Issuer, this));
- }
- }
-
- if (HasClaim(x => x.Type == Constants.Security.StartMediaNodeIdClaimType) == false && startMediaNodes != null)
- {
- foreach (var startMediaNode in startMediaNodes)
- {
- AddClaim(new Claim(Constants.Security.StartMediaNodeIdClaimType, startMediaNode.ToInvariantString(), ClaimValueTypes.Integer32, Issuer, Issuer, this));
- }
- }
-
- if (HasClaim(x => x.Type == ClaimTypes.Locality) == false)
- AddClaim(new Claim(ClaimTypes.Locality, culture, ClaimValueTypes.String, Issuer, Issuer, this));
-
- if (HasClaim(x => x.Type == Constants.Security.SessionIdClaimType) == false && SessionId.IsNullOrWhiteSpace() == false)
- AddClaim(new Claim(Constants.Security.SessionIdClaimType, sessionId, ClaimValueTypes.String, Issuer, Issuer, this));
-
- //The security stamp claim is also required... this is because this claim type is hard coded
- // by the SecurityStampValidator, see: https://katanaproject.codeplex.com/workitem/444
- if (HasClaim(x => x.Type == Constants.Web.SecurityStampClaimType) == false)
- AddClaim(new Claim(Constants.Web.SecurityStampClaimType, securityStamp, ClaimValueTypes.String, Issuer, Issuer, this));
-
- //Add each app as a separate claim
- if (HasClaim(x => x.Type == Constants.Security.AllowedApplicationsClaimType) == false && allowedApps != null)
- {
- foreach (var application in allowedApps)
- {
- AddClaim(new Claim(Constants.Security.AllowedApplicationsClaimType, application, ClaimValueTypes.String, Issuer, Issuer, this));
- }
- }
-
- //Claims are added by the ClaimsIdentityFactory because our UserStore supports roles, however this identity might
- // not be made with that factory if it was created with a different ticket so perform the check
- if (HasClaim(x => x.Type == DefaultRoleClaimType) == false && roles != null)
- {
- //manually add them
- foreach (var roleName in roles)
- {
- AddClaim(new Claim(RoleClaimType, roleName, ClaimValueTypes.String, Issuer, Issuer, this));
- }
- }
-
- }
-
- ///
- ///
- /// Gets the type of authenticated identity.
- ///
- ///
- /// The type of authenticated identity. This property always returns "UmbracoBackOffice".
- ///
- public override string AuthenticationType => Issuer;
-
- private int[] _startContentNodes;
- public int[] StartContentNodes => _startContentNodes ?? (_startContentNodes = FindAll(x => x.Type == Constants.Security.StartContentNodeIdClaimType).Select(app => int.TryParse(app.Value, out var i) ? i : default).Where(x => x != default).ToArray());
-
- private int[] _startMediaNodes;
- public int[] StartMediaNodes => _startMediaNodes ?? (_startMediaNodes = FindAll(x => x.Type == Constants.Security.StartMediaNodeIdClaimType).Select(app => int.TryParse(app.Value, out var i) ? i : default).Where(x => x != default).ToArray());
-
- private string[] _allowedApplications;
- public string[] AllowedApplications => _allowedApplications ?? (_allowedApplications = FindAll(x => x.Type == Constants.Security.AllowedApplicationsClaimType).Select(app => app.Value).ToArray());
-
- public int Id => int.Parse(this.FindFirstValue(ClaimTypes.NameIdentifier));
-
- public string RealName => this.FindFirstValue(ClaimTypes.GivenName);
-
- public string Username => this.FindFirstValue(ClaimTypes.Name);
-
- public string Culture => this.FindFirstValue(ClaimTypes.Locality);
-
- public string SessionId
- {
- get => this.FindFirstValue(Constants.Security.SessionIdClaimType);
- set
- {
- var existing = FindFirst(Constants.Security.SessionIdClaimType);
- if (existing != null)
- TryRemoveClaim(existing);
- AddClaim(new Claim(Constants.Security.SessionIdClaimType, value, ClaimValueTypes.String, Issuer, Issuer, this));
- }
- }
-
- public string SecurityStamp => this.FindFirstValue(Constants.Web.SecurityStampClaimType);
-
- public string[] Roles => this.FindAll(x => x.Type == DefaultRoleClaimType).Select(role => role.Value).ToArray();
-
- }
-}
diff --git a/src/Umbraco.Web/Security/UmbracoSecureDataFormat.cs b/src/Umbraco.Web/Security/UmbracoSecureDataFormat.cs
index 19cd602657..41a2ad3bba 100644
--- a/src/Umbraco.Web/Security/UmbracoSecureDataFormat.cs
+++ b/src/Umbraco.Web/Security/UmbracoSecureDataFormat.cs
@@ -1,6 +1,6 @@
using System;
using Microsoft.Owin.Security;
-using Umbraco.Core.Security;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/UmbracoSecurityStampValidator.cs b/src/Umbraco.Web/Security/UmbracoSecurityStampValidator.cs
index a3f78f5262..18539d8fab 100644
--- a/src/Umbraco.Web/Security/UmbracoSecurityStampValidator.cs
+++ b/src/Umbraco.Web/Security/UmbracoSecurityStampValidator.cs
@@ -3,7 +3,7 @@ using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Owin.Security.Cookies;
using Umbraco.Core;
-using Umbraco.Web.Models.Identity;
+using Umbraco.Core.BackOffice;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/UserAwarePasswordHasher.cs b/src/Umbraco.Web/Security/UserAwarePasswordHasher.cs
index d804ef0ae4..b1d88348d0 100644
--- a/src/Umbraco.Web/Security/UserAwarePasswordHasher.cs
+++ b/src/Umbraco.Web/Security/UserAwarePasswordHasher.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Identity;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Security;
-using Umbraco.Web.Models.Identity;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs
index 8975f9cde0..3c17bd370a 100644
--- a/src/Umbraco.Web/Security/WebSecurity.cs
+++ b/src/Umbraco.Web/Security/WebSecurity.cs
@@ -5,11 +5,10 @@ using Umbraco.Core;
using Umbraco.Core.Services;
using Umbraco.Core.Models.Membership;
using Microsoft.Owin;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
-using Umbraco.Core.IO;
using Umbraco.Core.Models;
-using Umbraco.Web.Models.Identity;
namespace Umbraco.Web.Security
{
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index b7c1e6e0b5..9817431f76 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -176,10 +176,6 @@
-
-
-
-
@@ -198,7 +194,6 @@
-
@@ -207,14 +202,11 @@
-
-
-
diff --git a/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs b/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs
index c68b949bba..09fd5e080c 100644
--- a/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs
@@ -6,13 +6,12 @@ using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Umbraco.Core;
using Umbraco.Web.Composing;
-using Umbraco.Core.Models.Identity;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Security;
using Umbraco.Web.Security;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
-using Umbraco.Web.Models.Identity;
namespace Umbraco.Web.WebApi.Filters
{
diff --git a/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs b/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs
index 2691063f19..b171356e23 100644
--- a/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs
+++ b/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs
@@ -2,10 +2,10 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
-using Umbraco.Web.WebApi.Filters;using Umbraco.Core.Models.Identity;
+using Umbraco.Web.WebApi.Filters;
+using Umbraco.Core.BackOffice;
using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
-using Umbraco.Web.Models.Identity;
using Umbraco.Web.Security;
using Umbraco.Core.Mapping;
using Umbraco.Web.Routing;
@@ -30,7 +30,7 @@ namespace Umbraco.Web.WebApi
[EnableDetailedErrors]
public abstract class UmbracoAuthorizedApiController : UmbracoApiController
{
- private BackOfficeUserManager _userManager;
+ private Security.BackOfficeUserManager _userManager;
protected UmbracoAuthorizedApiController()
{
@@ -44,7 +44,7 @@ namespace Umbraco.Web.WebApi
///
/// Gets the user manager.
///
- protected BackOfficeUserManager UserManager
+ protected Security.BackOfficeUserManager UserManager
=> _userManager ?? (_userManager = TryGetOwinContext().Result.GetBackOfficeUserManager());
}
}