//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.RelyingParty { using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Drawing.Design; using System.Globalization; using System.Linq; using System.Text; using System.Web.UI; using DotNetOpenAuth.Messaging; /// /// An ASP.NET control that renders a button that initiates an /// authentication when clicked. /// public class OpenIdButton : OpenIdRelyingPartyControlBase { #region Property defaults /// /// The default value for the property. /// private const string TextDefault = "Log in with [Provider]!"; /// /// The default value for the property. /// private const bool PrecreateRequestDefault = false; #endregion #region View state keys /// /// The key under which the value for the property will be stored. /// private const string TextViewStateKey = "Text"; /// /// The key under which the value for the property will be stored. /// private const string ImageUrlViewStateKey = "ImageUrl"; /// /// The key under which the value for the property will be stored. /// private const string PrecreateRequestViewStateKey = "PrecreateRequest"; #endregion /// /// Initializes a new instance of the class. /// public OpenIdButton() { } /// /// Gets or sets the text to display for the link. /// [Bindable(true), DefaultValue(TextDefault), Category(AppearanceCategory)] [Description("The text to display for the link.")] public string Text { get { return (string)ViewState[TextViewStateKey] ?? TextDefault; } set { ViewState[TextViewStateKey] = value; } } /// /// Gets or sets the image to display. /// [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")] [Bindable(true), Category(AppearanceCategory)] [Description("The image to display.")] [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] public string ImageUrl { get { return (string)ViewState[ImageUrlViewStateKey]; } set { UriUtil.ValidateResolvableUrl(Page, DesignMode, value); ViewState[ImageUrlViewStateKey] = value; } } /// /// Gets or sets a value indicating whether to pre-discover the identifier so /// the user agent has an immediate redirect. /// [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Precreate", Justification = "Breaking change to public API")] [Bindable(true), Category(OpenIdCategory), DefaultValue(PrecreateRequestDefault)] [Description("Whether to pre-discover the identifier so the user agent has an immediate redirect.")] public bool PrecreateRequest { get { return (bool)(ViewState[PrecreateRequestViewStateKey] ?? PrecreateRequestDefault); } set { ViewState[PrecreateRequestViewStateKey] = value; } } /// /// Gets or sets a value indicating when to use a popup window to complete the login experience. /// /// The default value is . [Bindable(false), Browsable(false)] public override PopupBehavior Popup { get { return base.Popup; } set { ErrorUtilities.VerifySupported(value == base.Popup, OpenIdStrings.PropertyValueNotSupported); } } /// /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server. /// /// A that represents an optional event argument to be passed to the event handler. protected override void RaisePostBackEvent(string eventArgument) { if (!this.PrecreateRequest) { try { IAuthenticationRequest request = this.CreateRequests().First(); request.RedirectToProvider(); } catch (InvalidOperationException ex) { throw ErrorUtilities.Wrap(ex, OpenIdStrings.OpenIdEndpointNotFound); } } } /// /// Raises the event. /// /// An object that contains the event data. protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); if (!this.DesignMode) { ErrorUtilities.VerifyOperation(this.Identifier != null, OpenIdStrings.NoIdentifierSet); } } /// /// 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. [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.HtmlTextWriter.WriteEncodedText(System.String)", Justification = "Not localizable")] protected override void Render(HtmlTextWriter writer) { if (string.IsNullOrEmpty(this.Identifier)) { writer.WriteEncodedText(string.Format(CultureInfo.CurrentCulture, "[{0}]", OpenIdStrings.NoIdentifierSet)); } else { string tooltip = this.Text; if (this.PrecreateRequest && !this.DesignMode) { IAuthenticationRequest request = this.CreateRequests().FirstOrDefault(); if (request != null) { RenderOpenIdMessageTransmissionAsAnchorAttributes(writer, request, tooltip); } else { tooltip = OpenIdStrings.OpenIdEndpointNotFound; } } else { writer.AddAttribute(HtmlTextWriterAttribute.Href, this.Page.ClientScript.GetPostBackClientHyperlink(this, null)); } writer.AddAttribute(HtmlTextWriterAttribute.Title, tooltip); writer.RenderBeginTag(HtmlTextWriterTag.A); if (!string.IsNullOrEmpty(this.ImageUrl)) { writer.AddAttribute(HtmlTextWriterAttribute.Src, this.ResolveClientUrl(this.ImageUrl)); writer.AddAttribute(HtmlTextWriterAttribute.Border, "0"); writer.AddAttribute(HtmlTextWriterAttribute.Alt, this.Text); writer.AddAttribute(HtmlTextWriterAttribute.Title, this.Text); writer.RenderBeginTag(HtmlTextWriterTag.Img); writer.RenderEndTag(); } else if (!string.IsNullOrEmpty(this.Text)) { writer.WriteEncodedText(this.Text); } writer.RenderEndTag(); } } } }