//-----------------------------------------------------------------------
//
// 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();
}
}
}
}