diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec
index 1d136daf95..92cb0f065e 100644
--- a/build/NuSpecs/UmbracoCms.Web.nuspec
+++ b/build/NuSpecs/UmbracoCms.Web.nuspec
@@ -43,18 +43,15 @@
-
-
-
diff --git a/build/build.ps1 b/build/build.ps1
index 07d856d075..58d56fcdfe 100644
--- a/build/build.ps1
+++ b/build/build.ps1
@@ -478,7 +478,7 @@
{
$this.VerifyNuGetConsistency(
("UmbracoCms", "UmbracoCms.Core", "UmbracoCms.Web"),
- ("Umbraco.Core", "Umbraco.Infrastructure", "Umbraco.Web.UI.NetCore", "Umbraco.Examine.Lucene", "Umbraco.PublishedCache.NuCache", "Umbraco.Web.Common", "Umbraco.Web.Website", "Umbraco.Web.BackOffice", "Umbraco.ModelsBuilder.Embedded", "Umbraco.Persistence.SqlCe"))
+ ("Umbraco.Core", "Umbraco.Infrastructure", "Umbraco.Web.UI.NetCore", "Umbraco.Examine.Lucene", "Umbraco.PublishedCache.NuCache", "Umbraco.Web.Common", "Umbraco.Web.Website", "Umbraco.Web.BackOffice", "Umbraco.Persistence.SqlCe"))
if ($this.OnError()) { return }
})
diff --git a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
index bd0deaf6bb..516f26774a 100644
--- a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
+++ b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Extensions.Logging;
@@ -21,7 +21,6 @@ namespace Umbraco.Cms.Core.Composing
"Umbraco.Core",
"Umbraco.Infrastructure",
"Umbraco.PublishedCache.NuCache",
- "Umbraco.ModelsBuilder.Embedded",
"Umbraco.Examine.Lucene",
"Umbraco.Web.Common",
"Umbraco.Web.BackOffice",
diff --git a/src/Umbraco.Core/Configuration/MemberPasswordConfiguration.cs b/src/Umbraco.Core/Configuration/MemberPasswordConfiguration.cs
index 8bc98f4286..c7ce20454f 100644
--- a/src/Umbraco.Core/Configuration/MemberPasswordConfiguration.cs
+++ b/src/Umbraco.Core/Configuration/MemberPasswordConfiguration.cs
@@ -1,7 +1,7 @@
namespace Umbraco.Cms.Core.Configuration
{
///
- /// The password configuration for back office users
+ /// The password configuration for members
///
public class MemberPasswordConfiguration : PasswordConfiguration, IMemberPasswordConfiguration
{
diff --git a/src/Umbraco.Core/Constants-Security.cs b/src/Umbraco.Core/Constants-Security.cs
index 51b7a1824c..ba0f1e0a37 100644
--- a/src/Umbraco.Core/Constants-Security.cs
+++ b/src/Umbraco.Core/Constants-Security.cs
@@ -41,6 +41,9 @@ namespace Umbraco.Cms.Core
public const string EmptyPasswordPrefix = "___UIDEMPTYPWORD__";
+ public const string DefaultMemberTypeAlias = "Member";
+
+
///
/// The prefix used for external identity providers for their authentication type
///
diff --git a/src/Umbraco.ModelsBuilder.Embedded/ModelsBuilderDashboard.cs b/src/Umbraco.Core/Dashboards/ModelsBuilderDashboard.cs
similarity index 83%
rename from src/Umbraco.ModelsBuilder.Embedded/ModelsBuilderDashboard.cs
rename to src/Umbraco.Core/Dashboards/ModelsBuilderDashboard.cs
index 56ee0b983d..9ba5c9dd0c 100644
--- a/src/Umbraco.ModelsBuilder.Embedded/ModelsBuilderDashboard.cs
+++ b/src/Umbraco.Core/Dashboards/ModelsBuilderDashboard.cs
@@ -1,8 +1,7 @@
using System;
using Umbraco.Cms.Core.Composing;
-using Umbraco.Cms.Core.Dashboards;
-namespace Umbraco.Cms.ModelsBuilder.Embedded
+namespace Umbraco.Cms.Core.Dashboards
{
[Weight(40)]
public class ModelsBuilderDashboard : IDashboard
diff --git a/src/Umbraco.Core/IO/ViewHelper.cs b/src/Umbraco.Core/IO/ViewHelper.cs
index 9a7016b6be..258c4a7f64 100644
--- a/src/Umbraco.Core/IO/ViewHelper.cs
+++ b/src/Umbraco.Core/IO/ViewHelper.cs
@@ -71,7 +71,7 @@ namespace Umbraco.Cms.Core.IO
// @inherits Umbraco.Web.Mvc.UmbracoViewPage
// @inherits Umbraco.Web.Mvc.UmbracoViewPage
content.AppendLine("@using Umbraco.Cms.Web.Common.PublishedModels;");
- content.Append("@inherits Umbraco.Cms.Web.Common.AspNetCore.UmbracoViewPage");
+ content.Append("@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage");
if (modelClassName.IsNullOrWhiteSpace() == false)
{
content.Append("<");
diff --git a/src/Umbraco.Core/Models/Mapping/MemberMapDefinition.cs b/src/Umbraco.Core/Models/Mapping/MemberMapDefinition.cs
new file mode 100644
index 0000000000..d4cbe6c95f
--- /dev/null
+++ b/src/Umbraco.Core/Models/Mapping/MemberMapDefinition.cs
@@ -0,0 +1,33 @@
+using Umbraco.Cms.Core.Mapping;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Models.ContentEditing;
+
+namespace Umbraco.Core.Models.Mapping
+{
+ ///
+ public class MemberMapDefinition : IMapDefinition
+ {
+ ///
+ public void DefineMaps(UmbracoMapper mapper) => mapper.Define(Map);
+
+ private static void Map(MemberSave source, IMember target, MapperContext context)
+ {
+ target.IsApproved = source.IsApproved;
+ target.Name = source.Name;
+ target.Email = source.Email;
+ target.Key = source.Key;
+ target.Username = source.Username;
+ target.Comments = source.Comments;
+ target.CreateDate = source.CreateDate;
+ target.UpdateDate = source.UpdateDate;
+ target.Email = source.Email;
+
+ // TODO: ensure all properties are mapped as required
+ //target.Id = source.Id;
+ //target.ParentId = -1;
+ //target.Path = "-1," + source.Id;
+
+ //TODO: add groups as required
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs b/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs
index e54203619e..92aab36bd4 100644
--- a/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs
+++ b/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Options;
diff --git a/src/Umbraco.Core/Models/Member.cs b/src/Umbraco.Core/Models/Member.cs
index 455aa44c13..e218113bf6 100644
--- a/src/Umbraco.Core/Models/Member.cs
+++ b/src/Umbraco.Core/Models/Member.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
@@ -19,8 +19,11 @@ namespace Umbraco.Cms.Core.Models
private string _email;
private string _rawPasswordValue;
private string _passwordConfig;
+ private DateTime? _emailConfirmedDate;
+ private string _securityStamp;
///
+ /// Initializes a new instance of the class.
/// Constructor for creating an empty Member object
///
/// ContentType for the current Content object
@@ -29,13 +32,14 @@ namespace Umbraco.Cms.Core.Models
{
IsApproved = true;
- //this cannot be null but can be empty
+ // this cannot be null but can be empty
_rawPasswordValue = "";
_email = "";
_username = "";
}
///
+ /// Initializes a new instance of the class.
/// Constructor for creating a Member object
///
/// Name of the content
@@ -43,18 +47,21 @@ namespace Umbraco.Cms.Core.Models
public Member(string name, IMemberType contentType)
: base(name, -1, contentType, new PropertyCollection())
{
- if (name == null) throw new ArgumentNullException(nameof(name));
- if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(name));
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (string.IsNullOrWhiteSpace(name))
+ throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(name));
IsApproved = true;
- //this cannot be null but can be empty
+ // this cannot be null but can be empty
_rawPasswordValue = "";
_email = "";
_username = "";
}
///
+ /// Initializes a new instance of the class.
/// Constructor for creating a Member object
///
///
@@ -64,22 +71,29 @@ namespace Umbraco.Cms.Core.Models
public Member(string name, string email, string username, IMemberType contentType, bool isApproved = true)
: base(name, -1, contentType, new PropertyCollection())
{
- if (name == null) throw new ArgumentNullException(nameof(name));
- if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(name));
- if (email == null) throw new ArgumentNullException(nameof(email));
- if (string.IsNullOrWhiteSpace(email)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(email));
- if (username == null) throw new ArgumentNullException(nameof(username));
- if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(username));
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (string.IsNullOrWhiteSpace(name))
+ throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(name));
+ if (email == null)
+ throw new ArgumentNullException(nameof(email));
+ if (string.IsNullOrWhiteSpace(email))
+ throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(email));
+ if (username == null)
+ throw new ArgumentNullException(nameof(username));
+ if (string.IsNullOrWhiteSpace(username))
+ throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(username));
_email = email;
_username = username;
IsApproved = isApproved;
- //this cannot be null but can be empty
+ // this cannot be null but can be empty
_rawPasswordValue = "";
}
///
+ /// Initializes a new instance of the class.
/// Constructor for creating a Member object
///
///
@@ -99,6 +113,7 @@ namespace Umbraco.Cms.Core.Models
}
///
+ /// Initializes a new instance of the class.
/// Constructor for creating a Member object
///
///
@@ -138,6 +153,13 @@ namespace Umbraco.Cms.Core.Models
set => SetPropertyValueAndDetectChanges(value, ref _email, nameof(Email));
}
+ [DataMember]
+ public DateTime? EmailConfirmedDate
+ {
+ get => _emailConfirmedDate;
+ set => SetPropertyValueAndDetectChanges(value, ref _emailConfirmedDate, nameof(EmailConfirmedDate));
+ }
+
///
/// Gets or sets the raw password value
///
@@ -190,7 +212,8 @@ namespace Umbraco.Cms.Core.Models
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.Comments, nameof(Comments), default(string));
- if (a.Success == false) return a.Result;
+ if (a.Success == false)
+ return a.Result;
return Properties[Constants.Conventions.Member.Comments].GetValue() == null
? string.Empty
@@ -200,7 +223,8 @@ namespace Umbraco.Cms.Core.Models
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.Comments,
- nameof(Comments)) == false) return;
+ nameof(Comments)) == false)
+ return;
Properties[Constants.Conventions.Member.Comments].SetValue(value);
}
@@ -221,8 +245,10 @@ namespace Umbraco.Cms.Core.Models
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsApproved, nameof(IsApproved),
//This is the default value if the prop is not found
true);
- if (a.Success == false) return a.Result;
- if (Properties[Constants.Conventions.Member.IsApproved].GetValue() == null) return true;
+ if (a.Success == false)
+ return a.Result;
+ if (Properties[Constants.Conventions.Member.IsApproved].GetValue() == null)
+ return true;
var tryConvert = Properties[Constants.Conventions.Member.IsApproved].GetValue().TryConvertTo();
if (tryConvert.Success)
{
@@ -235,7 +261,8 @@ namespace Umbraco.Cms.Core.Models
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.IsApproved,
- nameof(IsApproved)) == false) return;
+ nameof(IsApproved)) == false)
+ return;
Properties[Constants.Conventions.Member.IsApproved].SetValue(value);
}
@@ -254,8 +281,10 @@ namespace Umbraco.Cms.Core.Models
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsLockedOut, nameof(IsLockedOut), false);
- if (a.Success == false) return a.Result;
- if (Properties[Constants.Conventions.Member.IsLockedOut].GetValue() == null) return false;
+ if (a.Success == false)
+ return a.Result;
+ if (Properties[Constants.Conventions.Member.IsLockedOut].GetValue() == null)
+ return false;
var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut].GetValue().TryConvertTo();
if (tryConvert.Success)
{
@@ -268,7 +297,8 @@ namespace Umbraco.Cms.Core.Models
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.IsLockedOut,
- nameof(IsLockedOut)) == false) return;
+ nameof(IsLockedOut)) == false)
+ return;
Properties[Constants.Conventions.Member.IsLockedOut].SetValue(value);
}
@@ -287,8 +317,10 @@ namespace Umbraco.Cms.Core.Models
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLoginDate, nameof(LastLoginDate), default(DateTime));
- if (a.Success == false) return a.Result;
- if (Properties[Constants.Conventions.Member.LastLoginDate].GetValue() == null) return default(DateTime);
+ if (a.Success == false)
+ return a.Result;
+ if (Properties[Constants.Conventions.Member.LastLoginDate].GetValue() == null)
+ return default(DateTime);
var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate].GetValue().TryConvertTo();
if (tryConvert.Success)
{
@@ -301,7 +333,8 @@ namespace Umbraco.Cms.Core.Models
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.LastLoginDate,
- nameof(LastLoginDate)) == false) return;
+ nameof(LastLoginDate)) == false)
+ return;
Properties[Constants.Conventions.Member.LastLoginDate].SetValue(value);
}
@@ -320,8 +353,10 @@ namespace Umbraco.Cms.Core.Models
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastPasswordChangeDate, nameof(LastPasswordChangeDate), default(DateTime));
- if (a.Success == false) return a.Result;
- if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].GetValue() == null) return default(DateTime);
+ if (a.Success == false)
+ return a.Result;
+ if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].GetValue() == null)
+ return default(DateTime);
var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate].GetValue().TryConvertTo();
if (tryConvert.Success)
{
@@ -334,7 +369,8 @@ namespace Umbraco.Cms.Core.Models
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.LastPasswordChangeDate,
- nameof(LastPasswordChangeDate)) == false) return;
+ nameof(LastPasswordChangeDate)) == false)
+ return;
Properties[Constants.Conventions.Member.LastPasswordChangeDate].SetValue(value);
}
@@ -353,8 +389,10 @@ namespace Umbraco.Cms.Core.Models
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLockoutDate, nameof(LastLockoutDate), default(DateTime));
- if (a.Success == false) return a.Result;
- if (Properties[Constants.Conventions.Member.LastLockoutDate].GetValue() == null) return default(DateTime);
+ if (a.Success == false)
+ return a.Result;
+ if (Properties[Constants.Conventions.Member.LastLockoutDate].GetValue() == null)
+ return default(DateTime);
var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate].GetValue().TryConvertTo();
if (tryConvert.Success)
{
@@ -367,7 +405,8 @@ namespace Umbraco.Cms.Core.Models
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.LastLockoutDate,
- nameof(LastLockoutDate)) == false) return;
+ nameof(LastLockoutDate)) == false)
+ return;
Properties[Constants.Conventions.Member.LastLockoutDate].SetValue(value);
}
@@ -387,8 +426,10 @@ namespace Umbraco.Cms.Core.Models
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.FailedPasswordAttempts, nameof(FailedPasswordAttempts), 0);
- if (a.Success == false) return a.Result;
- if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].GetValue() == null) return default(int);
+ if (a.Success == false)
+ return a.Result;
+ if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].GetValue() == null)
+ return default(int);
var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts].GetValue().TryConvertTo();
if (tryConvert.Success)
{
@@ -401,7 +442,8 @@ namespace Umbraco.Cms.Core.Models
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.FailedPasswordAttempts,
- nameof(FailedPasswordAttempts)) == false) return;
+ nameof(FailedPasswordAttempts)) == false)
+ return;
Properties[Constants.Conventions.Member.FailedPasswordAttempts].SetValue(value);
}
@@ -413,6 +455,17 @@ namespace Umbraco.Cms.Core.Models
[DataMember]
public virtual string ContentTypeAlias => ContentType.Alias;
+ ///
+ /// The security stamp used by ASP.Net identity
+ ///
+ [IgnoreDataMember]
+ public string SecurityStamp
+ {
+ get => _securityStamp;
+ set => SetPropertyValueAndDetectChanges(value, ref _securityStamp, nameof(SecurityStamp));
+ }
+
+
///
/// Internal/Experimental - only used for mapping queries.
///
diff --git a/src/Umbraco.Core/Models/Membership/IMembershipUser.cs b/src/Umbraco.Core/Models/Membership/IMembershipUser.cs
index 3374f1f11a..29a6bf4cdb 100644
--- a/src/Umbraco.Core/Models/Membership/IMembershipUser.cs
+++ b/src/Umbraco.Core/Models/Membership/IMembershipUser.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using Umbraco.Cms.Core.Models.Entities;
namespace Umbraco.Cms.Core.Models.Membership
@@ -10,6 +10,7 @@ namespace Umbraco.Cms.Core.Models.Membership
{
string Username { get; set; }
string Email { get; set; }
+ DateTime? EmailConfirmedDate { get; set; }
///
/// Gets or sets the raw password value
@@ -38,6 +39,11 @@ namespace Umbraco.Cms.Core.Models.Membership
///
int FailedPasswordAttempts { get; set; }
+ ///
+ /// Gets or sets the security stamp used by ASP.NET Identity
+ ///
+ string SecurityStamp { get; set; }
+
//object ProfileId { get; set; }
//IEnumerable