+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Change Password History

Change Password History

4 posts, 0 answered
  1. Rocky Chia
    Rocky Chia avatar
    2 posts
    Registered:
    25 Apr 2006
    06 Feb 2015
    Link to this post

    HI,

     I am trying to implement password change history. So when a user changes his password, I will check against a list and not allow if the password is present in the list.

     I used the EventHub to subscribe to the UserUpdating event in the Global.asax using the Bootstrapper.

     

     EventHub.Subscribe<UserUpdating>(UserUpdating_Action);

     

    Next in the event handler:

     private void UserUpdating_Action(UserUpdating @event)

    {

        if (@event.PasswordChanged)

    {

    // Check list and throw validataion error

    ...

    ...

    throw new ValidationException("Error");

     

    }

    }

     

    This throws a standard ASP.NET error on the page. I would prefer it to display into the error message box on the page and stop the password from changing to the new one.

     How would this be accomplished? Effectively how to stop the event from completing in an event handler?

    thanks

     

     

  2. Nikola Zagorchev
    Nikola Zagorchev avatar
    424 posts
    Registered:
    08 Dec 2016
    11 Feb 2015
    Link to this post
    Hi Rocky Chia,

    In order to validate the input and show an error message, you should create a custom UserChangePasswordWidget.
    Here is the widget template, added a custom validator, so we can show the error message:
    <%@ Control Language="C#" %>
    <%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.ContentUI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.Fields" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sfvalidation" Namespace="Telerik.Sitefinity.Web.UI.Validation.Definitions" Assembly="Telerik.Sitefinity" %>
     
    <asp:PlaceHolder ID="changePasswordRegion" runat="server">
    <fieldset class="sfprofileChangePasswordFormWrp">
        <sf:SitefinityLabel runat="server" id="errorLabel" Visible="false" WrapperTagName="div" HideIfNoText="false" CssClass="sfprofileFailureMsg" />
        <sf:SitefinityLabel runat="server" id="successLabel" Visible="false" WrapperTagName="div" HideIfNoText="false" CssClass="sfprofileSuccessMsg" />
        <ol class="sfprofileFieldsList">
            <sf:TextField ID="newPassword" runat="server" DisplayMode="Write" IsPasswordMode ="true" Title="<%$ Resources:Labels, NewPasswordText %>" CssClass="sfprofileField" WrapperTag="li">
                <ValidatorDefinition MessageCssClass="sfError" Required="true"/>
            </sf:TextField>
            <sf:TextField ID="confirmNewPassword" runat="server" DisplayMode="Write" IsPasswordMode ="true" Title="<%$ Resources:Labels, ConfirmNewPasswordText %>" CssClass="sfprofileField" WrapperTag="li">
                <ValidatorDefinition MessageCssClass="sfError">
                    <ComparingValidatorDefinitions>
                        <sfvalidation:ComparingValidatorDefinition ControlToCompare="newPassword"
                 Operator="Equal" ValidationViolationMessage="<%$ Resources:ErrorMessages, CreateUserWizardDefaultConfirmPasswordCompareErrorMessage %>"/>
                    </ComparingValidatorDefinitions>
                </ValidatorDefinition>
            </sf:TextField>
     
            <asp:CustomValidator id="CustomValidator1" runat="server"             
                 ControlToValidate="newPassword" 
                    CssClass="sfError"
                 ErrorMessage="Password already used. Enter new password.">
            </asp:CustomValidator>
     
        </ol>
        <div class="sfprofileLnkWrp">
            <asp:LinkButton runat="server" ID="saveChanges" Text="<%$ Resources:Labels, Submit %>" CssClass="sfprofileSaveLnk" />
        </div>
    </fieldset>
    </asp:PlaceHolder>
    <asp:PlaceHolder ID="passwordChangedRegion" runat="server" Visible="false">
        <p>
            <asp:Literal runat="server" Text="<%$ Resources:Labels, PasswordSuccessfullyChanged %>"></asp:Literal>
        </p>
        <sf:SitefinityHyperLink ID="continueToWebsite" runat="server" Text="<%$ Resources:Labels, ContinueToWebsite %>" NavigateUrl="~/"></sf:SitefinityHyperLink>
    </asp:PlaceHolder>

    Server code:
    public class UserChangePasswordWidgetCustom : UserChangePasswordWidget
    {
        public override string LayoutTemplatePath
        {
            get
            {
                return UserChangePasswordWidgetCustom.layoutTemplatePathCustom;
            }
        }
     
        protected virtual CustomValidator CustomValidator1
        {
            get
            {
                return this.Container.GetControl<CustomValidator>("CustomValidator1", true);
            }
        }
     
        protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container, Telerik.Sitefinity.Web.UI.ContentUI.Contracts.IContentViewDefinition definition)
        {
            this.CustomValidator1.ServerValidate += NewPasswordValidate;
            this.SaveChangesButton.Click += SaveChangesButton_Click;
     
            base.InitializeControls(container, definition);
        }
     
        void SaveChangesButton_Click(object sender, EventArgs e)
        {
            this.NewPasswordOriginalValue = this.NewPasswordTextField.Value;
            if (this.NewPasswordOriginalValue != null && !string.IsNullOrWhiteSpace(this.NewPasswordOriginalValue.ToString()))
            {
                if (!ValidatePassword(this.NewPasswordOriginalValue.ToString()))
                {
                    this.NewPasswordTextField.Value = string.Empty;
                    this.NewPasswordTextField.ShowMessageOnError = false;
                }
            }
        }
     
        protected void NewPasswordValidate(object source, ServerValidateEventArgs args)
        {
            args.IsValid = ValidatePassword(args.Value.ToString());
        }
     
        private bool ValidatePassword(string password)
        {
            // Check list
            return false;
        }
     
        protected override bool OnBubbleEvent(object source, EventArgs args)
        {
            this.NewPasswordTextField.Value = this.NewPasswordOriginalValue;
            return base.OnBubbleEvent(source, args);
        }
     
        internal static readonly string layoutTemplatePathCustom = "~/UserChangePasswordWidgetCustom/UserChangePasswordWidgetCustom.ascx";
     
        public object NewPasswordOriginalValue { get; set; }
    }

    Unfortunately, there is no descent way to stop the processing, since the methods are internal and private, so we use a workaround here by setting the new password field value to empty string and then reverting to the original value.
    I have logged a feature request for the ability to easily extend this logic. You can review it here.

    Hope this is helpful.

    Regards,
    Nikola Zagorchev
    Telerik
     
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
     
  3. Rocky Chia
    Rocky Chia avatar
    2 posts
    Registered:
    25 Apr 2006
    13 Feb 2015 in reply to Nikola Zagorchev
    Link to this post

    Thanks Nikola,

     I was hoping not to create a whole new widget to perform what has already been done. But I guess that will do. Of course now the next thing is to disable the standard backend change password page so the user would be forced to use this new one, but that's another story.

     For that matter, the ability to return a bool from any event handler raised by EventHub that will interrupt the main processing would be most useful not just to this particular scenario.

     

     

  4. Nikola Zagorchev
    Nikola Zagorchev avatar
    424 posts
    Registered:
    08 Dec 2016
    13 Feb 2015
    Link to this post
    Hi Rocky Chia,

    Unfortunately, the EventHub provides only subscribe/unsubscribe functionality. The event cannot be canceled from the -ing events. Furthermore, you will not be able to show an adequate error message from the event handling.

    Regards,
    Nikola Zagorchev
    Telerik
     
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
     
4 posts, 0 answered