//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.RelyingParty { using System; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Threading; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using DotNetOpenAuth.Messaging; /// /// An ASP.NET control providing a complete OpenID login experience. /// [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", Justification = "Legacy code")] [DefaultProperty("Text"), ValidationProperty("Text")] [ToolboxData("<{0}:OpenIdLogin runat=\"server\" />")] public class OpenIdLogin : OpenIdTextBox { #region Property defaults /// /// The default value for the property. /// private const string RegisterToolTipDefault = "Sign up free for an OpenID with MyOpenID now."; /// /// The default value for the property. /// private const string RememberMeTextDefault = "Remember me"; /// /// The default value for the property. /// private const string ButtonTextDefault = "Login »"; /// /// The default value for the property. /// private const string CanceledTextDefault = "Login canceled."; /// /// The default value for the property. /// private const string FailedMessageTextDefault = "Login failed: {0}"; /// /// The default value for the property. /// private const string ExamplePrefixDefault = "Example:"; /// /// The default value for the property. /// private const string ExampleUrlDefault = "http://your.name.myopenid.com"; /// /// The default value for the property. /// private const string LabelTextDefault = "OpenID Login:"; /// /// The default value for the property. /// private const string RequiredTextDefault = "Provide an OpenID first."; /// /// The default value for the property. /// private const string UriFormatTextDefault = "Invalid OpenID URL."; /// /// The default value for the property. /// private const string RegisterTextDefault = "register"; /// /// The default value for the property. /// private const string RegisterUrlDefault = "https://www.myopenid.com/signup"; /// /// The default value for the property. /// private const string ButtonToolTipDefault = "Account login"; /// /// The default value for the property. /// private const string ValidationGroupDefault = "OpenIdLogin"; /// /// The default value for the property. /// private const bool RegisterVisibleDefault = true; /// /// The default value for the property. /// private const bool RememberMeVisibleDefault = false; /// /// The default value for the property. /// private const bool RememberMeDefault = false; /// /// The default value for the property. /// private const bool UriValidatorEnabledDefault = true; #endregion #region Property viewstate keys /// /// The viewstate key to use for the property. /// private const string FailedMessageTextViewStateKey = "FailedMessageText"; /// /// The viewstate key to use for the property. /// private const string CanceledTextViewStateKey = "CanceledText"; /// /// The viewstate key to use for the property. /// private const string IdSelectorIdentifierViewStateKey = "IdSelectorIdentifier"; #endregion /// /// The HTML to append to the property value when rendering. /// private const string RequiredTextSuffix = "
"; /// /// The number to add to to get the tab index of the textbox control. /// private const short TextBoxTabIndexOffset = 0; /// /// The number to add to to get the tab index of the login button control. /// private const short LoginButtonTabIndexOffset = 1; /// /// The number to add to to get the tab index of the remember me checkbox control. /// private const short RememberMeTabIndexOffset = 2; /// /// The number to add to to get the tab index of the register link control. /// private const short RegisterTabIndexOffset = 3; #region Controls /// /// The control into which all other controls are added. /// private Panel panel; /// /// The Login button. /// private Button loginButton; /// /// The label that presents the text box. /// private HtmlGenericControl label; /// /// The validator that flags an empty text box. /// private RequiredFieldValidator requiredValidator; /// /// The validator that flags invalid formats of OpenID identifiers. /// private CustomValidator identifierFormatValidator; /// /// The label that precedes an example OpenID identifier. /// private Label examplePrefixLabel; /// /// The label that contains the example OpenID identifier. /// private Label exampleUrlLabel; /// /// A link to allow the user to create an account with a popular OpenID Provider. /// private HyperLink registerLink; /// /// The Remember Me checkbox. /// private CheckBox rememberMeCheckBox; /// /// The javascript snippet that activates the ID Selector javascript control. /// private Literal idselectorJavascript; /// /// The label that will display login failure messages. /// private Label errorLabel; #endregion /// /// Initializes a new instance of the class. /// public OpenIdLogin() { } #region Events /// /// Fired when the Remember Me checkbox is changed by the user. /// [Description("Fires when the Remember Me checkbox is changed by the user.")] public event EventHandler RememberMeChanged; #endregion #region Properties /// /// Gets a object that represents the child controls for a specified server control in the UI hierarchy. /// /// /// The collection of child controls for the specified server control. /// public override ControlCollection Controls { get { this.EnsureChildControls(); return base.Controls; } } /// /// Gets or sets the caption that appears before the text box. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(LabelTextDefault)] [Localizable(true)] [Description("The caption that appears before the text box.")] public string LabelText { get { EnsureChildControls(); return this.label.InnerText; } set { EnsureChildControls(); this.label.InnerText = value; } } /// /// Gets or sets the text that introduces the example OpenID url. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(ExamplePrefixDefault)] [Localizable(true)] [Description("The text that introduces the example OpenID url.")] public string ExamplePrefix { get { EnsureChildControls(); return this.examplePrefixLabel.Text; } set { EnsureChildControls(); this.examplePrefixLabel.Text = value; } } /// /// Gets or sets the example OpenID Identifier to display to the user. /// [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid only supports primitive types.")] [Bindable(true)] [Category("Appearance")] [DefaultValue(ExampleUrlDefault)] [Localizable(true)] [Description("The example OpenID Identifier to display to the user.")] public string ExampleUrl { get { EnsureChildControls(); return this.exampleUrlLabel.Text; } set { EnsureChildControls(); this.exampleUrlLabel.Text = value; } } /// /// Gets or sets the text to display if the user attempts to login /// without providing an Identifier. /// [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "br", Justification = "HTML"), Bindable(true)] [Category("Appearance")] [DefaultValue(RequiredTextDefault)] [Localizable(true)] [Description("The text to display if the user attempts to login without providing an Identifier.")] public string RequiredText { get { EnsureChildControls(); return this.requiredValidator.Text.Substring(0, this.requiredValidator.Text.Length - RequiredTextSuffix.Length); } set { EnsureChildControls(); this.requiredValidator.ErrorMessage = this.requiredValidator.Text = value + RequiredTextSuffix; } } /// /// Gets or sets the text to display if the user provides an invalid form for an Identifier. /// [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "br", Justification = "HTML"), SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid only supports primitive types.")] [Bindable(true)] [Category("Appearance")] [DefaultValue(UriFormatTextDefault)] [Localizable(true)] [Description("The text to display if the user provides an invalid form for an Identifier.")] public string UriFormatText { get { EnsureChildControls(); return this.identifierFormatValidator.Text.Substring(0, this.identifierFormatValidator.Text.Length - RequiredTextSuffix.Length); } set { EnsureChildControls(); this.identifierFormatValidator.ErrorMessage = this.identifierFormatValidator.Text = value + RequiredTextSuffix; } } /// /// Gets or sets a value indicating whether to perform Identifier /// format validation prior to an authentication attempt. /// [Bindable(true)] [Category("Behavior")] [DefaultValue(UriValidatorEnabledDefault)] [Description("Whether to perform Identifier format validation prior to an authentication attempt.")] public bool UriValidatorEnabled { get { EnsureChildControls(); return this.identifierFormatValidator.Enabled; } set { EnsureChildControls(); this.identifierFormatValidator.Enabled = value; } } /// /// Gets or sets the text of the link users can click on to obtain an OpenID. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(RegisterTextDefault)] [Localizable(true)] [Description("The text of the link users can click on to obtain an OpenID.")] public string RegisterText { get { EnsureChildControls(); return this.registerLink.Text; } set { EnsureChildControls(); this.registerLink.Text = value; } } /// /// Gets or sets the URL to link users to who click the link to obtain a new OpenID. /// [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid only supports primitive types.")] [Bindable(true)] [Category("Appearance")] [DefaultValue(RegisterUrlDefault)] [Localizable(true)] [Description("The URL to link users to who click the link to obtain a new OpenID.")] public string RegisterUrl { get { EnsureChildControls(); return this.registerLink.NavigateUrl; } set { EnsureChildControls(); this.registerLink.NavigateUrl = value; } } /// /// Gets or sets the text of the tooltip to display when the user hovers /// over the link to obtain a new OpenID. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(RegisterToolTipDefault)] [Localizable(true)] [Description("The text of the tooltip to display when the user hovers over the link to obtain a new OpenID.")] public string RegisterToolTip { get { EnsureChildControls(); return this.registerLink.ToolTip; } set { EnsureChildControls(); this.registerLink.ToolTip = value; } } /// /// Gets or sets a value indicating whether to display a link to /// allow users to easily obtain a new OpenID. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(RegisterVisibleDefault)] [Description("Whether to display a link to allow users to easily obtain a new OpenID.")] public bool RegisterVisible { get { EnsureChildControls(); return this.registerLink.Visible; } set { EnsureChildControls(); this.registerLink.Visible = value; } } /// /// Gets or sets the text that appears on the button that initiates login. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(ButtonTextDefault)] [Localizable(true)] [Description("The text that appears on the button that initiates login.")] public string ButtonText { get { EnsureChildControls(); return this.loginButton.Text; } set { EnsureChildControls(); this.loginButton.Text = value; } } /// /// Gets or sets the text of the "Remember Me" checkbox. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(RememberMeTextDefault)] [Localizable(true)] [Description("The text of the \"Remember Me\" checkbox.")] public string RememberMeText { get { EnsureChildControls(); return this.rememberMeCheckBox.Text; } set { EnsureChildControls(); this.rememberMeCheckBox.Text = value; } } /// /// Gets or sets the message display in the event of a failed /// authentication. {0} may be used to insert the actual error. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(FailedMessageTextDefault)] [Localizable(true)] [Description("The message display in the event of a failed authentication. {0} may be used to insert the actual error.")] public string FailedMessageText { get { return (string)ViewState[FailedMessageTextViewStateKey] ?? FailedMessageTextDefault; } set { ViewState[FailedMessageTextViewStateKey] = value; } } /// /// Gets or sets the text to display in the event of an authentication canceled at the Provider. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(CanceledTextDefault)] [Localizable(true)] [Description("The text to display in the event of an authentication canceled at the Provider.")] public string CanceledText { get { return (string)ViewState[CanceledTextViewStateKey] ?? CanceledTextDefault; } set { ViewState[CanceledTextViewStateKey] = value; } } /// /// Gets or sets a value indicating whether the "Remember Me" checkbox should be displayed. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(RememberMeVisibleDefault)] [Description("Whether the \"Remember Me\" checkbox should be displayed.")] public bool RememberMeVisible { get { EnsureChildControls(); return this.rememberMeCheckBox.Visible; } set { EnsureChildControls(); this.rememberMeCheckBox.Visible = value; } } /// /// Gets or sets a value indicating whether a successful authentication should result in a persistent /// cookie being saved to the browser. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(RememberMeDefault)] [Description("Whether a successful authentication should result in a persistent cookie being saved to the browser.")] public bool RememberMe { get { return this.UsePersistentCookie != LogOnPersistence.Session; } set { this.UsePersistentCookie = value ? LogOnPersistence.PersistentAuthentication : LogOnPersistence.Session; } } /// /// Gets or sets the starting tab index to distribute across the controls. /// [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "value+1", Justification = "Overflow would provide desired UI behavior.")] [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "value+2", Justification = "Overflow would provide desired UI behavior.")] [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "value+3", Justification = "Overflow would provide desired UI behavior.")] public override short TabIndex { get { return base.TabIndex; } set { unchecked { EnsureChildControls(); base.TabIndex = (short)(value + TextBoxTabIndexOffset); this.loginButton.TabIndex = (short)(value + LoginButtonTabIndexOffset); this.rememberMeCheckBox.TabIndex = (short)(value + RememberMeTabIndexOffset); this.registerLink.TabIndex = (short)(value + RegisterTabIndexOffset); } } } /// /// Gets or sets the tooltip to display when the user hovers over the login button. /// [Bindable(true)] [Category("Appearance")] [DefaultValue(ButtonToolTipDefault)] [Localizable(true)] [Description("The tooltip to display when the user hovers over the login button.")] public string ButtonToolTip { get { EnsureChildControls(); return this.loginButton.ToolTip; } set { EnsureChildControls(); this.loginButton.ToolTip = value; } } /// /// Gets or sets the validation group that the login button and text box validator belong to. /// [Category("Behavior")] [DefaultValue(ValidationGroupDefault)] [Description("The validation group that the login button and text box validator belong to.")] public string ValidationGroup { get { EnsureChildControls(); return this.requiredValidator.ValidationGroup; } set { EnsureChildControls(); this.requiredValidator.ValidationGroup = value; this.loginButton.ValidationGroup = value; } } /// /// Gets or sets the unique hash string that ends your idselector.com account. /// [Category("Behavior")] [Description("The unique hash string that ends your idselector.com account.")] public string IdSelectorIdentifier { get { return (string)ViewState[IdSelectorIdentifierViewStateKey]; } set { ViewState[IdSelectorIdentifierViewStateKey] = value; } } #endregion #region Properties to hide /// /// Gets or sets a value indicating whether a FormsAuthentication /// cookie should persist across user sessions. /// [Browsable(false), Bindable(false)] public override LogOnPersistence UsePersistentCookie { get { return base.UsePersistentCookie; } set { base.UsePersistentCookie = value; if (this.rememberMeCheckBox != null) { // use conditional here to prevent infinite recursion // with CheckedChanged event. bool rememberMe = value != LogOnPersistence.Session; if (this.rememberMeCheckBox.Checked != rememberMe) { this.rememberMeCheckBox.Checked = rememberMe; } } } } #endregion /// /// Outputs server control content to a provided object and stores tracing information about the control if tracing is enabled. /// /// The object that receives the control content. public override void RenderControl(HtmlTextWriter writer) { this.RenderChildren(writer); } /// /// Creates the child controls. /// protected override void CreateChildControls() { this.InitializeControls(); // Just add the panel we've assembled earlier. base.Controls.Add(this.panel); } /// /// Raises the event. /// /// An object that contains the event data. protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); this.EnsureChildControls(); } /// /// Initializes the child controls. /// [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.WebControl.set_ToolTip(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.Label.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.HyperLink.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.CheckBox.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.Button.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.BaseValidator.set_ErrorMessage(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "br", Justification = "HTML"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "OpenID", Justification = "It is correct"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "MyOpenID", Justification = "Correct spelling"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "myopenid", Justification = "URL")] protected void InitializeControls() { this.panel = new Panel(); Table table = new Table(); try { TableRow row1, row2, row3; TableCell cell; table.Rows.Add(row1 = new TableRow()); table.Rows.Add(row2 = new TableRow()); table.Rows.Add(row3 = new TableRow()); // top row, left cell cell = new TableCell(); try { this.label = new HtmlGenericControl("label"); this.label.InnerText = LabelTextDefault; cell.Controls.Add(this.label); row1.Cells.Add(cell); } catch { cell.Dispose(); throw; } // top row, middle cell cell = new TableCell(); try { cell.Controls.Add(new InPlaceControl(this)); row1.Cells.Add(cell); } catch { cell.Dispose(); throw; } // top row, right cell cell = new TableCell(); try { this.loginButton = new Button(); this.loginButton.ID = this.ID + "_loginButton"; this.loginButton.Text = ButtonTextDefault; this.loginButton.ToolTip = ButtonToolTipDefault; this.loginButton.Click += this.LoginButton_Click; this.loginButton.ValidationGroup = ValidationGroupDefault; #if !Mono this.panel.DefaultButton = this.loginButton.ID; #endif cell.Controls.Add(this.loginButton); row1.Cells.Add(cell); } catch { cell.Dispose(); throw; } // middle row, left cell row2.Cells.Add(new TableCell()); // middle row, middle cell cell = new TableCell(); try { cell.Style[HtmlTextWriterStyle.Color] = "gray"; cell.Style[HtmlTextWriterStyle.FontSize] = "smaller"; this.requiredValidator = new RequiredFieldValidator(); this.requiredValidator.ErrorMessage = RequiredTextDefault + RequiredTextSuffix; this.requiredValidator.Text = RequiredTextDefault + RequiredTextSuffix; this.requiredValidator.Display = ValidatorDisplay.Dynamic; this.requiredValidator.ValidationGroup = ValidationGroupDefault; cell.Controls.Add(this.requiredValidator); this.identifierFormatValidator = new CustomValidator(); this.identifierFormatValidator.ErrorMessage = UriFormatTextDefault + RequiredTextSuffix; this.identifierFormatValidator.Text = UriFormatTextDefault + RequiredTextSuffix; this.identifierFormatValidator.ServerValidate += this.IdentifierFormatValidator_ServerValidate; this.identifierFormatValidator.Enabled = UriValidatorEnabledDefault; this.identifierFormatValidator.Display = ValidatorDisplay.Dynamic; this.identifierFormatValidator.ValidationGroup = ValidationGroupDefault; cell.Controls.Add(this.identifierFormatValidator); this.errorLabel = new Label(); this.errorLabel.EnableViewState = false; this.errorLabel.ForeColor = System.Drawing.Color.Red; this.errorLabel.Style[HtmlTextWriterStyle.Display] = "block"; // puts it on its own line this.errorLabel.Visible = false; cell.Controls.Add(this.errorLabel); this.examplePrefixLabel = new Label(); this.examplePrefixLabel.Text = ExamplePrefixDefault; cell.Controls.Add(this.examplePrefixLabel); cell.Controls.Add(new LiteralControl(" ")); this.exampleUrlLabel = new Label(); this.exampleUrlLabel.Font.Bold = true; this.exampleUrlLabel.Text = ExampleUrlDefault; cell.Controls.Add(this.exampleUrlLabel); row2.Cells.Add(cell); } catch { cell.Dispose(); throw; } // middle row, right cell cell = new TableCell(); try { cell.Style[HtmlTextWriterStyle.Color] = "gray"; cell.Style[HtmlTextWriterStyle.FontSize] = "smaller"; cell.Style[HtmlTextWriterStyle.TextAlign] = "center"; this.registerLink = new HyperLink(); this.registerLink.Text = RegisterTextDefault; this.registerLink.ToolTip = RegisterToolTipDefault; this.registerLink.NavigateUrl = RegisterUrlDefault; this.registerLink.Visible = RegisterVisibleDefault; cell.Controls.Add(this.registerLink); row2.Cells.Add(cell); } catch { cell.Dispose(); throw; } // bottom row, left cell cell = new TableCell(); row3.Cells.Add(cell); // bottom row, middle cell cell = new TableCell(); try { this.rememberMeCheckBox = new CheckBox(); this.rememberMeCheckBox.Text = RememberMeTextDefault; this.rememberMeCheckBox.Checked = this.UsePersistentCookie != LogOnPersistence.Session; this.rememberMeCheckBox.Visible = RememberMeVisibleDefault; this.rememberMeCheckBox.CheckedChanged += this.RememberMeCheckBox_CheckedChanged; cell.Controls.Add(this.rememberMeCheckBox); row3.Cells.Add(cell); } catch { cell.Dispose(); throw; } // bottom row, right cell cell = new TableCell(); try { row3.Cells.Add(cell); } catch { cell.Dispose(); throw; } // this sets all the controls' tab indexes this.TabIndex = TabIndexDefault; this.panel.Controls.Add(table); } catch { table.Dispose(); throw; } this.idselectorJavascript = new Literal(); this.panel.Controls.Add(this.idselectorJavascript); } /// /// Raises the event. /// /// An object that contains the event data. protected override void OnInit(EventArgs e) { this.SetChildControlReferenceIds(); base.OnInit(e); } /// /// Renders the child controls. /// /// The object that receives the rendered content. [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.Literal.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "idselector", Justification = "HTML"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "charset", Justification = "html"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "src", Justification = "html"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "openidselector", Justification = "html"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "idselectorinputid", Justification = "html")] protected override void RenderChildren(HtmlTextWriter writer) { if (!this.DesignMode) { this.label.Attributes["for"] = this.ClientID; if (!string.IsNullOrEmpty(this.IdSelectorIdentifier)) { this.idselectorJavascript.Visible = true; this.idselectorJavascript.Text = @" "; } else { this.idselectorJavascript.Visible = false; } } base.RenderChildren(writer); } /// /// Adds failure handling to display an error message to the user. /// /// The response. protected override void OnFailed(IAuthenticationResponse response) { base.OnFailed(response); if (!string.IsNullOrEmpty(this.FailedMessageText)) { this.errorLabel.Text = string.Format(CultureInfo.CurrentCulture, this.FailedMessageText, response.Exception.ToStringDescriptive()); this.errorLabel.Visible = true; } } /// /// Adds authentication cancellation behavior to display a message to the user. /// /// The response. protected override void OnCanceled(IAuthenticationResponse response) { base.OnCanceled(response); if (!string.IsNullOrEmpty(this.CanceledText)) { this.errorLabel.Text = this.CanceledText; this.errorLabel.Visible = true; } } /// /// Fires the event. /// protected virtual void OnRememberMeChanged() { EventHandler rememberMeChanged = this.RememberMeChanged; if (rememberMeChanged != null) { rememberMeChanged(this, new EventArgs()); } } /// /// Handles the ServerValidate event of the identifierFormatValidator control. /// /// The source of the event. /// The instance containing the event data. private void IdentifierFormatValidator_ServerValidate(object source, ServerValidateEventArgs args) { args.IsValid = Identifier.IsValid(args.Value); } /// /// Handles the CheckedChanged event of the rememberMeCheckBox control. /// /// The source of the event. /// The instance containing the event data. private void RememberMeCheckBox_CheckedChanged(object sender, EventArgs e) { this.RememberMe = this.rememberMeCheckBox.Checked; this.OnRememberMeChanged(); } /// /// Handles the Click event of the loginButton control. /// /// The source of the event. /// The instance containing the event data. private void LoginButton_Click(object sender, EventArgs e) { this.Page.RegisterAsyncTask( new PageAsyncTask( async ct => { if (!this.Page.IsValid) { return; } var authenticationRequests = await this.CreateRequestsAsync(CancellationToken.None); IAuthenticationRequest request = authenticationRequests.FirstOrDefault(); if (request != null) { await this.LogOnAsync(request, CancellationToken.None); } else { if (!string.IsNullOrEmpty(this.FailedMessageText)) { this.errorLabel.Text = string.Format( CultureInfo.CurrentCulture, this.FailedMessageText, OpenIdStrings.OpenIdEndpointNotFound); this.errorLabel.Visible = true; } } })); } /// /// Renders the control inner. /// /// The writer. private void RenderControlInner(HtmlTextWriter writer) { base.RenderControl(writer); } /// /// Sets child control properties that depend on this control's ID. /// private void SetChildControlReferenceIds() { this.EnsureChildControls(); this.EnsureID(); ErrorUtilities.VerifyInternal(!string.IsNullOrEmpty(this.ID), "No control ID available yet!"); this.requiredValidator.ControlToValidate = this.ID; this.requiredValidator.ID = this.ID + "_requiredValidator"; this.identifierFormatValidator.ControlToValidate = this.ID; this.identifierFormatValidator.ID = this.ID + "_identifierFormatValidator"; } /// /// A control that acts as a placeholder to indicate where /// the OpenIdLogin control should render its OpenIdTextBox parent. /// private class InPlaceControl : PlaceHolder { /// /// The owning control to render. /// private OpenIdLogin renderControl; /// /// Initializes a new instance of the class. /// /// The render control. internal InPlaceControl(OpenIdLogin renderControl) { this.renderControl = renderControl; } /// /// Sends server control content to a provided object, which writes the content to be rendered on the client. /// /// The object that receives the server control content. protected override void Render(HtmlTextWriter writer) { this.renderControl.RenderControlInner(writer); } } } }