From 3f8b3031c22b91d8478e9a9518e5c7ccadba30ca Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 22 Jan 2014 11:57:33 +1100 Subject: [PATCH] completes: U4-3996 Fix EditUser to use the membership provider properly, U4-3997 Fix EditMember to use the membership provider properly --- src/Umbraco.Core/Models/Membership/IUser.cs | 2 +- .../Models/Membership/IUserType.cs | 2 +- .../Security/IUsersMembershipProvider.cs | 10 ++++ .../Security/MembershipProviderExtensions.cs | 10 ++++ .../Security/UmbracoMembershipProviderBase.cs | 1 - .../Services/IMembershipUserService.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../Providers/MembersMembershipProvider.cs | 2 +- .../UmbracoServiceMembershipProvider.cs | 2 +- .../Providers/UsersMembershipProvider.cs | 3 +- .../umbraco/editContent.aspx.cs | 2 - .../umbraco/login.aspx.cs | 47 +++++++++++++------ .../umbraco/members/EditMember.aspx.cs | 13 +++-- .../umbraco/users/EditUser.aspx.cs | 17 +++---- .../UsersMembershipProvider.cs | 2 +- 15 files changed, 76 insertions(+), 40 deletions(-) create mode 100644 src/Umbraco.Core/Security/IUsersMembershipProvider.cs diff --git a/src/Umbraco.Core/Models/Membership/IUser.cs b/src/Umbraco.Core/Models/Membership/IUser.cs index f45f4ebea6..b15e5845e5 100644 --- a/src/Umbraco.Core/Models/Membership/IUser.cs +++ b/src/Umbraco.Core/Models/Membership/IUser.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.Membership /// Defines the interface for a /// /// Will be left internal until a proper Membership implementation is part of the roadmap - internal interface IUser : IMembershipUser, IProfile + public interface IUser : IMembershipUser, IProfile { new object Id { get; set; } diff --git a/src/Umbraco.Core/Models/Membership/IUserType.cs b/src/Umbraco.Core/Models/Membership/IUserType.cs index aa2d882e4c..fe678afd2b 100644 --- a/src/Umbraco.Core/Models/Membership/IUserType.cs +++ b/src/Umbraco.Core/Models/Membership/IUserType.cs @@ -5,7 +5,7 @@ using Umbraco.Core.Persistence.Mappers; namespace Umbraco.Core.Models.Membership { - internal interface IUserType : IAggregateRoot + public interface IUserType : IAggregateRoot { /// /// The user type alias diff --git a/src/Umbraco.Core/Security/IUsersMembershipProvider.cs b/src/Umbraco.Core/Security/IUsersMembershipProvider.cs new file mode 100644 index 0000000000..8f2dbf8b00 --- /dev/null +++ b/src/Umbraco.Core/Security/IUsersMembershipProvider.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Core.Security +{ + /// + /// A marker interface used internally to identify Umbraco built-in Users membership providers + /// + internal interface IUsersMembershipProvider + { + + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Security/MembershipProviderExtensions.cs b/src/Umbraco.Core/Security/MembershipProviderExtensions.cs index 85db27ac97..747f6c42c0 100644 --- a/src/Umbraco.Core/Security/MembershipProviderExtensions.cs +++ b/src/Umbraco.Core/Security/MembershipProviderExtensions.cs @@ -10,6 +10,16 @@ namespace Umbraco.Core.Security { internal static class MembershipProviderExtensions { + /// + /// Returns true if the provider specified is a built-in Umbraco users provider + /// + /// + /// + public static bool IsUmbracoUsersProvider(this MembershipProvider membershipProvider) + { + return (membershipProvider is IUsersMembershipProvider); + } + /// /// Returns true if the provider specified is a built-in Umbraco membership provider /// diff --git a/src/Umbraco.Core/Security/UmbracoMembershipProviderBase.cs b/src/Umbraco.Core/Security/UmbracoMembershipProviderBase.cs index 6cbd12f448..12ca2b4b4a 100644 --- a/src/Umbraco.Core/Security/UmbracoMembershipProviderBase.cs +++ b/src/Umbraco.Core/Security/UmbracoMembershipProviderBase.cs @@ -3,7 +3,6 @@ using System.Web.Security; namespace Umbraco.Core.Security { - /// /// A base membership provider class for umbraco providers /// diff --git a/src/Umbraco.Core/Services/IMembershipUserService.cs b/src/Umbraco.Core/Services/IMembershipUserService.cs index c79607edab..75382e5c46 100644 --- a/src/Umbraco.Core/Services/IMembershipUserService.cs +++ b/src/Umbraco.Core/Services/IMembershipUserService.cs @@ -8,7 +8,7 @@ namespace Umbraco.Core.Services /// /// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl. /// - internal interface IMembershipUserService : IMembershipMemberService + public interface IMembershipUserService : IMembershipMemberService { IUser CreateMember(string username, string email, string password, IUserType userType); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 09ab59e054..0c7025fe00 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -740,6 +740,7 @@ + diff --git a/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs index 9ab6b90bd0..84de8f3367 100644 --- a/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs @@ -17,7 +17,7 @@ namespace Umbraco.Web.Security.Providers /// /// Custom Membership Provider for Umbraco Members (User authentication for Frontend applications NOT umbraco CMS) /// - internal class MembersMembershipProvider : UmbracoServiceMembershipProvider + public class MembersMembershipProvider : UmbracoServiceMembershipProvider { public MembersMembershipProvider() : this(ApplicationContext.Current.Services.MemberService) diff --git a/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs index 16ea1e4393..28c3b930b7 100644 --- a/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs @@ -17,7 +17,7 @@ namespace Umbraco.Web.Security.Providers /// /// Abstract Membership Provider that users any implementation of IMembershipMemberService{TEntity} service /// - internal abstract class UmbracoServiceMembershipProvider : UmbracoMembershipProviderBase + public abstract class UmbracoServiceMembershipProvider : UmbracoMembershipProviderBase where T : IMembershipMemberService where TEntity : class, IMembershipUser { diff --git a/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs index 23fe07b02b..d8bfceba43 100644 --- a/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs @@ -5,6 +5,7 @@ using System.Text; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; using Umbraco.Core.Services; namespace Umbraco.Web.Security.Providers @@ -12,7 +13,7 @@ namespace Umbraco.Web.Security.Providers /// /// Custom Membership Provider for Umbraco Users (User authentication for Umbraco Backend CMS) /// - internal class UsersMembershipProvider : UmbracoServiceMembershipProvider + public class UsersMembershipProvider : UmbracoServiceMembershipProvider, IUsersMembershipProvider { public UsersMembershipProvider() diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index 91c6a8a4e0..3af648c142 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -365,8 +365,6 @@ namespace umbraco.cms.presentation _unPublish.Visible = false; _documentHasPublishedVersion = false; - //library.UnPublishSingleNode(_document.Id); - Current.ClientTools.SyncTree(_document.Path, true); ClientTools.ShowSpeechBubble(speechBubbleIcon.success, ui.Text("unpublish"), ui.Text("speechBubbles", "contentUnpublished")); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs index 73a26c4494..36008e7fac 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.ComponentModel; +using System.Configuration.Provider; using System.Data; using System.Drawing; using System.Security; @@ -17,6 +18,7 @@ using Umbraco.Core.IO; using umbraco.cms.businesslogic.web; using System.Linq; using Umbraco.Core; +using Umbraco.Core.Security; namespace umbraco.cms.presentation { @@ -28,6 +30,19 @@ namespace umbraco.cms.presentation [Obsolete("This property is no longer used")] protected umbWindow treeWindow; + private MembershipProvider BackOfficeProvider + { + get + { + var provider = Membership.Providers[UmbracoSettings.DefaultBackofficeProvider]; + if (provider == null) + { + throw new ProviderException("The membership provider " + UmbracoSettings.DefaultBackofficeProvider + " was not found"); + } + return provider; + } + } + protected override void OnLoad(EventArgs e) { base.OnLoad(e); @@ -35,9 +50,9 @@ namespace umbraco.cms.presentation // validate redirect url string redirUrl = Request["redir"]; - if (!String.IsNullOrEmpty(redirUrl)) + if (!string.IsNullOrEmpty(redirUrl)) { - validateRedirectUrl(redirUrl); + ValidateRedirectUrl(redirUrl); } } @@ -63,15 +78,18 @@ namespace umbraco.cms.presentation } - protected void Button1_Click(object sender, System.EventArgs e) + protected void Button1_Click(object sender, EventArgs e) { // Authenticate users by using the provider specified in umbracoSettings.config - if (Membership.Providers[UmbracoSettings.DefaultBackofficeProvider].ValidateUser(lname.Text, passw.Text)) + if (BackOfficeProvider.ValidateUser(lname.Text, passw.Text)) { - if (Membership.Providers[UmbracoSettings.DefaultBackofficeProvider] is ActiveDirectoryMembershipProvider) - ActiveDirectoryMapping(lname.Text, Membership.Providers[UmbracoSettings.DefaultBackofficeProvider].GetUser(lname.Text, false).Email); + if (BackOfficeProvider.IsUmbracoUsersProvider() == false) + { + CustomProviderMapping(lname.Text, BackOfficeProvider.GetUser(lname.Text, false).Email); + } + - BusinessLogic.User u = new User(lname.Text); + var u = new User(lname.Text); doLogin(u); // Check if the user should be redirected to live editing @@ -97,8 +115,7 @@ namespace umbraco.cms.presentation } else if (u.DefaultToLiveEditing) { - throw new UserAuthorizationException( - "Canvas editing isn't enabled. It can be enabled via the UmbracoSettings.config"); + throw new UserAuthorizationException("Canvas editing isn't enabled. It can be enabled via the UmbracoSettings.config"); } if (hf_height.Value != "undefined") @@ -111,7 +128,7 @@ namespace umbraco.cms.presentation if (string.IsNullOrEmpty(redirUrl)) Response.Redirect("umbraco.aspx"); - else if (validateRedirectUrl(redirUrl)) + else if (ValidateRedirectUrl(redirUrl)) { Response.Redirect(redirUrl, true); } @@ -122,9 +139,9 @@ namespace umbraco.cms.presentation } } - private bool validateRedirectUrl(string url) + private static bool ValidateRedirectUrl(string url) { - if (!isUrlLocalToHost(url)) + if (IsUrlLocalToHost(url) == false) { LogHelper.Info(String.Format("Security warning: Login redirect was attempted to a site at another domain: '{0}'", url)); @@ -137,7 +154,7 @@ namespace umbraco.cms.presentation return true; } - private bool isUrlLocalToHost(string url) + private static bool IsUrlLocalToHost(string url) { if (String.IsNullOrEmpty(url)) { @@ -158,11 +175,11 @@ namespace umbraco.cms.presentation } /// - /// Maps active directory account to umbraco user account + /// Maps a custom provider's information to an umbraco user account /// /// Name of the login. /// Email address of the user - private void ActiveDirectoryMapping(string loginName, string email) + private static void CustomProviderMapping(string loginName, string email) { // Password is not copied over because it is stored in active directory for security! // The user is create with default access to content and as a writer user type diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs index 600b769c6a..0154b77382 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs @@ -68,7 +68,7 @@ namespace umbraco.cms.presentation.members { _document = new Member(int.Parse(Request.QueryString["id"])); _member = Membership.GetUser(_document.LoginName, false); - _contentControl = new ContentControl(_document, controls.ContentControl.publishModes.NoPublish, "TabView1"); + _contentControl = new ContentControl(_document, ContentControl.publishModes.NoPublish, "TabView1"); _contentControl.Width = Unit.Pixel(666); _contentControl.Height = Unit.Pixel(666); @@ -92,13 +92,13 @@ namespace umbraco.cms.presentation.members MemberLoginNameVal.EnableClientScript = false; MemberLoginNameVal.Display = ValidatorDisplay.Dynamic; - MemberLoginNameExistCheck.ErrorMessage = ui.Text("errorHandling", "errorExistsWithoutTab", "Login Name", BasePages.UmbracoEnsuredPage.CurrentUser); + MemberLoginNameExistCheck.ErrorMessage = ui.Text("errorHandling", "errorExistsWithoutTab", "Login Name", CurrentUser); MemberLoginNameExistCheck.EnableClientScript = false; MemberLoginNameExistCheck.ValidateEmptyText = false; MemberLoginNameExistCheck.ControlToValidate = MemberLoginNameTxt.ID; MemberLoginNameExistCheck.ServerValidate += MemberLoginNameExistCheck_ServerValidate; - MemberEmailExistCheck.ErrorMessage = ui.Text("errorHandling", "errorExistsWithoutTab", "E-mail", BasePages.UmbracoEnsuredPage.CurrentUser); + MemberEmailExistCheck.ErrorMessage = ui.Text("errorHandling", "errorExistsWithoutTab", "E-mail", CurrentUser); MemberEmailExistCheck.EnableClientScript = false; MemberEmailExistCheck.ValidateEmptyText = false; MemberEmailExistCheck.ControlToValidate = MemberEmail.ID; @@ -116,7 +116,7 @@ namespace umbraco.cms.presentation.members var menuSave = m_MemberShipPanel.Menu.NewImageButton(); menuSave.ID = m_MemberShipPanel.ID + "_save"; menuSave.ImageUrl = SystemDirectories.Umbraco + "/images/editor/save.gif"; - menuSave.Click += new ImageClickEventHandler(MenuSaveClick); + menuSave.Click += MenuSaveClick; menuSave.AltText = ui.Text("buttons", "save", null); _member = Membership.GetUser(Request.QueryString["id"], false); @@ -167,7 +167,7 @@ namespace umbraco.cms.presentation.members if (Membership.Provider.IsUmbracoMembershipProvider()) { _contentControl.tpProp.Controls.Add(p); - _contentControl.Save += new System.EventHandler(tmp_save); + _contentControl.Save += tmp_save; } else { @@ -244,8 +244,7 @@ namespace umbraco.cms.presentation.members { var membershipHelper = new MembershipHelper(); //set the writable properties that we are editing - membershipHelper.UpdateMember(membershipUser, Membership.Provider, - MemberEmail.Text.Trim()); + membershipHelper.UpdateMember(membershipUser, Membership.Provider, MemberEmail.Text.Trim()); } private void UpdateRoles(MembershipUser membershipUser) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs index 95b2e891e7..b85835788d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs @@ -10,6 +10,7 @@ using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Xml; using Umbraco.Core.Logging; +using Umbraco.Core.Security; using Umbraco.Web; using Umbraco.Web.Models; using Umbraco.Web.Security; @@ -36,7 +37,7 @@ namespace umbraco.cms.presentation.user { public EditUser() { - CurrentApp = BusinessLogic.DefaultApps.users.ToString(); + CurrentApp = DefaultApps.users.ToString(); } protected HtmlTable macroProperties; protected TextBox uname = new TextBox(); @@ -51,8 +52,8 @@ namespace umbraco.cms.presentation.user protected CheckBox DefaultToLiveEditing = new CheckBox(); - protected controls.ContentPicker mediaPicker = new umbraco.controls.ContentPicker(); - protected controls.ContentPicker contentPicker = new umbraco.controls.ContentPicker(); + protected ContentPicker mediaPicker = new ContentPicker(); + protected ContentPicker contentPicker = new ContentPicker(); protected TextBox cName = new TextBox(); protected CheckBox cFulltree = new CheckBox(); @@ -60,8 +61,8 @@ namespace umbraco.cms.presentation.user protected DropDownList cDescription = new DropDownList(); protected DropDownList cCategories = new DropDownList(); protected DropDownList cExcerpt = new DropDownList(); - protected controls.ContentPicker cMediaPicker = new umbraco.controls.ContentPicker(); - protected controls.ContentPicker cContentPicker = new umbraco.controls.ContentPicker(); + protected ContentPicker cMediaPicker = new ContentPicker(); + protected ContentPicker cContentPicker = new ContentPicker(); protected CustomValidator sectionValidator = new CustomValidator(); protected Pane pp = new Pane(); @@ -167,7 +168,7 @@ namespace umbraco.cms.presentation.user //This is a hack to allow the admin to change a user's password to whatever they want - this will only work if we are using the // default umbraco membership provider. // See the notes below in the ChangePassword method. - if (BackOfficeProvider is UsersMembershipProvider) + if (BackOfficeProvider.IsUmbracoUsersProvider()) { passwordChanger.ShowOldPassword = false; } @@ -436,7 +437,7 @@ namespace umbraco.cms.presentation.user var changePasswordModel = passwordChangerControl.ChangingPasswordModel; // Is it using the default membership provider - if (BackOfficeProvider is UsersMembershipProvider) + if (BackOfficeProvider.IsUmbracoUsersProvider()) { //This is a total hack so that an admin can change the password without knowing the previous one // we do this by simply passing in the already stored hashed/encrypted password in the database - @@ -604,6 +605,6 @@ namespace umbraco.cms.presentation.user /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::umbraco.uicontrols.TabView UserTabs; + protected TabView UserTabs; } } diff --git a/src/umbraco.providers/UsersMembershipProvider.cs b/src/umbraco.providers/UsersMembershipProvider.cs index f5e9acf961..0c8c23854b 100644 --- a/src/umbraco.providers/UsersMembershipProvider.cs +++ b/src/umbraco.providers/UsersMembershipProvider.cs @@ -16,7 +16,7 @@ namespace umbraco.providers /// /// Custom Membership Provider for Umbraco Users (User authentication for Umbraco Backend CMS) /// - public class UsersMembershipProvider : MembershipProviderBase + public class UsersMembershipProvider : MembershipProviderBase, IUsersMembershipProvider { ///