diff --git a/src/Umbraco.Core/Security/AuthenticationExtensions.cs b/src/Umbraco.Core/Security/AuthenticationExtensions.cs
index 3c88c07edf..17cea2976c 100644
--- a/src/Umbraco.Core/Security/AuthenticationExtensions.cs
+++ b/src/Umbraco.Core/Security/AuthenticationExtensions.cs
@@ -80,7 +80,41 @@ namespace Umbraco.Core.Security
return false;
}
+
+ ///
+ /// This will return the current back office identity if the IPrincipal is the correct type
+ ///
+ ///
+ ///
+ internal static UmbracoBackOfficeIdentity GetUmbracoIdentity(this IPrincipal user)
+ {
+ //If it's already a UmbracoBackOfficeIdentity
+ var backOfficeIdentity = user.Identity as UmbracoBackOfficeIdentity;
+ if (backOfficeIdentity != null) return backOfficeIdentity;
+ //Check if there's more than one identity assigned and see if it's a UmbracoBackOfficeIdentity and use that
+ var claimsPrincipal = user as ClaimsPrincipal;
+ if (claimsPrincipal != null)
+ {
+ 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
+ var claimsIdentity = user.Identity as ClaimsIdentity;
+ if (claimsIdentity != null && claimsIdentity.IsAuthenticated && claimsIdentity.HasClaim(x => x.Type == Constants.Security.SessionIdClaimType))
+ {
+ try
+ {
+ return UmbracoBackOfficeIdentity.FromClaimsIdentity(claimsIdentity);
+ }
+ catch (InvalidOperationException)
+ {
+ }
+ }
+
+ return null;
+ }
///
/// This will return the current back office identity.
@@ -100,31 +134,8 @@ namespace Umbraco.Core.Security
if (http.User == null) return null; //there's no user at all so no identity
//If it's already a UmbracoBackOfficeIdentity
- var backOfficeIdentity = http.User.Identity as UmbracoBackOfficeIdentity;
- if (backOfficeIdentity != null) return backOfficeIdentity;
-
- //Check if there's more than one identity assigned and see if it's a UmbracoBackOfficeIdentity and use that
- var claimsPrincipal = http.User as ClaimsPrincipal;
- if (claimsPrincipal != null)
- {
- 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
- var claimsIdentity = http.User.Identity as ClaimsIdentity;
- if (claimsIdentity != null && claimsIdentity.IsAuthenticated && claimsIdentity.HasClaim(x => x.Type == Constants.Security.SessionIdClaimType))
- {
- try
- {
- return UmbracoBackOfficeIdentity.FromClaimsIdentity(claimsIdentity);
- }
- catch (InvalidOperationException ex)
- {
- //This will occur if the required claim types are missing which would mean something strange is going on
- LogHelper.Error(typeof(AuthenticationExtensions), "The current identity cannot be converted to " + typeof(UmbracoBackOfficeIdentity), ex);
- }
- }
+ var backOfficeIdentity = GetUmbracoIdentity(http.User);
+ if (backOfficeIdentity != null) return backOfficeIdentity;
if (authenticateRequestIfNotFound == false) return null;
diff --git a/src/Umbraco.Core/Security/MembershipProviderBase.cs b/src/Umbraco.Core/Security/MembershipProviderBase.cs
index d8bbc1dced..efee6f4893 100644
--- a/src/Umbraco.Core/Security/MembershipProviderBase.cs
+++ b/src/Umbraco.Core/Security/MembershipProviderBase.cs
@@ -521,9 +521,9 @@ namespace Umbraco.Core.Security
public override string ResetPassword(string username, string answer)
{
- var auth = new HttpContextWrapper(HttpContext.Current).GetUmbracoAuthTicket();
- var userIsAdmin = ApplicationContext.Current.Services.UserService.GetByUsername(auth.Name).IsAdmin();
- if (userIsAdmin == false && EnablePasswordReset == false)
+ var canReset = this.CanResetPassword(ApplicationContext.Current.Services.UserService);
+
+ if (canReset == false)
{
throw new NotSupportedException("Password reset is not supported");
}
diff --git a/src/Umbraco.Core/Security/MembershipProviderExtensions.cs b/src/Umbraco.Core/Security/MembershipProviderExtensions.cs
index bdd3174960..ebd42bd781 100644
--- a/src/Umbraco.Core/Security/MembershipProviderExtensions.cs
+++ b/src/Umbraco.Core/Security/MembershipProviderExtensions.cs
@@ -9,12 +9,44 @@ using System.Web;
using System.Web.Hosting;
using System.Web.Security;
using Umbraco.Core.Configuration;
+using Umbraco.Core.Models;
using Umbraco.Core.Security;
+using Umbraco.Core.Services;
namespace Umbraco.Core.Security
{
public static class MembershipProviderExtensions
{
+ ///
+ /// Extension method to check if a password can be reset based on a given provider and the current request (logged in user)
+ ///
+ ///
+ ///
+ ///
+ internal static bool CanResetPassword(this MembershipProvider provider, IUserService userService)
+ {
+ if (provider == null) throw new ArgumentNullException("provider");
+ if (userService == null) throw new ArgumentNullException("userService");
+
+ var canReset = provider.EnablePasswordReset;
+
+ //we need to check for the special case in which a user is an admin - in which acse they can reset the password even if EnablePasswordReset == false
+ if (provider.EnablePasswordReset == false)
+ {
+ var identity = Thread.CurrentPrincipal.GetUmbracoIdentity();
+ if (identity != null)
+ {
+ var user = userService.GetByUsername(identity.Username);
+ var userIsAdmin = user.IsAdmin();
+ if (userIsAdmin)
+ {
+ canReset = true;
+ }
+ }
+ }
+ return canReset;
+ }
+
internal static MembershipUserCollection FindUsersByName(this MembershipProvider provider, string usernameToMatch)
{
int totalRecords = 0;
diff --git a/src/Umbraco.Web.UI/umbraco/controls/PasswordChanger.ascx.cs b/src/Umbraco.Web.UI/umbraco/controls/PasswordChanger.ascx.cs
index f5f2834fba..75540408b8 100644
--- a/src/Umbraco.Web.UI/umbraco/controls/PasswordChanger.ascx.cs
+++ b/src/Umbraco.Web.UI/umbraco/controls/PasswordChanger.ascx.cs
@@ -24,10 +24,12 @@ namespace Umbraco.Web.UI.Umbraco.Controls
//reset the flag always
IsChangingPasswordField.Value = "false";
- var auth = new HttpContextWrapper(HttpContext.Current).GetUmbracoAuthTicket();
- ResetPlaceHolder.Visible = ApplicationContext.Current.Services.UserService.GetByUsername(auth.Name).IsAdmin();
+ var canReset = Provider.CanResetPassword(ApplicationContext.Current.Services.UserService);
+
+ ResetPlaceHolder.Visible = canReset;
this.DataBind();
}
+
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Editors/CurrentUserController.cs b/src/Umbraco.Web/Editors/CurrentUserController.cs
index 5c56106063..aacad99fb7 100644
--- a/src/Umbraco.Web/Editors/CurrentUserController.cs
+++ b/src/Umbraco.Web/Editors/CurrentUserController.cs
@@ -37,7 +37,7 @@ namespace Umbraco.Web.Editors
public IDictionary GetMembershipProviderConfig()
{
var provider = Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider();
- return provider.GetConfiguration();
+ return provider.GetConfiguration(Services.UserService);
}
///
diff --git a/src/Umbraco.Web/MembershipProviderExtensions.cs b/src/Umbraco.Web/MembershipProviderExtensions.cs
index 49d8abca7f..2a32384732 100644
--- a/src/Umbraco.Web/MembershipProviderExtensions.cs
+++ b/src/Umbraco.Web/MembershipProviderExtensions.cs
@@ -1,7 +1,9 @@
using System.Collections.Generic;
+using System.Web;
using System.Web.Security;
using Umbraco.Core.Models;
using Umbraco.Core.Security;
+using Umbraco.Core.Services;
namespace Umbraco.Web
{
@@ -11,16 +13,19 @@ namespace Umbraco.Web
/// Returns the configuration of the membership provider used to configure change password editors
///
///
+ ///
///
public static IDictionary GetConfiguration(
- this MembershipProvider membershipProvider)
+ this MembershipProvider membershipProvider, IUserService userService)
{
var baseProvider = membershipProvider as MembershipProviderBase;
-
+
+ var canReset = membershipProvider.CanResetPassword(userService);
+
return new Dictionary
{
{"minPasswordLength", membershipProvider.MinRequiredPasswordLength},
- {"enableReset", UmbracoContext.Current.Security.CurrentUser.IsAdmin()},
+ {"enableReset", canReset},
{"enablePasswordRetrieval", membershipProvider.EnablePasswordRetrieval},
{"requiresQuestionAnswer", membershipProvider.RequiresQuestionAndAnswer},
{"allowManuallyChangingPassword", baseProvider != null && baseProvider.AllowManuallyChangingPassword}
diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs
index 3982302906..e0eb318866 100644
--- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs
@@ -81,7 +81,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(display => display.IsContainer, expression => expression.Ignore())
.ForMember(display => display.TreeNodeUrl, expression => expression.Ignore())
.ForMember(display => display.HasPublishedVersion, expression => expression.Ignore())
- .AfterMap((member, display) => MapGenericCustomProperties(applicationContext.Services.MemberService, member, display, applicationContext.Services.TextService));
+ .AfterMap((member, display) => MapGenericCustomProperties(applicationContext.Services.MemberService, applicationContext.Services.UserService, member, display, applicationContext.Services.TextService));
//FROM IMember TO MemberBasic
config.CreateMap()
@@ -139,13 +139,14 @@ namespace Umbraco.Web.Models.Mapping
/// Maps the generic tab with custom properties for content
///
///
+ ///
///
///
///
///
/// If this is a new entity and there is an approved field then we'll set it to true by default.
///
- private static void MapGenericCustomProperties(IMemberService memberService, IMember member, MemberDisplay display, ILocalizedTextService localizedText)
+ private static void MapGenericCustomProperties(IMemberService memberService, IUserService userService, IMember member, MemberDisplay display, ILocalizedTextService localizedText)
{
var membersProvider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider();
@@ -189,7 +190,7 @@ namespace Umbraco.Web.Models.Mapping
//TODO: Hard coding this because the changepassword doesn't necessarily need to be a resolvable (real) property editor
View = "changepassword",
//initialize the dictionary with the configuration from the default membership provider
- Config = new Dictionary(membersProvider.GetConfiguration())
+ Config = new Dictionary(membersProvider.GetConfiguration(userService))
{
//the password change toggle will only be displayed if there is already a password assigned.
{"hasPassword", member.RawPasswordValue.IsNullOrWhiteSpace() == false}
diff --git a/src/Umbraco.Web/Security/MembershipHelper.cs b/src/Umbraco.Web/Security/MembershipHelper.cs
index c82d8411ad..605b5137d8 100644
--- a/src/Umbraco.Web/Security/MembershipHelper.cs
+++ b/src/Umbraco.Web/Security/MembershipHelper.cs
@@ -663,8 +663,8 @@ namespace Umbraco.Web.Security
//Are we resetting the password??
if (passwordModel.Reset.HasValue && passwordModel.Reset.Value)
{
- var userIsAdmin = UmbracoContext.Current.Security.CurrentUser.IsAdmin();
- if (userIsAdmin == false && membershipProvider.EnablePasswordReset == false)
+ var canReset = membershipProvider.CanResetPassword(_applicationContext.Services.UserService);
+ if (canReset == false)
{
return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Password reset is not enabled", new[] { "resetPassword" }) });
}