summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OpenId.RelyingParty
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OpenId.RelyingParty')
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj31
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdAjaxOptions.cs76
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdHelper.cs431
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Controls.cd112
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs242
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.cs877
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.css49
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.js644
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdButton.cs179
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdEventArgs.cs74
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdLogin.cs1001
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdMobileTextBox.cs778
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs468
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js751
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs1054
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js172
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.cs455
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.css109
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.js196
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdTextBox.cs708
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PopupBehavior.cs31
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButton.cs46
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButtonContract.cs46
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorOpenIdButton.cs82
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorProviderButton.cs113
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_failure.pngbin714 -> 0 bytes
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success (lock).pngbin571 -> 0 bytes
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success.pngbin464 -> 0 bytes
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/openid_login.pngbin457 -> 0 bytes
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/spinner.gifbin725 -> 0 bytes
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/Properties/AssemblyInfo.cs2
31 files changed, 2 insertions, 8725 deletions
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj b/src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj
index c9158ba..4222497 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty/DotNetOpenAuth.OpenId.RelyingParty.csproj
@@ -39,8 +39,6 @@
<Compile Include="OpenId\Messages\AssociateSuccessfulResponseContract.cs" />
<Compile Include="OpenId\Messages\AssociateSuccessfulResponseRelyingParty.cs" />
<Compile Include="OpenId\Messages\AssociateUnencryptedResponseRelyingParty.cs" />
- <Compile Include="OpenId\Mvc\OpenIdAjaxOptions.cs" />
- <Compile Include="OpenId\Mvc\OpenIdHelper.cs" />
<Compile Include="OpenId\RelyingParty\CryptoKeyStoreAsRelyingPartyAssociationStore.cs" />
<Compile Include="OpenId\RelyingParty\IRelyingPartyAssociationStore.cs" />
<Compile Include="OpenId\RelyingParty\Associations.cs" />
@@ -49,47 +47,18 @@
<Compile Include="OpenId\RelyingParty\AuthenticationRequest.cs" />
<Compile Include="OpenId\RelyingParty\DuplicateRequestedHostsComparer.cs" />
<Compile Include="OpenId\RelyingParty\NegativeAuthenticationResponse.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdAjaxRelyingParty.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdAjaxTextBox.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdButton.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdEventArgs.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdLogin.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdMobileTextBox.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdSelector.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdTextBox.cs" />
- <Compile Include="OpenId\RelyingParty\PopupBehavior.cs" />
<Compile Include="OpenId\RelyingParty\PositiveAnonymousResponse.cs" />
<Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponse.cs" />
<Compile Include="OpenId\RelyingParty\FailedAuthenticationResponse.cs" />
<Compile Include="OpenId\RelyingParty\ISetupRequiredAuthenticationResponse.cs" />
<Compile Include="OpenId\RelyingParty\OpenIdRelyingParty.cs" />
<Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponseSnapshot.cs" />
- <Compile Include="OpenId\RelyingParty\SelectorButton.cs" />
- <Compile Include="OpenId\RelyingParty\SelectorButtonContract.cs" />
- <Compile Include="OpenId\RelyingParty\SelectorOpenIdButton.cs" />
- <Compile Include="OpenId\RelyingParty\SelectorProviderButton.cs" />
<Compile Include="OpenId\RelyingParty\SimpleXrdsProviderEndpoint.cs" />
<Compile Include="OpenId\RelyingParty\StandardRelyingPartyApplicationStore.cs" />
<Compile Include="OpenId\RelyingParty\WellKnownProviders.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
- <Content Include="OpenId\RelyingParty\login_failure.png" />
- <Content Include="OpenId\RelyingParty\login_success %28lock%29.png" />
- <Content Include="OpenId\RelyingParty\login_success.png" />
- <Content Include="OpenId\RelyingParty\OpenIdAjaxTextBox.css" />
- <Content Include="OpenId\RelyingParty\OpenIdAjaxTextBox.js" />
- <Content Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.js" />
- <Content Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.js" />
- <Content Include="OpenId\RelyingParty\OpenIdSelector.css" />
- <Content Include="OpenId\RelyingParty\OpenIdSelector.js" />
- <Content Include="OpenId\RelyingParty\openid_login.png" />
- <Content Include="OpenId\RelyingParty\spinner.gif" />
- </ItemGroup>
- <ItemGroup>
- <None Include="OpenId\RelyingParty\Controls.cd" />
<None Include="OpenId\RelyingParty\OpenIdRelyingParty.cd" />
</ItemGroup>
<ItemGroup>
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdAjaxOptions.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdAjaxOptions.cs
deleted file mode 100644
index 4b88d04..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdAjaxOptions.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdAjaxOptions.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Mvc {
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// A set of customizations available for the scripts sent to the browser in AJAX OpenID scenarios.
- /// </summary>
- public class OpenIdAjaxOptions {
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdAjaxOptions"/> class.
- /// </summary>
- public OpenIdAjaxOptions() {
- this.AssertionHiddenFieldId = "openid_openidAuthData";
- this.ReturnUrlHiddenFieldId = "ReturnUrl";
- }
-
- /// <summary>
- /// Gets or sets the ID of the hidden field that should carry the positive assertion
- /// until it is posted to the RP.
- /// </summary>
- public string AssertionHiddenFieldId { get; set; }
-
- /// <summary>
- /// Gets or sets the ID of the hidden field that should be set with the parent window/frame's URL
- /// prior to posting the form with the positive assertion. Useful for jQuery popup dialogs.
- /// </summary>
- public string ReturnUrlHiddenFieldId { get; set; }
-
- /// <summary>
- /// Gets or sets the index of the form in the document.forms array on the browser that should
- /// be submitted when the user is ready to send the positive assertion to the RP.
- /// </summary>
- public int FormIndex { get; set; }
-
- /// <summary>
- /// Gets or sets the id of the form in the document.forms array on the browser that should
- /// be submitted when the user is ready to send the positive assertion to the RP. A value
- /// in this property takes precedence over any value in the <see cref="FormIndex"/> property.
- /// </summary>
- /// <value>The form id.</value>
- public string FormId { get; set; }
-
- /// <summary>
- /// Gets or sets the preloaded discovery results.
- /// </summary>
- public string PreloadedDiscoveryResults { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether to print diagnostic trace messages in the browser.
- /// </summary>
- public bool ShowDiagnosticTrace { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether to show all the "hidden" iframes that facilitate
- /// asynchronous authentication of the user for diagnostic purposes.
- /// </summary>
- public bool ShowDiagnosticIFrame { get; set; }
-
- /// <summary>
- /// Gets the form key to use when accessing the relevant form.
- /// </summary>
- internal string FormKey {
- get { return string.IsNullOrEmpty(this.FormId) ? this.FormIndex.ToString(CultureInfo.InvariantCulture) : MessagingUtilities.GetSafeJavascriptValue(this.FormId); }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdHelper.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdHelper.cs
deleted file mode 100644
index b98e0d6..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Mvc/OpenIdHelper.cs
+++ /dev/null
@@ -1,431 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdHelper.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Mvc {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Routing;
- using System.Web.UI;
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.RelyingParty;
-
- /// <summary>
- /// Methods that generate HTML or Javascript for hosting AJAX OpenID "controls" on
- /// ASP.NET MVC web sites.
- /// </summary>
- public static class OpenIdHelper {
- /// <summary>
- /// Emits a series of stylesheet import tags to support the AJAX OpenID Selector.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <returns>HTML that should be sent directly to the browser.</returns>
- public static string OpenIdSelectorStyles(this HtmlHelper html) {
- Contract.Requires<ArgumentNullException>(html != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- using (var result = new StringWriter(CultureInfo.CurrentCulture)) {
- result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdSelector.EmbeddedStylesheetResourceName);
- result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedStylesheetResourceName);
- return result.ToString();
- }
- }
-
- /// <summary>
- /// Emits a series of script import tags and some inline script to support the AJAX OpenID Selector.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <returns>HTML that should be sent directly to the browser.</returns>
- public static string OpenIdSelectorScripts(this HtmlHelper html) {
- return OpenIdSelectorScripts(html, null, null);
- }
-
- /// <summary>
- /// Emits a series of script import tags and some inline script to support the AJAX OpenID Selector.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="selectorOptions">An optional instance of an <see cref="OpenIdSelector"/> control, whose properties have been customized to express how this MVC control should be rendered.</param>
- /// <param name="additionalOptions">An optional set of additional script customizations.</param>
- /// <returns>
- /// HTML that should be sent directly to the browser.
- /// </returns>
- [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive")]
- public static string OpenIdSelectorScripts(this HtmlHelper html, OpenIdSelector selectorOptions, OpenIdAjaxOptions additionalOptions) {
- Contract.Requires<ArgumentNullException>(html != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- bool selectorOptionsOwned = false;
- if (selectorOptions == null) {
- selectorOptionsOwned = true;
- selectorOptions = new OpenId.RelyingParty.OpenIdSelector();
- }
- try {
- if (additionalOptions == null) {
- additionalOptions = new OpenIdAjaxOptions();
- }
-
- using (StringWriter result = new StringWriter(CultureInfo.CurrentCulture)) {
- if (additionalOptions.ShowDiagnosticIFrame || additionalOptions.ShowDiagnosticTrace) {
- string scriptFormat = @"window.openid_visible_iframe = {0}; // causes the hidden iframe to show up
-window.openid_trace = {1}; // causes lots of messages";
- result.WriteScriptBlock(string.Format(
- CultureInfo.InvariantCulture,
- scriptFormat,
- additionalOptions.ShowDiagnosticIFrame ? "true" : "false",
- additionalOptions.ShowDiagnosticTrace ? "true" : "false"));
- }
- var scriptResources = new[] {
- OpenIdRelyingPartyControlBase.EmbeddedJavascriptResource,
- OpenIdRelyingPartyAjaxControlBase.EmbeddedAjaxJavascriptResource,
- OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedScriptResourceName,
- };
- result.WriteScriptTags(scriptResources);
-
- if (selectorOptions.DownloadYahooUILibrary) {
- result.WriteScriptTagsUrls(new[] { "https://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js" });
- }
-
- using (var blockBuilder = new StringWriter(CultureInfo.CurrentCulture)) {
- if (selectorOptions.DownloadYahooUILibrary) {
- blockBuilder.WriteLine(@" try {
- if (YAHOO) {
- var loader = new YAHOO.util.YUILoader({
- require: ['button', 'menu'],
- loadOptional: false,
- combine: true
- });
-
- loader.insert();
- }
- } catch (e) { }");
- }
-
- blockBuilder.WriteLine("window.aspnetapppath = '{0}';", VirtualPathUtility.AppendTrailingSlash(HttpContext.Current.Request.ApplicationPath));
-
- // Positive assertions can last no longer than this library is willing to consider them valid,
- // and when they come with OP private associations they last no longer than the OP is willing
- // to consider them valid. We assume the OP will hold them valid for at least five minutes.
- double assertionLifetimeInMilliseconds = Math.Min(TimeSpan.FromMinutes(5).TotalMilliseconds, Math.Min(OpenIdElement.Configuration.MaxAuthenticationTime.TotalMilliseconds, DotNetOpenAuthSection.Messaging.MaximumMessageLifetime.TotalMilliseconds));
- blockBuilder.WriteLine(
- "{0} = {1};",
- OpenIdRelyingPartyAjaxControlBase.MaxPositiveAssertionLifetimeJsName,
- assertionLifetimeInMilliseconds.ToString(CultureInfo.InvariantCulture));
-
- if (additionalOptions.PreloadedDiscoveryResults != null) {
- blockBuilder.WriteLine(additionalOptions.PreloadedDiscoveryResults);
- }
-
- string discoverUrl = VirtualPathUtility.AppendTrailingSlash(HttpContext.Current.Request.ApplicationPath) + html.RouteCollection["OpenIdDiscover"].GetVirtualPath(html.ViewContext.RequestContext, new RouteValueDictionary(new { identifier = "xxx" })).VirtualPath;
- string blockFormat = @" {0} = function (argument, resultFunction, errorCallback) {{
- jQuery.ajax({{
- async: true,
- dataType: 'text',
- error: function (request, status, error) {{ errorCallback(status, argument); }},
- success: function (result) {{ resultFunction(result, argument); }},
- url: '{1}'.replace('xxx', encodeURIComponent(argument))
- }});
- }};";
- blockBuilder.WriteLine(blockFormat, OpenIdRelyingPartyAjaxControlBase.CallbackJSFunctionAsync, discoverUrl);
-
- blockFormat = @" window.postLoginAssertion = function (positiveAssertion) {{
- $('#{0}')[0].setAttribute('value', positiveAssertion);
- if ($('#{1}')[0] && !$('#{1}')[0].value) {{ // popups have no ReturnUrl predefined, but full page LogOn does.
- $('#{1}')[0].setAttribute('value', window.parent.location.href);
- }}
- document.forms[{2}].submit();
- }};";
- blockBuilder.WriteLine(
- blockFormat,
- additionalOptions.AssertionHiddenFieldId,
- additionalOptions.ReturnUrlHiddenFieldId,
- additionalOptions.FormKey);
-
- blockFormat = @" $(function () {{
- var box = document.getElementsByName('openid_identifier')[0];
- initAjaxOpenId(box, {0}, {1}, {2}, {3}, {4}, {5},
- null, // js function to invoke on receiving a positive assertion
- {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17},
- false, // auto postback
- null); // PostBackEventReference (unused in MVC)
- }});";
- blockBuilder.WriteLine(
- blockFormat,
- MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenIdTextBox.EmbeddedLogoResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedSpinnerResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginFailureResourceName)),
- selectorOptions.Throttle,
- selectorOptions.Timeout.TotalMilliseconds,
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnText),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnToolTip),
- selectorOptions.TextBox.ShowLogOnPostBackButton ? "true" : "false",
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnPostBackToolTip),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.RetryText),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.RetryToolTip),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.BusyToolTip),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.IdentifierRequiredMessage),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnInProgressMessage),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticationSucceededToolTip),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticatedAsToolTip),
- MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticationFailedToolTip));
-
- result.WriteScriptBlock(blockBuilder.ToString());
- result.WriteScriptTags(OpenId.RelyingParty.OpenIdSelector.EmbeddedScriptResourceName);
-
- Reporting.RecordFeatureUse("MVC " + typeof(OpenIdSelector).Name);
- return result.ToString();
- }
- }
- } catch {
- if (selectorOptionsOwned) {
- selectorOptions.Dispose();
- }
-
- throw;
- }
- }
-
- /// <summary>
- /// Emits the HTML to render an OpenID Provider button as a part of the overall OpenID Selector UI.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="providerIdentifier">The OP Identifier.</param>
- /// <param name="imageUrl">The URL of the image to display on the button.</param>
- /// <returns>
- /// HTML that should be sent directly to the browser.
- /// </returns>
- public static string OpenIdSelectorOPButton(this HtmlHelper html, Identifier providerIdentifier, string imageUrl) {
- Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(providerIdentifier != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
- Contract.Ensures(Contract.Result<string>() != null);
-
- return OpenIdSelectorButton(html, providerIdentifier, "OPButton", imageUrl);
- }
-
- /// <summary>
- /// Emits the HTML to render a generic OpenID button as a part of the overall OpenID Selector UI,
- /// allowing the user to enter their own OpenID.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="imageUrl">The URL of the image to display on the button.</param>
- /// <returns>
- /// HTML that should be sent directly to the browser.
- /// </returns>
- public static string OpenIdSelectorOpenIdButton(this HtmlHelper html, string imageUrl) {
- Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
- Contract.Ensures(Contract.Result<string>() != null);
-
- return OpenIdSelectorButton(html, "OpenIDButton", "OpenIDButton", imageUrl);
- }
-
- /// <summary>
- /// Emits the HTML to render the entire OpenID Selector UI.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="buttons">The buttons to include on the selector.</param>
- /// <returns>
- /// HTML that should be sent directly to the browser.
- /// </returns>
- [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Not a problem for this type.")]
- public static string OpenIdSelector(this HtmlHelper html, params SelectorButton[] buttons) {
- Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(buttons != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- using (var writer = new StringWriter(CultureInfo.CurrentCulture)) {
- using (var h = new HtmlTextWriter(writer)) {
- h.AddAttribute(HtmlTextWriterAttribute.Class, "OpenIdProviders");
- h.RenderBeginTag(HtmlTextWriterTag.Ul);
-
- foreach (SelectorButton button in buttons) {
- var op = button as SelectorProviderButton;
- if (op != null) {
- h.Write(OpenIdSelectorOPButton(html, op.OPIdentifier, op.Image));
- continue;
- }
-
- var openid = button as SelectorOpenIdButton;
- if (openid != null) {
- h.Write(OpenIdSelectorOpenIdButton(html, openid.Image));
- continue;
- }
-
- ErrorUtilities.VerifySupported(false, "The {0} button is not yet supported for MVC.", button.GetType().Name);
- }
-
- h.RenderEndTag(); // ul
-
- if (buttons.OfType<SelectorOpenIdButton>().Any()) {
- h.Write(OpenIdAjaxTextBox(html));
- }
- }
-
- return writer.ToString();
- }
- }
-
- /// <summary>
- /// Emits the HTML to render the <see cref="OpenIdAjaxTextBox"/> control as a part of the overall
- /// OpenID Selector UI.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <returns>
- /// HTML that should be sent directly to the browser.
- /// </returns>
- [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "html", Justification = "Breaking change, and it's an extension method so it's useful.")]
- public static string OpenIdAjaxTextBox(this HtmlHelper html) {
- return @"<div style='display: none' id='OpenIDForm'>
- <span class='OpenIdAjaxTextBox' style='display: inline-block; position: relative; font-size: 16px'>
- <input name='openid_identifier' id='openid_identifier' size='40' style='padding-left: 18px; border-style: solid; border-width: 1px; border-color: lightgray' />
- </span>
- </div>";
- }
-
- /// <summary>
- /// Emits the HTML to render a button as a part of the overall OpenID Selector UI.
- /// </summary>
- /// <param name="html">The <see cref="HtmlHelper"/> on the view.</param>
- /// <param name="id">The value to assign to the HTML id attribute.</param>
- /// <param name="cssClass">The value to assign to the HTML class attribute.</param>
- /// <param name="imageUrl">The URL of the image to draw on the button.</param>
- /// <returns>
- /// HTML that should be sent directly to the browser.
- /// </returns>
- [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Not a problem for this type.")]
- private static string OpenIdSelectorButton(this HtmlHelper html, string id, string cssClass, string imageUrl) {
- Contract.Requires<ArgumentNullException>(html != null);
- Contract.Requires<ArgumentNullException>(id != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
- Contract.Ensures(Contract.Result<string>() != null);
-
- using (var writer = new StringWriter(CultureInfo.CurrentCulture)) {
- using (var h = new HtmlTextWriter(writer)) {
- h.AddAttribute(HtmlTextWriterAttribute.Id, id);
- if (!string.IsNullOrEmpty(cssClass)) {
- h.AddAttribute(HtmlTextWriterAttribute.Class, cssClass);
- }
- h.RenderBeginTag(HtmlTextWriterTag.Li);
-
- h.AddAttribute(HtmlTextWriterAttribute.Href, "#");
- h.RenderBeginTag(HtmlTextWriterTag.A);
-
- h.RenderBeginTag(HtmlTextWriterTag.Div);
- h.RenderBeginTag(HtmlTextWriterTag.Div);
-
- h.AddAttribute(HtmlTextWriterAttribute.Src, imageUrl);
- h.RenderBeginTag(HtmlTextWriterTag.Img);
- h.RenderEndTag();
-
- h.AddAttribute(HtmlTextWriterAttribute.Src, Util.GetWebResourceUrl(typeof(OpenIdSelector), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName));
- h.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess");
- h.AddAttribute(HtmlTextWriterAttribute.Title, "Authenticated as {0}");
- h.RenderBeginTag(HtmlTextWriterTag.Img);
- h.RenderEndTag();
-
- h.RenderEndTag(); // div
-
- h.AddAttribute(HtmlTextWriterAttribute.Class, "ui-widget-overlay");
- h.RenderBeginTag(HtmlTextWriterTag.Div);
- h.RenderEndTag(); // div
-
- h.RenderEndTag(); // div
- h.RenderEndTag(); // a
- h.RenderEndTag(); // li
- }
-
- return writer.ToString();
- }
- }
-
- /// <summary>
- /// Emits &lt;script&gt; tags that import a given set of scripts given their URLs.
- /// </summary>
- /// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="scriptUrls">The locations of the scripts to import.</param>
- private static void WriteScriptTagsUrls(this TextWriter writer, IEnumerable<string> scriptUrls) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentNullException>(scriptUrls != null);
-
- foreach (string script in scriptUrls) {
- writer.WriteLine("<script type='text/javascript' src='{0}'></script>", script);
- }
- }
-
- /// <summary>
- /// Writes out script tags that import a script from resources embedded in this assembly.
- /// </summary>
- /// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="resourceName">Name of the resource.</param>
- private static void WriteScriptTags(this TextWriter writer, string resourceName) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(resourceName));
-
- WriteScriptTags(writer, new[] { resourceName });
- }
-
- /// <summary>
- /// Writes out script tags that import scripts from resources embedded in this assembly.
- /// </summary>
- /// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="resourceNames">The resource names.</param>
- private static void WriteScriptTags(this TextWriter writer, IEnumerable<string> resourceNames) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentNullException>(resourceNames != null);
-
- writer.WriteScriptTagsUrls(resourceNames.Select(r => Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), r)));
- }
-
- /// <summary>
- /// Writes a given script block, surrounding it with &lt;script&gt; and CDATA tags.
- /// </summary>
- /// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="script">The script to inline on the page.</param>
- private static void WriteScriptBlock(this TextWriter writer, string script) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(script));
-
- writer.WriteLine("<script type='text/javascript' language='javascript'><!--");
- writer.WriteLine("//<![CDATA[");
- writer.WriteLine(script);
- writer.WriteLine("//]]>--></script>");
- }
-
- /// <summary>
- /// Writes a given CSS link.
- /// </summary>
- /// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="resourceName">Name of the resource containing the CSS content.</param>
- private static void WriteStylesheetLink(this TextWriter writer, string resourceName) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(resourceName));
-
- WriteStylesheetLinkUrl(writer, Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyAjaxControlBase), resourceName));
- }
-
- /// <summary>
- /// Writes a given CSS link.
- /// </summary>
- /// <param name="writer">The writer to emit the tags to.</param>
- /// <param name="stylesheet">The stylesheet to link in.</param>
- private static void WriteStylesheetLinkUrl(this TextWriter writer, string stylesheet) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(stylesheet));
-
- writer.WriteLine("<link rel='stylesheet' type='text/css' href='{0}' />", stylesheet);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Controls.cd b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Controls.cd
deleted file mode 100644
index f96db36..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/Controls.cd
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ClassDiagram MajorVersion="1" MinorVersion="1">
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyAjaxControlBase">
- <Position X="0.5" Y="9.75" Width="3" />
- <Compartments>
- <Compartment Name="Fields" Collapsed="true" />
- </Compartments>
- <TypeIdentifier>
- <HashCode>BARAAAAAAAAAAACQAAAAAAAEAAAgAAAAAQAFAAAAAFk=</HashCode>
- <FileName>OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.cs</FileName>
- </TypeIdentifier>
- <Lollipop Position="0.2" />
- </Class>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdMobileTextBox">
- <Position X="8.5" Y="5.25" Width="2.5" />
- <Compartments>
- <Compartment Name="Fields" Collapsed="true" />
- </Compartments>
- <TypeIdentifier>
- <HashCode>AI0JADgFQRQQDAIw4lAYSEIWCAMZhMVlELAASQIAgSI=</HashCode>
- <FileName>OpenId\RelyingParty\OpenIdMobileTextBox.cs</FileName>
- </TypeIdentifier>
- </Class>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdLogin">
- <Position X="6.25" Y="1.25" Width="1.75" />
- <Compartments>
- <Compartment Name="Fields" Collapsed="true" />
- </Compartments>
- <NestedTypes>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdLogin.InPlaceControl" Collapsed="true">
- <TypeIdentifier>
- <NewMemberFileName>OpenId\RelyingParty\OpenIdLogin.cs</NewMemberFileName>
- </TypeIdentifier>
- </Class>
- </NestedTypes>
- <TypeIdentifier>
- <HashCode>gIMgADAIAQEQIJAYOQBSADiQBgiIECk0jQCggdAp4BQ=</HashCode>
- <FileName>OpenId\RelyingParty\OpenIdLogin.cs</FileName>
- </TypeIdentifier>
- </Class>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox">
- <Position X="3.75" Y="10" Width="2.25" />
- <Compartments>
- <Compartment Name="Fields" Collapsed="true" />
- </Compartments>
- <TypeIdentifier>
- <HashCode>ACBEEbABZzOzAKCYJNOEwM3uSIR5AAOkUFANCQ7DsVs=</HashCode>
- <FileName>OpenId\RelyingParty\OpenIdAjaxTextBox.cs</FileName>
- </TypeIdentifier>
- <Lollipop Position="0.2" />
- </Class>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdButton">
- <Position X="8.75" Y="1" Width="1.75" />
- <Compartments>
- <Compartment Name="Fields" Collapsed="true" />
- </Compartments>
- <InheritanceLine Type="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
- <Path>
- <Point X="2.875" Y="0.5" />
- <Point X="7.194" Y="0.5" />
- <Point X="7.194" Y="1" />
- <Point X="8.75" Y="1" />
- </Path>
- </InheritanceLine>
- <TypeIdentifier>
- <HashCode>BAAEQAAAAAAAAAACAAAgAAAAAIAAAACQABAECABAAAA=</HashCode>
- <FileName>OpenId\RelyingParty\OpenIdButton.cs</FileName>
- </TypeIdentifier>
- <Lollipop Position="0.2" />
- </Class>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdTextBox">
- <Position X="3.5" Y="1.25" Width="2.25" />
- <Compartments>
- <Compartment Name="Fields" Collapsed="true" />
- </Compartments>
- <TypeIdentifier>
- <HashCode>AIEVQjgBIxYITIARcAAACEc2CIAIlER1CBAQSQoEpCg=</HashCode>
- <FileName>OpenId\RelyingParty\OpenIdTextBox.cs</FileName>
- </TypeIdentifier>
- <Lollipop Position="0.2" />
- </Class>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase">
- <Position X="0.5" Y="0.5" Width="2.5" />
- <Compartments>
- <Compartment Name="Fields" Collapsed="true" />
- </Compartments>
- <NestedTypes>
- <Enum Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.LoginSiteNotification" Collapsed="true">
- <TypeIdentifier>
- <NewMemberFileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</NewMemberFileName>
- </TypeIdentifier>
- </Enum>
- <Enum Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.LoginPersistence" Collapsed="true">
- <TypeIdentifier>
- <NewMemberFileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</NewMemberFileName>
- </TypeIdentifier>
- </Enum>
- <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.DuplicateRequestedHostsComparer" Collapsed="true">
- <TypeIdentifier>
- <NewMemberFileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</NewMemberFileName>
- </TypeIdentifier>
- <Lollipop Position="0.2" />
- </Class>
- </NestedTypes>
- <TypeIdentifier>
- <HashCode>BA0AAsAAQCAwQAJAoFAWwADSAgE5EIEEEbAGSAwAgfI=</HashCode>
- <FileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</FileName>
- </TypeIdentifier>
- <Lollipop Position="0.2" />
- </Class>
- <Font Name="Segoe UI" Size="9" />
-</ClassDiagram> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
deleted file mode 100644
index 42bfbde..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
+++ /dev/null
@@ -1,242 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdAjaxRelyingParty.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Linq;
- using System.Net;
- using System.Net.Mime;
- using System.Text;
- using System.Web;
- using System.Web.Script.Serialization;
-
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.Extensions;
- using DotNetOpenAuth.OpenId.Extensions.UI;
-
- /// <summary>
- /// Provides the programmatic facilities to act as an AJAX-enabled OpenID relying party.
- /// </summary>
- public class OpenIdAjaxRelyingParty : OpenIdRelyingParty {
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdAjaxRelyingParty"/> class.
- /// </summary>
- public OpenIdAjaxRelyingParty() {
- Reporting.RecordFeatureUse(this);
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdAjaxRelyingParty"/> class.
- /// </summary>
- /// <param name="applicationStore">The application store. If <c>null</c>, the relying party will always operate in "dumb mode".</param>
- public OpenIdAjaxRelyingParty(IOpenIdApplicationStore applicationStore)
- : base(applicationStore) {
- Reporting.RecordFeatureUse(this);
- }
-
- /// <summary>
- /// Generates AJAX-ready authentication requests that can satisfy the requirements of some OpenID Identifier.
- /// </summary>
- /// <param name="userSuppliedIdentifier">The Identifier supplied by the user. This may be a URL, an XRI or i-name.</param>
- /// <param name="realm">The shorest URL that describes this relying party web site's address.
- /// For example, if your login page is found at https://www.example.com/login.aspx,
- /// your realm would typically be https://www.example.com/.</param>
- /// <param name="returnToUrl">The URL of the login page, or the page prepared to receive authentication
- /// responses from the OpenID Provider.</param>
- /// <returns>
- /// A sequence of authentication requests, any of which constitutes a valid identity assertion on the Claimed Identifier.
- /// Never null, but may be empty.
- /// </returns>
- /// <remarks>
- /// <para>Any individual generated request can satisfy the authentication.
- /// The generated requests are sorted in preferred order.
- /// Each request is generated as it is enumerated to. Associations are created only as
- /// <see cref="IAuthenticationRequest.RedirectingResponse"/> is called.</para>
- /// <para>No exception is thrown if no OpenID endpoints were discovered.
- /// An empty enumerable is returned instead.</para>
- /// </remarks>
- public override IEnumerable<IAuthenticationRequest> CreateRequests(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl) {
- var requests = base.CreateRequests(userSuppliedIdentifier, realm, returnToUrl);
-
- // Alter the requests so that have AJAX characteristics.
- // Some OPs may be listed multiple times (one with HTTPS and the other with HTTP, for example).
- // Since we're gathering OPs to try one after the other, just take the first choice of each OP
- // and don't try it multiple times.
- requests = requests.Distinct(DuplicateRequestedHostsComparer.Instance);
-
- // Configure each generated request.
- int reqIndex = 0;
- foreach (var req in requests) {
- // Inform ourselves in return_to that we're in a popup.
- req.SetUntrustedCallbackArgument(OpenIdRelyingPartyControlBase.UIPopupCallbackKey, "1");
-
- if (req.DiscoveryResult.IsExtensionSupported<UIRequest>()) {
- // Inform the OP that we'll be using a popup window consistent with the UI extension.
- req.AddExtension(new UIRequest());
-
- // Provide a hint for the client javascript about whether the OP supports the UI extension.
- // This is so the window can be made the correct size for the extension.
- // If the OP doesn't advertise support for the extension, the javascript will use
- // a bigger popup window.
- req.SetUntrustedCallbackArgument(OpenIdRelyingPartyControlBase.PopupUISupportedJSHint, "1");
- }
-
- req.SetUntrustedCallbackArgument("index", (reqIndex++).ToString(CultureInfo.InvariantCulture));
-
- // If the ReturnToUrl was explicitly set, we'll need to reset our first parameter
- if (OpenIdElement.Configuration.RelyingParty.PreserveUserSuppliedIdentifier) {
- if (string.IsNullOrEmpty(HttpUtility.ParseQueryString(req.ReturnToUrl.Query)[AuthenticationRequest.UserSuppliedIdentifierParameterName])) {
- req.SetUntrustedCallbackArgument(AuthenticationRequest.UserSuppliedIdentifierParameterName, userSuppliedIdentifier.OriginalString);
- }
- }
-
- // Our javascript needs to let the user know which endpoint responded. So we force it here.
- // This gives us the info even for 1.0 OPs and 2.0 setup_required responses.
- req.SetUntrustedCallbackArgument(OpenIdRelyingPartyAjaxControlBase.OPEndpointParameterName, req.Provider.Uri.AbsoluteUri);
- req.SetUntrustedCallbackArgument(OpenIdRelyingPartyAjaxControlBase.ClaimedIdParameterName, (string)req.ClaimedIdentifier ?? string.Empty);
-
- // Inform ourselves in return_to that we're in a popup or iframe.
- req.SetUntrustedCallbackArgument(OpenIdRelyingPartyAjaxControlBase.UIPopupCallbackKey, "1");
-
- // We append a # at the end so that if the OP happens to support it,
- // the OpenID response "query string" is appended after the hash rather than before, resulting in the
- // browser being super-speedy in closing the popup window since it doesn't try to pull a newer version
- // of the static resource down from the server merely because of a changed URL.
- // http://www.nabble.com/Re:-Defining-how-OpenID-should-behave-with-fragments-in-the-return_to-url-p22694227.html
- ////TODO:
-
- yield return req;
- }
- }
-
- /// <summary>
- /// Serializes discovery results on some <i>single</i> identifier on behalf of Javascript running on the browser.
- /// </summary>
- /// <param name="requests">The discovery results from just <i>one</i> identifier to serialize as a JSON response.</param>
- /// <returns>
- /// The JSON result to return to the user agent.
- /// </returns>
- /// <remarks>
- /// We prepare a JSON object with this interface:
- /// <code>
- /// class jsonResponse {
- /// string claimedIdentifier;
- /// Array requests; // never null
- /// string error; // null if no error
- /// }
- /// </code>
- /// Each element in the requests array looks like this:
- /// <code>
- /// class jsonAuthRequest {
- /// string endpoint; // URL to the OP endpoint
- /// string immediate; // URL to initiate an immediate request
- /// string setup; // URL to initiate a setup request.
- /// }
- /// </code>
- /// </remarks>
- public OutgoingWebResponse AsAjaxDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
- Contract.Requires<ArgumentNullException>(requests != null);
-
- var serializer = new JavaScriptSerializer();
- return new OutgoingWebResponse {
- Body = serializer.Serialize(this.AsJsonDiscoveryResult(requests)),
- };
- }
-
- /// <summary>
- /// Serializes discovery on a set of identifiers for preloading into an HTML page that carries
- /// an AJAX-aware OpenID control.
- /// </summary>
- /// <param name="requests">The discovery results to serialize as a JSON response.</param>
- /// <returns>
- /// The JSON result to return to the user agent.
- /// </returns>
- public string AsAjaxPreloadedDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
- Contract.Requires<ArgumentNullException>(requests != null);
-
- var serializer = new JavaScriptSerializer();
- string json = serializer.Serialize(this.AsJsonPreloadedDiscoveryResult(requests));
-
- string script = "window.dnoa_internal.loadPreloadedDiscoveryResults(" + json + ");";
- return script;
- }
-
- /// <summary>
- /// Converts a sequence of authentication requests to a JSON object for seeding an AJAX-enabled login page.
- /// </summary>
- /// <param name="requests">The discovery results from just <i>one</i> identifier to serialize as a JSON response.</param>
- /// <returns>A JSON object, not yet serialized.</returns>
- internal object AsJsonDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
- Contract.Requires<ArgumentNullException>(requests != null);
-
- requests = requests.CacheGeneratedResults();
-
- if (requests.Any()) {
- return new {
- claimedIdentifier = (string)requests.First().ClaimedIdentifier,
- requests = requests.Select(req => new {
- endpoint = req.Provider.Uri.AbsoluteUri,
- immediate = this.GetRedirectUrl(req, true),
- setup = this.GetRedirectUrl(req, false),
- }).ToArray()
- };
- } else {
- return new {
- requests = new object[0],
- error = OpenIdStrings.OpenIdEndpointNotFound,
- };
- }
- }
-
- /// <summary>
- /// Serializes discovery on a set of identifiers for preloading into an HTML page that carries
- /// an AJAX-aware OpenID control.
- /// </summary>
- /// <param name="requests">The discovery results to serialize as a JSON response.</param>
- /// <returns>
- /// A JSON object, not yet serialized to a string.
- /// </returns>
- private object AsJsonPreloadedDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
- Contract.Requires<ArgumentNullException>(requests != null);
-
- // We prepare a JSON object with this interface:
- // Array discoveryWrappers;
- // Where each element in the above array has this interface:
- // class discoveryWrapper {
- // string userSuppliedIdentifier;
- // jsonResponse discoveryResult; // contains result of call to SerializeDiscoveryAsJson(Identifier)
- // }
- var json = (from request in requests
- group request by request.DiscoveryResult.UserSuppliedIdentifier into requestsByIdentifier
- select new {
- userSuppliedIdentifier = (string)requestsByIdentifier.Key,
- discoveryResult = this.AsJsonDiscoveryResult(requestsByIdentifier),
- }).ToArray();
-
- return json;
- }
-
- /// <summary>
- /// Gets the full URL that carries an OpenID message, even if it exceeds the normal maximum size of a URL,
- /// for purposes of sending to an AJAX component running in the browser.
- /// </summary>
- /// <param name="request">The authentication request.</param>
- /// <param name="immediate"><c>true</c>to create a checkid_immediate request;
- /// <c>false</c> to create a checkid_setup request.</param>
- /// <returns>The absolute URL that carries the entire OpenID message.</returns>
- private Uri GetRedirectUrl(IAuthenticationRequest request, bool immediate) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- request.Mode = immediate ? AuthenticationRequestMode.Immediate : AuthenticationRequestMode.Setup;
- return request.RedirectingResponse.GetDirectUriRequest(this.Channel);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
deleted file mode 100644
index 8be097f..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
+++ /dev/null
@@ -1,877 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdAjaxTextBox.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedScriptResourceName, "text/javascript")]
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedStylesheetResourceName, "text/css")]
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedSpinnerResourceName, "image/gif")]
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName, "image/png")]
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginFailureResourceName, "image/png")]
-
-#pragma warning disable 0809 // marking inherited, unsupported properties as obsolete to discourage their use
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Drawing.Design;
- using System.Globalization;
- using System.Text;
- using System.Web.UI;
- using System.Web.UI.HtmlControls;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// An ASP.NET control that provides a minimal text box that is OpenID-aware and uses AJAX for
- /// a premium login experience.
- /// </summary>
- [DefaultProperty("Text"), ValidationProperty("Text")]
- [ToolboxData("<{0}:OpenIdAjaxTextBox runat=\"server\" />")]
- public class OpenIdAjaxTextBox : OpenIdRelyingPartyAjaxControlBase, IEditableTextControl, ITextControl, IPostBackDataHandler {
- /// <summary>
- /// The name of the manifest stream containing the OpenIdAjaxTextBox.js file.
- /// </summary>
- internal const string EmbeddedScriptResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdAjaxTextBox.js";
-
- /// <summary>
- /// The name of the manifest stream containing the OpenIdAjaxTextBox.css file.
- /// </summary>
- internal const string EmbeddedStylesheetResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdAjaxTextBox.css";
-
- /// <summary>
- /// The name of the manifest stream containing the spinner.gif file.
- /// </summary>
- internal const string EmbeddedSpinnerResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.spinner.gif";
-
- /// <summary>
- /// The name of the manifest stream containing the login_success.png file.
- /// </summary>
- internal const string EmbeddedLoginSuccessResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.login_success.png";
-
- /// <summary>
- /// The name of the manifest stream containing the login_failure.png file.
- /// </summary>
- internal const string EmbeddedLoginFailureResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.login_failure.png";
-
- /// <summary>
- /// The default value for the <see cref="DownloadYahooUILibrary"/> property.
- /// </summary>
- internal const bool DownloadYahooUILibraryDefault = true;
-
- /// <summary>
- /// The default value for the <see cref="Throttle"/> property.
- /// </summary>
- internal const int ThrottleDefault = 3;
-
- #region Property viewstate keys
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AutoPostBack"/> property.
- /// </summary>
- private const string AutoPostBackViewStateKey = "AutoPostback";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Text"/> property.
- /// </summary>
- private const string TextViewStateKey = "Text";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Columns"/> property.
- /// </summary>
- private const string ColumnsViewStateKey = "Columns";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="CssClass"/> property.
- /// </summary>
- private const string CssClassViewStateKey = "CssClass";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="OnClientAssertionReceived"/> property.
- /// </summary>
- private const string OnClientAssertionReceivedViewStateKey = "OnClientAssertionReceived";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticatedAsToolTip"/> property.
- /// </summary>
- private const string AuthenticatedAsToolTipViewStateKey = "AuthenticatedAsToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticationSucceededToolTip"/> property.
- /// </summary>
- private const string AuthenticationSucceededToolTipViewStateKey = "AuthenticationSucceededToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="LogOnInProgressMessage"/> property.
- /// </summary>
- private const string LogOnInProgressMessageViewStateKey = "BusyToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticationFailedToolTip"/> property.
- /// </summary>
- private const string AuthenticationFailedToolTipViewStateKey = "AuthenticationFailedToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="IdentifierRequiredMessage"/> property.
- /// </summary>
- private const string IdentifierRequiredMessageViewStateKey = "BusyToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="BusyToolTip"/> property.
- /// </summary>
- private const string BusyToolTipViewStateKey = "BusyToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="LogOnText"/> property.
- /// </summary>
- private const string LogOnTextViewStateKey = "LoginText";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Throttle"/> property.
- /// </summary>
- private const string ThrottleViewStateKey = "Throttle";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="LogOnToolTip"/> property.
- /// </summary>
- private const string LogOnToolTipViewStateKey = "LoginToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="LogOnPostBackToolTip"/> property.
- /// </summary>
- private const string LogOnPostBackToolTipViewStateKey = "LoginPostBackToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Name"/> property.
- /// </summary>
- private const string NameViewStateKey = "Name";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Timeout"/> property.
- /// </summary>
- private const string TimeoutViewStateKey = "Timeout";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="TabIndex"/> property.
- /// </summary>
- private const string TabIndexViewStateKey = "TabIndex";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Enabled"/> property.
- /// </summary>
- private const string EnabledViewStateKey = "Enabled";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="RetryToolTip"/> property.
- /// </summary>
- private const string RetryToolTipViewStateKey = "RetryToolTip";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="RetryText"/> property.
- /// </summary>
- private const string RetryTextViewStateKey = "RetryText";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="DownloadYahooUILibrary"/> property.
- /// </summary>
- private const string DownloadYahooUILibraryViewStateKey = "DownloadYahooUILibrary";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="ShowLogOnPostBackButton"/> property.
- /// </summary>
- private const string ShowLogOnPostBackButtonViewStateKey = "ShowLogOnPostBackButton";
-
- #endregion
-
- #region Property defaults
-
- /// <summary>
- /// The default value for the <see cref="AutoPostBack"/> property.
- /// </summary>
- private const bool AutoPostBackDefault = false;
-
- /// <summary>
- /// The default value for the <see cref="Columns"/> property.
- /// </summary>
- private const int ColumnsDefault = 40;
-
- /// <summary>
- /// The default value for the <see cref="CssClass"/> property.
- /// </summary>
- private const string CssClassDefault = "openid";
-
- /// <summary>
- /// The default value for the <see cref="LogOnInProgressMessage"/> property.
- /// </summary>
- private const string LogOnInProgressMessageDefault = "Please wait for login to complete.";
-
- /// <summary>
- /// The default value for the <see cref="AuthenticationSucceededToolTip"/> property.
- /// </summary>
- private const string AuthenticationSucceededToolTipDefault = "Authenticated by {0}.";
-
- /// <summary>
- /// The default value for the <see cref="AuthenticatedAsToolTip"/> property.
- /// </summary>
- private const string AuthenticatedAsToolTipDefault = "Authenticated as {0}.";
-
- /// <summary>
- /// The default value for the <see cref="AuthenticationFailedToolTip"/> property.
- /// </summary>
- private const string AuthenticationFailedToolTipDefault = "Authentication failed.";
-
- /// <summary>
- /// The default value for the <see cref="LogOnText"/> property.
- /// </summary>
- private const string LogOnTextDefault = "LOG IN";
-
- /// <summary>
- /// The default value for the <see cref="BusyToolTip"/> property.
- /// </summary>
- private const string BusyToolTipDefault = "Discovering/authenticating";
-
- /// <summary>
- /// The default value for the <see cref="IdentifierRequiredMessage"/> property.
- /// </summary>
- private const string IdentifierRequiredMessageDefault = "Please correct errors in OpenID identifier and allow login to complete before submitting.";
-
- /// <summary>
- /// The default value for the <see cref="Name"/> property.
- /// </summary>
- private const string NameDefault = "openid_identifier";
-
- /// <summary>
- /// Default value for <see cref="TabIndex"/> property.
- /// </summary>
- private const short TabIndexDefault = 0;
-
- /// <summary>
- /// The default value for the <see cref="RetryToolTip"/> property.
- /// </summary>
- private const string RetryToolTipDefault = "Retry a failed identifier discovery.";
-
- /// <summary>
- /// The default value for the <see cref="LogOnToolTip"/> property.
- /// </summary>
- private const string LogOnToolTipDefault = "Click here to log in using a pop-up window.";
-
- /// <summary>
- /// The default value for the <see cref="LogOnPostBackToolTip"/> property.
- /// </summary>
- private const string LogOnPostBackToolTipDefault = "Click here to log in immediately.";
-
- /// <summary>
- /// The default value for the <see cref="RetryText"/> property.
- /// </summary>
- private const string RetryTextDefault = "RETRY";
-
- /// <summary>
- /// The default value for the <see cref="ShowLogOnPostBackButton"/> property.
- /// </summary>
- private const bool ShowLogOnPostBackButtonDefault = false;
-
- #endregion
-
- /// <summary>
- /// The path where the YUI control library should be downloaded from for HTTP pages.
- /// </summary>
- private const string YuiLoaderHttp = "http://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js";
-
- /// <summary>
- /// The path where the YUI control library should be downloaded from for HTTPS pages.
- /// </summary>
- private const string YuiLoaderHttps = "https://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js";
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdAjaxTextBox"/> class.
- /// </summary>
- public OpenIdAjaxTextBox() {
- this.HookFormSubmit = true;
- }
-
- #region Events
-
- /// <summary>
- /// Fired when the content of the text changes between posts to the server.
- /// </summary>
- [Description("Occurs when the content of the text changes between posts to the server."), Category(BehaviorCategory)]
- public event EventHandler TextChanged;
-
- /// <summary>
- /// Gets or sets the client-side script that executes when an authentication
- /// assertion is received (but before it is verified).
- /// </summary>
- /// <remarks>
- /// <para>In the context of the executing javascript set in this property, the
- /// local variable <i>sender</i> is set to the openid_identifier input box
- /// that is executing this code.
- /// This variable has a getClaimedIdentifier() method that may be used to
- /// identify the user who is being authenticated.</para>
- /// <para>It is <b>very</b> important to note that when this code executes,
- /// the authentication has not been verified and may have been spoofed.
- /// No security-sensitive operations should take place in this javascript code.
- /// The authentication is verified on the server by the time the
- /// <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> server-side event fires.</para>
- /// </remarks>
- [Description("Gets or sets the client-side script that executes when an authentication assertion is received (but before it is verified).")]
- [Bindable(true), DefaultValue(""), Category(BehaviorCategory)]
- public string OnClientAssertionReceived {
- get { return this.ViewState[OnClientAssertionReceivedViewStateKey] as string; }
- set { this.ViewState[OnClientAssertionReceivedViewStateKey] = value; }
- }
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets or sets the value in the text field, completely unprocessed or normalized.
- /// </summary>
- [Bindable(true), DefaultValue(""), Category(AppearanceCategory)]
- [Description("The content of the text box.")]
- public string Text {
- get {
- return this.Identifier != null ? this.Identifier.OriginalString : (this.ViewState[TextViewStateKey] as string ?? string.Empty);
- }
-
- set {
- // Try to store it as a validated identifier,
- // but failing that at least store the text.
- Identifier id;
- if (Identifier.TryParse(value, out id)) {
- this.Identifier = id;
- } else {
- // Be sure to set the viewstate AFTER setting the Identifier,
- // since setting the Identifier clears the viewstate in OnIdentifierChanged.
- this.Identifier = null;
- this.ViewState[TextViewStateKey] = value;
- }
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether a postback is made to fire the
- /// <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event as soon as authentication has completed
- /// successfully.
- /// </summary>
- /// <value>
- /// <c>true</c> if a postback should be made automatically upon authentication;
- /// otherwise, <c>false</c> to delay the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/>
- /// event from firing at the server until a postback is made by some other control.
- /// </value>
- [Bindable(true), Category(BehaviorCategory), DefaultValue(AutoPostBackDefault)]
- [Description("Whether the LoggedIn event fires on the server as soon as authentication completes successfully.")]
- public bool AutoPostBack {
- get { return (bool)(this.ViewState[AutoPostBackViewStateKey] ?? AutoPostBackDefault); }
- set { this.ViewState[AutoPostBackViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the width of the text box in characters.
- /// </summary>
- [Bindable(true), Category(AppearanceCategory), DefaultValue(ColumnsDefault)]
- [Description("The width of the text box in characters.")]
- public int Columns {
- get {
- return (int)(this.ViewState[ColumnsViewStateKey] ?? ColumnsDefault);
- }
-
- set {
- Contract.Requires<ArgumentOutOfRangeException>(value >= 0);
- this.ViewState[ColumnsViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the CSS class assigned to the text box.
- /// </summary>
- [Bindable(true), DefaultValue(CssClassDefault), Category(AppearanceCategory)]
- [Description("The CSS class assigned to the text box.")]
- public string CssClass {
- get { return (string)this.ViewState[CssClassViewStateKey]; }
- set { this.ViewState[CssClassViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the tab index of the text box control. Use 0 to omit an explicit tabindex.
- /// </summary>
- [Bindable(true), Category(BehaviorCategory), DefaultValue(TabIndexDefault)]
- [Description("The tab index of the text box control. Use 0 to omit an explicit tabindex.")]
- public virtual short TabIndex {
- get { return (short)(this.ViewState[TabIndexViewStateKey] ?? TabIndexDefault); }
- set { this.ViewState[TabIndexViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether this <see cref="OpenIdTextBox"/> is enabled
- /// in the browser for editing and will respond to incoming OpenID messages.
- /// </summary>
- /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
- [Bindable(true), DefaultValue(true), Category(BehaviorCategory)]
- [Description("Whether the control is editable in the browser and will respond to OpenID messages.")]
- public bool Enabled {
- get { return (bool)(this.ViewState[EnabledViewStateKey] ?? true); }
- set { this.ViewState[EnabledViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the HTML name to assign to the text field.
- /// </summary>
- [Bindable(true), DefaultValue(NameDefault), Category("Misc")]
- [Description("The HTML name to assign to the text field.")]
- public string Name {
- get {
- return (string)(this.ViewState[NameViewStateKey] ?? NameDefault);
- }
-
- set {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));
- this.ViewState[NameViewStateKey] = value ?? string.Empty;
- }
- }
-
- /// <summary>
- /// Gets or sets the time duration for the AJAX control to wait for an OP to respond before reporting failure to the user.
- /// </summary>
- [Browsable(true), DefaultValue(typeof(TimeSpan), "00:00:08"), Category(BehaviorCategory)]
- [Description("The time duration for the AJAX control to wait for an OP to respond before reporting failure to the user.")]
- public TimeSpan Timeout {
- get {
- return (TimeSpan)(this.ViewState[TimeoutViewStateKey] ?? TimeoutDefault);
- }
-
- set {
- Contract.Requires<ArgumentOutOfRangeException>(value.TotalMilliseconds > 0);
- this.ViewState[TimeoutViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the maximum number of OpenID Providers to simultaneously try to authenticate with.
- /// </summary>
- [Browsable(true), DefaultValue(ThrottleDefault), Category(BehaviorCategory)]
- [Description("The maximum number of OpenID Providers to simultaneously try to authenticate with.")]
- public int Throttle {
- get {
- return (int)(this.ViewState[ThrottleViewStateKey] ?? ThrottleDefault);
- }
-
- set {
- Contract.Requires<ArgumentOutOfRangeException>(value > 0);
- this.ViewState[ThrottleViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.
- /// </summary>
- [Bindable(true), DefaultValue(LogOnTextDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.")]
- public string LogOnText {
- get {
- return (string)(this.ViewState[LogOnTextViewStateKey] ?? LogOnTextDefault);
- }
-
- set {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));
- this.ViewState[LogOnTextViewStateKey] = value ?? string.Empty;
- }
- }
-
- /// <summary>
- /// Gets or sets the rool tip text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.
- /// </summary>
- [Bindable(true), DefaultValue(LogOnToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.")]
- public string LogOnToolTip {
- get { return (string)(this.ViewState[LogOnToolTipViewStateKey] ?? LogOnToolTipDefault); }
- set { this.ViewState[LogOnToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the rool tip text that appears on the LOG IN button when clicking the button will result in an immediate postback.
- /// </summary>
- [Bindable(true), DefaultValue(LogOnPostBackToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears on the LOG IN button when clicking the button will result in an immediate postback.")]
- public string LogOnPostBackToolTip {
- get { return (string)(this.ViewState[LogOnPostBackToolTipViewStateKey] ?? LogOnPostBackToolTipDefault); }
- set { this.ViewState[LogOnPostBackToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the text that appears on the RETRY button in cases where authentication times out.
- /// </summary>
- [Bindable(true), DefaultValue(RetryTextDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The text that appears on the RETRY button in cases where authentication times out.")]
- public string RetryText {
- get {
- return (string)(this.ViewState[RetryTextViewStateKey] ?? RetryTextDefault);
- }
-
- set {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));
- this.ViewState[RetryTextViewStateKey] = value ?? string.Empty;
- }
- }
-
- /// <summary>
- /// Gets or sets the tool tip text that appears on the RETRY button in cases where authentication times out.
- /// </summary>
- [Bindable(true), DefaultValue(RetryToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears on the RETRY button in cases where authentication times out.")]
- public string RetryToolTip {
- get { return (string)(this.ViewState[RetryToolTipViewStateKey] ?? RetryToolTipDefault); }
- set { this.ViewState[RetryToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the tool tip text that appears when authentication succeeds.
- /// </summary>
- [Bindable(true), DefaultValue(AuthenticationSucceededToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears when authentication succeeds.")]
- public string AuthenticationSucceededToolTip {
- get { return (string)(this.ViewState[AuthenticationSucceededToolTipViewStateKey] ?? AuthenticationSucceededToolTipDefault); }
- set { this.ViewState[AuthenticationSucceededToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the tool tip text that appears on the green checkmark when authentication succeeds.
- /// </summary>
- [Bindable(true), DefaultValue(AuthenticatedAsToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears on the green checkmark when authentication succeeds.")]
- public string AuthenticatedAsToolTip {
- get { return (string)(this.ViewState[AuthenticatedAsToolTipViewStateKey] ?? AuthenticatedAsToolTipDefault); }
- set { this.ViewState[AuthenticatedAsToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the tool tip text that appears when authentication fails.
- /// </summary>
- [Bindable(true), DefaultValue(AuthenticationFailedToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears when authentication fails.")]
- public string AuthenticationFailedToolTip {
- get { return (string)(this.ViewState[AuthenticationFailedToolTipViewStateKey] ?? AuthenticationFailedToolTipDefault); }
- set { this.ViewState[AuthenticationFailedToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the tool tip text that appears over the text box when it is discovering and authenticating.
- /// </summary>
- [Bindable(true), DefaultValue(BusyToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears over the text box when it is discovering and authenticating.")]
- public string BusyToolTip {
- get { return (string)(this.ViewState[BusyToolTipViewStateKey] ?? BusyToolTipDefault); }
- set { this.ViewState[BusyToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the message that is displayed if a postback is about to occur before the identifier has been supplied.
- /// </summary>
- [Bindable(true), DefaultValue(IdentifierRequiredMessageDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The message that is displayed if a postback is about to occur before the identifier has been supplied.")]
- public string IdentifierRequiredMessage {
- get { return (string)(this.ViewState[IdentifierRequiredMessageViewStateKey] ?? IdentifierRequiredMessageDefault); }
- set { this.ViewState[IdentifierRequiredMessageViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets the message that is displayed if a postback is attempted while login is in process.
- /// </summary>
- [Bindable(true), DefaultValue(LogOnInProgressMessageDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The message that is displayed if a postback is attempted while login is in process.")]
- public string LogOnInProgressMessage {
- get { return (string)(this.ViewState[LogOnInProgressMessageViewStateKey] ?? LogOnInProgressMessageDefault); }
- set { this.ViewState[LogOnInProgressMessageViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether the Yahoo! User Interface Library (YUI)
- /// will be downloaded in order to provide a login split button.
- /// </summary>
- /// <value>
- /// <c>true</c> to use a split button; otherwise, <c>false</c> to use a standard HTML button
- /// or a split button by downloading the YUI library yourself on the hosting web page.
- /// </value>
- /// <remarks>
- /// The split button brings in about 180KB of YUI javascript dependencies.
- /// </remarks>
- [Bindable(true), DefaultValue(DownloadYahooUILibraryDefault), Category(BehaviorCategory)]
- [Description("Whether a split button will be used for the \"log in\" when the user provides an identifier that delegates to more than one Provider.")]
- public bool DownloadYahooUILibrary {
- get { return (bool)(this.ViewState[DownloadYahooUILibraryViewStateKey] ?? DownloadYahooUILibraryDefault); }
- set { this.ViewState[DownloadYahooUILibraryViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether the "Log in" button will be shown
- /// to initiate a postback containing the positive assertion.
- /// </summary>
- [Bindable(true), DefaultValue(ShowLogOnPostBackButtonDefault), Category(AppearanceCategory)]
- [Description("Whether the log in button will be shown to initiate a postback containing the positive assertion.")]
- public bool ShowLogOnPostBackButton {
- get { return (bool)(this.ViewState[ShowLogOnPostBackButtonViewStateKey] ?? ShowLogOnPostBackButtonDefault); }
- set { this.ViewState[ShowLogOnPostBackButtonViewStateKey] = value; }
- }
-
- #endregion
-
- /// <summary>
- /// Gets or sets a value indicating whether the ajax text box should hook the form's submit event for special behavior.
- /// </summary>
- internal bool HookFormSubmit { get; set; }
-
- /// <summary>
- /// Gets the name of the open id auth data form key.
- /// </summary>
- /// <value>
- /// A concatenation of <see cref="Name"/> and <c>"_openidAuthData"</c>.
- /// </value>
- protected override string OpenIdAuthDataFormKey {
- get { return this.Name + "_openidAuthData"; }
- }
-
- /// <summary>
- /// Gets the default value for the <see cref="Timeout"/> property.
- /// </summary>
- /// <value>8 seconds; or eternity if the debugger is attached.</value>
- private static TimeSpan TimeoutDefault {
- get {
- if (Debugger.IsAttached) {
- Logger.OpenId.Warn("Debugger is attached. Inflating default OpenIdAjaxTextbox.Timeout value to infinity.");
- return TimeSpan.MaxValue;
- } else {
- return TimeSpan.FromSeconds(8);
- }
- }
- }
-
- #region IPostBackDataHandler Members
-
- /// <summary>
- /// When implemented by a class, processes postback data for an ASP.NET server control.
- /// </summary>
- /// <param name="postDataKey">The key identifier for the control.</param>
- /// <param name="postCollection">The collection of all incoming name values.</param>
- /// <returns>
- /// true if the server control's state changes as a result of the postback; otherwise, false.
- /// </returns>
- bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection) {
- return this.LoadPostData(postDataKey, postCollection);
- }
-
- /// <summary>
- /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
- /// </summary>
- void IPostBackDataHandler.RaisePostDataChangedEvent() {
- this.RaisePostDataChangedEvent();
- }
-
- #endregion
-
- /// <summary>
- /// Raises the <see cref="E:Load"/> event.
- /// </summary>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- protected override void OnLoad(EventArgs e) {
- base.OnLoad(e);
-
- this.Page.RegisterRequiresPostBack(this);
- }
-
- /// <summary>
- /// Called when the <see cref="Identifier"/> property is changed.
- /// </summary>
- protected override void OnIdentifierChanged() {
- this.ViewState.Remove(TextViewStateKey);
- base.OnIdentifierChanged();
- }
-
- /// <summary>
- /// Prepares to render the control.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
-
- if (!this.Visible) {
- return;
- }
-
- if (this.DownloadYahooUILibrary) {
- // Although we'll add the <script> tag to download the YAHOO component,
- // a download failure may have occurred, so protect ourselves from a
- // script error using an if (YAHOO) block. But apparently at least in IE
- // that's not even enough, so we use a try/catch.
- string yuiLoadScript = @"try { if (YAHOO) {
- var loader = new YAHOO.util.YUILoader({
- require: ['button', 'menu'],
- loadOptional: false,
- combine: true
- });
-
- loader.insert();
-} } catch (e) { }";
- this.Page.ClientScript.RegisterClientScriptInclude("yuiloader", this.Page.Request.Url.IsTransportSecure() ? YuiLoaderHttps : YuiLoaderHttp);
- this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "requiredYuiComponents", yuiLoadScript, true);
- }
-
- var css = new HtmlLink();
- try {
- css.Href = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedStylesheetResourceName);
- css.Attributes["rel"] = "stylesheet";
- css.Attributes["type"] = "text/css";
- ErrorUtilities.VerifyHost(this.Page.Header != null, OpenIdStrings.HeadTagMustIncludeRunatServer);
- this.Page.Header.Controls.AddAt(0, css); // insert at top so host page can override
- } catch {
- css.Dispose();
- throw;
- }
-
- this.PrepareClientJavascript();
-
- // If an Identifier is preset on this control, preload discovery on that identifier,
- // but only if we're not already persisting an authentication result since that would
- // be redundant.
- if (this.Identifier != null && this.AuthenticationResponse == null) {
- this.PreloadDiscovery(this.Identifier);
- }
- }
-
- /// <summary>
- /// Renders the control.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
- protected override void Render(HtmlTextWriter writer) {
- base.Render(writer);
-
- // We surround the textbox with a span so that the .js file can inject a
- // login button within the text box with easy placement.
- string css = this.CssClass ?? string.Empty;
- css += " OpenIdAjaxTextBox";
- writer.AddAttribute(HtmlTextWriterAttribute.Class, css);
-
- writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "inline-block");
- writer.AddStyleAttribute(HtmlTextWriterStyle.Position, "relative");
- writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "16px");
- writer.RenderBeginTag(HtmlTextWriterTag.Span);
-
- writer.AddAttribute(HtmlTextWriterAttribute.Name, this.Name);
- writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
- writer.AddAttribute(HtmlTextWriterAttribute.Size, this.Columns.ToString(CultureInfo.InvariantCulture));
- if (!string.IsNullOrEmpty(this.Text)) {
- writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text, true);
- }
-
- if (this.TabIndex > 0) {
- writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, this.TabIndex.ToString(CultureInfo.InvariantCulture));
- }
- if (!this.Enabled) {
- writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "true");
- }
- if (!string.IsNullOrEmpty(this.CssClass)) {
- writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
- }
- writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, "18px");
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "solid");
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "1px");
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, "lightgray");
- writer.RenderBeginTag(HtmlTextWriterTag.Input);
- writer.RenderEndTag(); // </input>
- writer.RenderEndTag(); // </span>
- }
-
- /// <summary>
- /// When implemented by a class, processes postback data for an ASP.NET server control.
- /// </summary>
- /// <param name="postDataKey">The key identifier for the control.</param>
- /// <param name="postCollection">The collection of all incoming name values.</param>
- /// <returns>
- /// true if the server control's state changes as a result of the postback; otherwise, false.
- /// </returns>
- protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
- // If the control was temporarily hidden, it won't be in the Form data,
- // and we'll just implicitly keep the last Text setting.
- if (postCollection[this.Name] != null) {
- Identifier identifier = postCollection[this.Name].Length == 0 ? null : postCollection[this.Name];
- if (identifier != this.Identifier) {
- this.Identifier = identifier;
- return true;
- }
- }
-
- return false;
- }
-
- /// <summary>
- /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Predefined signature.")]
- protected virtual void RaisePostDataChangedEvent() {
- this.OnTextChanged();
- }
-
- /// <summary>
- /// Called on a postback when the Text property has changed.
- /// </summary>
- protected virtual void OnTextChanged() {
- EventHandler textChanged = this.TextChanged;
- if (textChanged != null) {
- textChanged(this, EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Assembles the javascript to send to the client and registers it with ASP.NET for transmission.
- /// </summary>
- private void PrepareClientJavascript() {
- // Import the .js file where most of the code is.
- this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdAjaxTextBox), EmbeddedScriptResourceName);
-
- // Call into the .js file with initialization information.
- StringBuilder startupScript = new StringBuilder();
- startupScript.AppendFormat("var box = document.getElementsByName('{0}')[0];{1}", this.Name, Environment.NewLine);
- startupScript.AppendFormat(
- CultureInfo.InvariantCulture,
- "initAjaxOpenId(box, {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, function() {{{20};}});{21}",
- MessagingUtilities.GetSafeJavascriptValue(this.Page.ClientScript.GetWebResourceUrl(this.GetType(), OpenIdTextBox.EmbeddedLogoResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedSpinnerResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedLoginSuccessResourceName)),
- MessagingUtilities.GetSafeJavascriptValue(this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedLoginFailureResourceName)),
- this.Throttle,
- this.Timeout.TotalMilliseconds,
- string.IsNullOrEmpty(this.OnClientAssertionReceived) ? "null" : "'" + this.OnClientAssertionReceived.Replace(@"\", @"\\").Replace("'", @"\'") + "'",
- MessagingUtilities.GetSafeJavascriptValue(this.LogOnText),
- MessagingUtilities.GetSafeJavascriptValue(this.LogOnToolTip),
- this.ShowLogOnPostBackButton ? "true" : "false",
- MessagingUtilities.GetSafeJavascriptValue(this.LogOnPostBackToolTip),
- MessagingUtilities.GetSafeJavascriptValue(this.RetryText),
- MessagingUtilities.GetSafeJavascriptValue(this.RetryToolTip),
- MessagingUtilities.GetSafeJavascriptValue(this.BusyToolTip),
- MessagingUtilities.GetSafeJavascriptValue(this.IdentifierRequiredMessage),
- MessagingUtilities.GetSafeJavascriptValue(this.LogOnInProgressMessage),
- MessagingUtilities.GetSafeJavascriptValue(this.AuthenticationSucceededToolTip),
- MessagingUtilities.GetSafeJavascriptValue(this.AuthenticatedAsToolTip),
- MessagingUtilities.GetSafeJavascriptValue(this.AuthenticationFailedToolTip),
- this.AutoPostBack ? "true" : "false",
- Page.ClientScript.GetPostBackEventReference(this, null),
- Environment.NewLine);
-
- ScriptManager.RegisterStartupScript(this, this.GetType(), "ajaxstartup", startupScript.ToString(), true);
- if (this.HookFormSubmit) {
- string htmlFormat = @"
-var openidbox = document.getElementsByName('{0}')[0];
-if (!openidbox.dnoi_internal.onSubmit()) {{ return false; }}
-";
- Page.ClientScript.RegisterOnSubmitStatement(
- this.GetType(),
- "loginvalidation",
- string.Format(CultureInfo.InvariantCulture, htmlFormat, this.Name));
- }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.css b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.css
deleted file mode 100644
index bed2e79..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.css
+++ /dev/null
@@ -1,49 +0,0 @@
-.OpenIdAjaxTextBox input
-{
- margin: 0px;
-}
-
-.OpenIdAjaxTextBox > span
-{
- position: absolute;
- right: -1px;
- top: 2px;
-}
-
-.OpenIdAjaxTextBox input[type=button]
-{
- visibility: hidden;
- position: absolute;
- padding: 0px;
- font-size: 8px;
- top: 1px;
- bottom: 1px;
- right: 2px;
-}
-
-.OpenIdAjaxTextBox .yui-split-button span button
-{
- font-size: 50%;
- font-size: 60%\9; /* the \9 is a hack that causes only IE7/8 to use this value. */
- line-height: 1;
- min-height: 1em;
- padding-top: 2px;
- padding-top: 3px\9;
- padding-bottom: 1px;
- padding-left: 5px;
- height: auto;
-}
-
-.OpenIdAjaxTextBox .yuimenuitem .yuimenuitemlabel
-{
- padding-left: 5px;
-}
-
-.OpenIdAjaxTextBox .yuimenuitem .yuimenuitemlabel img
-{
- border: 0;
- margin-right: 4px;
- vertical-align: middle;
- width: 16px;
- height: 16px;
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.js
deleted file mode 100644
index 9907b4e..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdAjaxTextBox.js
+++ /dev/null
@@ -1,644 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdAjaxTextBox.js" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// This file may be used and redistributed under the terms of the
-// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
-// </copyright>
-//-----------------------------------------------------------------------
-
-function initAjaxOpenId(box, openid_logo_url, spinner_url, success_icon_url, failure_icon_url,
- throttle, timeout, assertionReceivedCode,
- loginButtonText, loginButtonToolTip, showLoginPostBackButton, loginPostBackToolTip,
- retryButtonText, retryButtonToolTip, busyToolTip,
- identifierRequiredMessage, loginInProgressMessage,
- authenticatedByToolTip, authenticatedAsToolTip, authenticationFailedToolTip,
- autoPostback, postback) {
- box.dnoi_internal = {
- postback: postback
- };
- if (assertionReceivedCode) {
- box.dnoi_internal.onauthenticated = function(sender, e) { eval(assertionReceivedCode); };
- }
-
- box.dnoi_internal.originalBackground = box.style.background;
- box.timeout = timeout;
-
- box.dnoi_internal.authenticationIFrames = new window.dnoa_internal.FrameManager(throttle);
-
- box.dnoi_internal.constructButton = function(text, tooltip, onclick) {
- var button = document.createElement('input');
- button.textContent = text; // Mozilla
- button.value = text; // IE
- button.type = 'button';
- button.title = tooltip || '';
- button.onclick = onclick;
- box.parentNode.appendChild(button);
- return button;
- };
-
- box.dnoi_internal.constructSplitButton = function(text, tooltip, onclick, menu) {
- var htmlButton = box.dnoi_internal.constructButton(text, tooltip, onclick);
-
- if (!box.parentNode.className || box.parentNode.className.indexOf(' yui-skin-sam') < 0) {
- box.parentNode.className = (box.parentNode.className || '') + ' yui-skin-sam';
- }
-
- var splitButton = new YAHOO.widget.Button(htmlButton, {
- type: 'split',
- menu: menu
- });
-
- splitButton.on('click', onclick);
-
- return splitButton;
- };
-
- box.dnoi_internal.createLoginPostBackButton = function() {
- var postback = function() {
- var discoveryResult = window.dnoa_internal.discoveryResults[box.value];
- var respondingEndpoint = discoveryResult.findSuccessfulRequest();
- box.dnoi_internal.postback(discoveryResult, respondingEndpoint, respondingEndpoint.extensionResponses, { background: false });
- };
- var button = box.dnoi_internal.constructButton(loginButtonText, loginPostBackToolTip, postback);
- button.style.visibility = 'visible';
- button.destroy = function() {
- button.parentNode.removeChild(button);
- };
-
- return button;
- };
-
- box.dnoi_internal.createLoginButton = function(providers) {
- var onMenuItemClick = function(p_sType, p_aArgs, p_oItem) {
- var selectedProvider = (p_oItem && p_oItem.value) ? p_oItem.value : providers[0].value;
- selectedProvider.loginPopup();
- return false;
- };
-
- for (var i = 0; i < providers.length; i++) {
- providers[i].onclick = { fn: onMenuItemClick };
- }
-
- // We'll use the split button if we have more than one Provider, and the YUI library is available.
- if (providers.length > 1 && YAHOO && YAHOO.widget && YAHOO.widget.Button) {
- return box.dnoi_internal.constructSplitButton(loginButtonText, loginButtonToolTip, onMenuItemClick, providers);
- } else {
- var button = box.dnoi_internal.constructButton(loginButtonText, loginButtonToolTip, onMenuItemClick);
- button.style.visibility = 'visible';
- button.destroy = function() {
- button.parentNode.removeChild(button);
- };
- return button;
- }
- };
-
- box.dnoi_internal.constructIcon = function(imageUrl, tooltip, rightSide, visible, height) {
- var icon = document.createElement('img');
- icon.src = imageUrl;
- icon.title = tooltip || '';
- icon.originalTitle = icon.title;
- if (!visible) {
- icon.style.visibility = 'hidden';
- }
- icon.style.position = 'absolute';
- icon.style.top = "2px";
- icon.style.bottom = "2px"; // for FireFox (and IE7, I think)
- if (height) {
- icon.style.height = height; // for Chrome and IE8
- }
- if (rightSide) {
- icon.style.right = "2px";
- } else {
- icon.style.left = "2px";
- }
- box.parentNode.appendChild(icon);
- return icon;
- };
-
- box.dnoi_internal.prefetchImage = function(imageUrl) {
- var img = document.createElement('img');
- img.src = imageUrl;
- img.style.display = 'none';
- box.parentNode.appendChild(img);
- return img;
- };
-
- function findParentForm(element) {
- if (!element || element.nodeName == "FORM") {
- return element;
- }
-
- return findParentForm(element.parentNode);
- }
-
- box.parentForm = findParentForm(box);
-
- function findOrCreateHiddenField() {
- var name = box.name + '_openidAuthData';
- var existing = window.document.getElementsByName(name);
- if (existing && existing.length > 0) {
- return existing[0];
- }
-
- var hiddenField = document.createElement('input');
- hiddenField.setAttribute("name", name);
- hiddenField.setAttribute("type", "hidden");
- box.parentForm.appendChild(hiddenField);
- return hiddenField;
- }
-
- box.dnoi_internal.retryButton = box.dnoi_internal.constructButton(retryButtonText, retryButtonToolTip, function() {
- box.timeout += 5000; // give the retry attempt 5s longer than the last attempt
- box.dnoi_internal.performDiscovery();
- return false;
- });
- box.dnoi_internal.openid_logo = box.dnoi_internal.constructIcon(openid_logo_url, null, false, true);
- box.dnoi_internal.op_logo = box.dnoi_internal.constructIcon('', authenticatedByToolTip, false, false, "16px");
- box.dnoi_internal.op_logo.style.maxWidth = '16px';
- box.dnoi_internal.spinner = box.dnoi_internal.constructIcon(spinner_url, busyToolTip, true);
- box.dnoi_internal.success_icon = box.dnoi_internal.constructIcon(success_icon_url, authenticatedAsToolTip, true);
- box.dnoi_internal.failure_icon = box.dnoi_internal.constructIcon(failure_icon_url, authenticationFailedToolTip, true);
-
- box.dnoi_internal.dnoi_logo = box.dnoi_internal.openid_logo;
-
- box.dnoi_internal.setVisualCue = function(state, authenticatedBy, authenticatedAs, providers, errorMessage) {
- box.dnoi_internal.openid_logo.style.visibility = 'hidden';
- box.dnoi_internal.dnoi_logo.style.visibility = 'hidden';
- box.dnoi_internal.op_logo.style.visibility = 'hidden';
- box.dnoi_internal.openid_logo.title = box.dnoi_internal.openid_logo.originalTitle;
- box.dnoi_internal.spinner.style.visibility = 'hidden';
- box.dnoi_internal.success_icon.style.visibility = 'hidden';
- box.dnoi_internal.failure_icon.style.visibility = 'hidden';
- box.dnoi_internal.retryButton.style.visibility = 'hidden';
- if (box.dnoi_internal.loginButton) {
- box.dnoi_internal.loginButton.destroy();
- box.dnoi_internal.loginButton = null;
- }
- if (box.dnoi_internal.postbackLoginButton) {
- box.dnoi_internal.postbackLoginButton.destroy();
- box.dnoi_internal.postbackLoginButton = null;
- }
- box.title = '';
- box.dnoi_internal.state = state;
- var opLogo;
- if (state == "discovering") {
- box.dnoi_internal.dnoi_logo.style.visibility = 'visible';
- box.dnoi_internal.spinner.style.visibility = 'visible';
- box.dnoi_internal.claimedIdentifier = null;
- box.title = '';
- window.status = "Discovering OpenID Identifier '" + box.value + "'...";
- } else if (state == "authenticated") {
- opLogo = box.dnoi_internal.deriveOPFavIcon();
- if (opLogo) {
- box.dnoi_internal.op_logo.src = opLogo;
- box.dnoi_internal.op_logo.style.visibility = 'visible';
- box.dnoi_internal.op_logo.title = box.dnoi_internal.op_logo.originalTitle.replace('{0}', authenticatedBy.getHost());
- }
- //trace("OP icon size: " + box.dnoi_internal.op_logo.fileSize);
- // The filesize check just doesn't seem to work any more.
- if (!opLogo) {// || box.dnoi_internal.op_logo.fileSize == -1 /*IE*/ || box.dnoi_internal.op_logo.fileSize === undefined /* FF */) {
- trace('recovering from missing OP icon');
- box.dnoi_internal.op_logo.style.visibility = 'hidden';
- box.dnoi_internal.openid_logo.style.visibility = 'visible';
- box.dnoi_internal.openid_logo.title = box.dnoi_internal.op_logo.originalTitle.replace('{0}', authenticatedBy.getHost());
- }
- if (showLoginPostBackButton) {
- box.dnoi_internal.postbackLoginButton = box.dnoi_internal.createLoginPostBackButton();
- } else {
- box.dnoi_internal.success_icon.style.visibility = 'visible';
- box.dnoi_internal.success_icon.title = box.dnoi_internal.success_icon.originalTitle.replace('{0}', authenticatedAs);
- }
- box.title = box.dnoi_internal.claimedIdentifier;
- window.status = "Authenticated as " + authenticatedAs;
- } else if (state == "setup") {
- opLogo = box.dnoi_internal.deriveOPFavIcon();
- if (opLogo) {
- box.dnoi_internal.op_logo.src = opLogo;
- box.dnoi_internal.op_logo.style.visibility = 'visible';
- } else {
- box.dnoi_internal.openid_logo.style.visibility = 'visible';
- }
-
- box.dnoi_internal.loginButton = box.dnoi_internal.createLoginButton(providers);
-
- box.dnoi_internal.claimedIdentifier = null;
- window.status = "Authentication requires user interaction.";
- } else if (state == "failed") {
- box.dnoi_internal.openid_logo.style.visibility = 'visible';
- box.dnoi_internal.retryButton.style.visibility = 'visible';
- box.dnoi_internal.claimedIdentifier = null;
- window.status = authenticationFailedToolTip;
- box.title = authenticationFailedToolTip;
- } else if (state == "failednoretry") {
- box.dnoi_internal.failure_icon.title = errorMessage;
- box.dnoi_internal.failure_icon.style.visibility = 'visible';
- box.dnoi_internal.openid_logo.style.visibility = 'visible';
- box.dnoi_internal.claimedIdentifier = null;
- window.status = errorMessage;
- box.title = errorMessage;
- } else if (state == '' || !state) {
- box.dnoi_internal.openid_logo.style.visibility = 'visible';
- box.title = '';
- box.dnoi_internal.claimedIdentifier = null;
- window.status = null;
- } else {
- box.dnoi_internal.claimedIdentifier = null;
- trace('unrecognized state ' + state);
- }
-
- if (box.onStateChanged) {
- box.onStateChanged(state);
- }
- };
-
- box.dnoi_internal.isBusy = function() {
- var lastDiscovery = window.dnoa_internal.discoveryResults[box.lastDiscoveredIdentifier];
- return box.dnoi_internal.state == 'discovering' ||
- (lastDiscovery && lastDiscovery.busy());
- };
-
- box.dnoi_internal.canAttemptLogin = function() {
- if (box.value.length === 0) { return false; }
- if (!window.dnoa_internal.discoveryResults[box.value]) { return false; }
- if (box.dnoi_internal.state == 'failed') { return false; }
- return true;
- };
-
- box.dnoi_internal.getUserSuppliedIdentifierResults = function() {
- return window.dnoa_internal.discoveryResults[box.value];
- };
-
- box.dnoi_internal.isAuthenticated = function() {
- var results = box.dnoi_internal.getUserSuppliedIdentifierResults();
- return results && results.findSuccessfulRequest();
- };
-
- box.dnoi_internal.onSubmit = function() {
- var hiddenField = findOrCreateHiddenField();
- if (box.dnoi_internal.isAuthenticated()) {
- // stick the result in a hidden field so the RP can verify it
- hiddenField.setAttribute("value", window.dnoa_internal.discoveryResults[box.value].successAuthData);
- } else {
- hiddenField.setAttribute("value", '');
- if (box.dnoi_internal.isBusy()) {
- alert(loginInProgressMessage);
- } else {
- if (box.value.length > 0) {
- // submitPending will be true if we've already tried deferring submit for a login,
- // in which case we just want to display a box to the user.
- if (box.dnoi_internal.submitPending || !box.dnoi_internal.canAttemptLogin()) {
- alert(identifierRequiredMessage);
- } else {
- // The user hasn't clicked "Login" yet. We'll click login for him,
- // after leaving a note for ourselves to automatically click submit
- // when login is complete.
- box.dnoi_internal.submitPending = box.dnoi_internal.submitButtonJustClicked;
- if (box.dnoi_internal.submitPending === null) {
- box.dnoi_internal.submitPending = true;
- }
- box.dnoi_internal.loginButton.onclick();
- return false; // abort submit for now
- }
- } else {
- return true;
- }
- }
- return false;
- }
- return true;
- };
-
- /// <summary>
- /// Records which submit button caused this openid box to question whether it
- /// was ready to submit the user's identifier so that that button can be re-invoked
- /// automatically after authentication completes.
- /// </summary>
- box.dnoi_internal.setLastSubmitButtonClicked = function(evt) {
- var button;
- if (evt.target) {
- button = evt.target;
- } else {
- button = evt.srcElement;
- }
-
- box.dnoi_internal.submitButtonJustClicked = button;
- };
-
- // Find all submit buttons and hook their click events so that we can validate
- // whether we are ready for the user to postback.
- var inputs = document.getElementsByTagName('input');
- for (var i = 0; i < inputs.length; i++) {
- var el = inputs[i];
- if (el.type == 'submit') {
- if (el.attachEvent) {
- el.attachEvent("onclick", box.dnoi_internal.setLastSubmitButtonClicked);
- } else {
- el.addEventListener("click", box.dnoi_internal.setLastSubmitButtonClicked, true);
- }
- }
- }
-
- /// <summary>
- /// Returns the URL of the authenticating OP's logo so it can be displayed to the user.
- /// </summary>
- /// <param name="opUri">The OP Endpoint, if known.</param>
- box.dnoi_internal.deriveOPFavIcon = function(opUri) {
- if (!opUri) {
- var idresults = box.dnoi_internal.getUserSuppliedIdentifierResults();
- var response = idresults ? idresults.successAuthData : null;
- if (!response || response.length === 0) {
- trace('No favicon because no successAuthData.');
- return;
- }
- var authResult = new window.dnoa_internal.Uri(response);
- if (authResult.getQueryArgValue("openid.op_endpoint")) {
- opUri = new window.dnoa_internal.Uri(authResult.getQueryArgValue("openid.op_endpoint"));
- } else if (authResult.getQueryArgValue("dnoa.op_endpoint")) {
- opUri = new window.dnoa_internal.Uri(authResult.getQueryArgValue("dnoa.op_endpoint"));
- } else if (authResult.getQueryArgValue("openid.user_setup_url")) {
- opUri = new window.dnoa_internal.Uri(authResult.getQueryArgValue("openid.user_setup_url"));
- } else {
- return null;
- }
- }
- var favicon = opUri.getAuthority() + "/favicon.ico";
- trace('Guessing favicon location of: ' + favicon);
- return favicon;
- };
-
- /*****************************************
- * Event Handlers
- *****************************************/
-
- window.dnoa_internal.addDiscoveryStarted(function(identifier) {
- if (identifier == box.value) {
- box.dnoi_internal.setVisualCue('discovering');
- }
- }, box);
-
- window.dnoa_internal.addDiscoverySuccess(function(identifier, discoveryResult, state) {
- if (identifier == box.value && (box.dnoi_internal.state == 'discovering' || !box.dnoi_internal.state)) {
- // Start pre-fetching the OP favicons
- for (var i = 0; i < discoveryResult.length; i++) {
- var favicon = box.dnoi_internal.deriveOPFavIcon(discoveryResult[i].endpoint);
- if (favicon) {
- trace('Prefetching ' + favicon);
- box.dnoi_internal.prefetchImage(favicon);
- }
- }
- if (discoveryResult.length > 0) {
- discoveryResult.loginBackground(
- box.dnoi_internal.authenticationIFrames,
- null,
- null,
- null,
- box.timeout);
- } else {
- // discovery completed successfully -- it just didn't yield any service endpoints.
- box.dnoi_internal.setVisualCue('failednoretry', null, null, null, discoveryResult.error);
- if (discoveryResult.error) { box.title = discoveryResult.error; }
- }
- }
- }, box);
-
- window.dnoa_internal.addDiscoveryFailed(function(identifier, message) {
- if (identifier == box.value) {
- box.dnoi_internal.setVisualCue('failed');
- if (message) { box.title = message; }
- }
- }, box);
-
- window.dnoa_internal.addAuthStarted(function(discoveryResult, serviceEndpoint, state) {
- if (discoveryResult.userSuppliedIdentifier == box.value) {
- box.dnoi_internal.setVisualCue('discovering');
- }
- }, box);
-
- window.dnoa_internal.addAuthSuccess(function(discoveryResult, serviceEndpoint, extensionResponses, state) {
- if (discoveryResult.userSuppliedIdentifier == box.value) {
- // visual cue that auth was successful
- var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(discoveryResult.successAuthData);
- box.dnoi_internal.claimedIdentifier = parsedPositiveAssertion.claimedIdentifier;
-
- // If the OP doesn't support delegation, "correct" the identifier the user entered
- // so he realizes his identity didn't stick. But don't change out OP Identifiers.
- if (discoveryResult.claimedIdentifier && discoveryResult.claimedIdentifier != parsedPositiveAssertion.claimedIdentifier) {
- box.value = parsedPositiveAssertion.claimedIdentifier;
- box.lastDiscoveredIdentifier = box.value;
-
- // Also inject a fake discovery result for this new identifier to keep the UI from performing
- // discovery on the new identifier (the RP will perform the necessary verification server-side).
- if (!window.dnoa_internal.discoveryResults[box.value]) {
- // We must make sure that the only service endpoint from the earlier discovery that
- // is copied over is the one that sent the assertion just now. Deep clone, then strip
- // out the other SEPs.
- window.dnoa_internal.discoveryResults[box.value] = discoveryResult.cloneWithOneServiceEndpoint(serviceEndpoint);
- }
- }
- box.dnoi_internal.setVisualCue('authenticated', parsedPositiveAssertion.endpoint, parsedPositiveAssertion.claimedIdentifier);
- if (box.dnoi_internal.onauthenticated) {
- box.dnoi_internal.onauthenticated(box, extensionResponses);
- }
-
- if (showLoginPostBackButton && !state.background) {
- box.dnoi_internal.postback(discoveryResult, serviceEndpoint, extensionResponses, state);
- } else if (box.dnoi_internal.submitPending) {
- // We submit the form BEFORE resetting the submitPending so
- // the submit handler knows we've already tried this route.
- if (box.dnoi_internal.submitPending === true) {
- box.parentForm.submit();
- } else {
- box.dnoi_internal.submitPending.click();
- }
-
- box.dnoi_internal.submitPending = null;
- } else if (!state.deserialized && autoPostback) {
- // as long as this is a fresh auth response, postback to the server if configured to do so.
- box.dnoi_internal.postback(discoveryResult, serviceEndpoint, extensionResponses, state);
- }
- }
- }, box);
-
- window.dnoa_internal.addAuthFailed(function(discoveryResult, serviceEndpoint, state) {
- if (discoveryResult.userSuppliedIdentifier == box.value) {
- box.dnoi_internal.submitPending = null;
- if (!serviceEndpoint || !state.background) { // if the last service endpoint just turned the user down
- box.dnoi_internal.displayLoginButton(discoveryResult);
- }
- }
- }, box);
-
- window.dnoa_internal.addAuthCleared(function(discoveryResult, serviceEndpoint) {
- if (discoveryResult.userSuppliedIdentifier == box.value) {
- if (!discoveryResult.findSuccessfulRequest()) {
- // attempt to renew the positive assertion.
- discoveryResult.loginBackground(
- box.dnoi_internal.authenticationIFrames,
- null,
- null,
- null,
- box.timeout);
- }
- }
- }, box);
-
- /*****************************************
- * Flow
- *****************************************/
-
- box.dnoi_internal.displayLoginButton = function(discoveryResult) {
- trace('No asynchronous authentication attempt is in progress. Display setup view.');
- var providers = [];
- for (var i = 0; i < discoveryResult.length; i++) {
- var favicon = box.dnoi_internal.deriveOPFavIcon(discoveryResult[i].endpoint);
- var img = '<img src="' + favicon + '" />';
- providers.push({ text: img + discoveryResult[i].host, value: discoveryResult[i] });
- }
-
- // visual cue that auth failed
- box.dnoi_internal.setVisualCue('setup', null, null, providers);
- };
-
- /// <summary>Called to initiate discovery on some identifier.</summary>
- box.dnoi_internal.performDiscovery = function() {
- box.dnoi_internal.authenticationIFrames.closeFrames();
- box.lastDiscoveredIdentifier = box.value;
- var openid = new window.OpenIdIdentifier(box.value);
- openid.discover();
- };
-
- box.onblur = function(event) {
- if (box.lastDiscoveredIdentifier != box.value || !box.dnoi_internal.state) {
- if (box.value.length > 0) {
- box.dnoi_internal.resetAndDiscover();
- } else {
- box.dnoi_internal.setVisualCue();
- }
- }
-
- return true;
- };
-
- //{
- var rate = NaN;
- var lastValue = box.value;
- var keyPresses = 0;
- var startTime = null;
- var lastKeyPress = null;
- var discoveryTimer;
-
- function cancelTimer() {
- if (discoveryTimer) {
- trace('canceling timer', 'gray');
- clearTimeout(discoveryTimer);
- discoveryTimer = null;
- }
- }
-
- function identifierSanityCheck(id) {
- return id.match("^[=@+$!(].+|.*?\\..*[^\\.]|\\w+://.+");
- }
-
- function discover() {
- cancelTimer();
- trace('typist discovery candidate', 'gray');
- if (identifierSanityCheck(box.value)) {
- trace('typist discovery begun', 'gray');
- box.dnoi_internal.performDiscovery();
- } else {
- trace('typist discovery canceled due to incomplete identifier.', 'gray');
- }
- }
-
- function reset() {
- keyPresses = 0;
- startTime = null;
- rate = NaN;
- trace('resetting state', 'gray');
- }
-
- box.dnoi_internal.resetAndDiscover = function() {
- reset();
- discover();
- };
-
- box.onkeyup = function(e) {
- e = e || window.event; // for IE
-
- if (new Date() - lastKeyPress > 3000) {
- // the user seems to have altogether stopped typing,
- // so reset our typist speed detector.
- reset();
- }
- lastKeyPress = new Date();
-
- var newValue = box.value;
- if (e.keyCode == 13) {
- if (box.dnoi_internal.state === 'setup') {
- box.dnoi_internal.loginButton.click();
- } else if (box.dnoi_internal.postbackLoginButton) {
- box.dnoi_internal.postbackLoginButton.click();
- } else {
- discover();
- }
- } else {
- if (lastValue != newValue && newValue != box.lastDiscoveredIdentifier) {
- box.dnoi_internal.setVisualCue();
- if (newValue.length === 0) {
- reset();
- } else if (Math.abs((lastValue || '').length - newValue.length) > 1) {
- // One key press is responsible for multiple character changes.
- // The user may have pasted in his identifier in which case
- // we want to begin discovery immediately.
- trace(newValue + ': paste detected (old value ' + lastValue + ')', 'gray');
- discover();
- } else {
- keyPresses++;
- var timeout = 3000; // timeout to use if we don't have enough keying to figure out type rate
- if (startTime === null) {
- startTime = new Date();
- } else if (keyPresses > 1) {
- cancelTimer();
- rate = (new Date() - startTime) / keyPresses;
- var minTimeout = 300;
- var maxTimeout = 3000;
- var typistFactor = 5;
- timeout = Math.max(minTimeout, Math.min(rate * typistFactor, maxTimeout));
- }
-
- trace(newValue + ': setting timer for ' + timeout, 'gray');
- discoveryTimer = setTimeout(discover, timeout);
- }
- }
- }
-
- trace(newValue + ': updating lastValue', 'gray');
- lastValue = newValue;
-
- return true;
- };
- //}
-
- box.getClaimedIdentifier = function() { return box.dnoi_internal.claimedIdentifier; };
-
- // If an identifier is preset on the box, perform discovery on it, but only
- // if there isn't a prior authentication that we're about to deserialize.
- if (box.value.length > 0 && findOrCreateHiddenField().value.length === 0) {
- trace('jumpstarting discovery on ' + box.value + ' because it was preset.');
- box.dnoi_internal.performDiscovery();
- }
-
- // Restore a previously achieved state (from pre-postback) if it is given.
- window.dnoa_internal.deserializePreviousAuthentication(findOrCreateHiddenField().value);
-
- // public methods
- box.setValue = function(value) {
- box.value = value;
- if (box.value) {
- box.dnoi_internal.performDiscovery();
- }
- };
-
- // public events
- // box.onStateChanged(state)
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdButton.cs
deleted file mode 100644
index 6243917..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdButton.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdButton.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-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;
-
- /// <summary>
- /// An ASP.NET control that renders a button that initiates an
- /// authentication when clicked.
- /// </summary>
- public class OpenIdButton : OpenIdRelyingPartyControlBase {
- #region Property defaults
-
- /// <summary>
- /// The default value for the <see cref="Text"/> property.
- /// </summary>
- private const string TextDefault = "Log in with [Provider]!";
-
- /// <summary>
- /// The default value for the <see cref="PrecreateRequest"/> property.
- /// </summary>
- private const bool PrecreateRequestDefault = false;
-
- #endregion
-
- #region View state keys
-
- /// <summary>
- /// The key under which the value for the <see cref="Text"/> property will be stored.
- /// </summary>
- private const string TextViewStateKey = "Text";
-
- /// <summary>
- /// The key under which the value for the <see cref="ImageUrl"/> property will be stored.
- /// </summary>
- private const string ImageUrlViewStateKey = "ImageUrl";
-
- /// <summary>
- /// The key under which the value for the <see cref="PrecreateRequest"/> property will be stored.
- /// </summary>
- private const string PrecreateRequestViewStateKey = "PrecreateRequest";
-
- #endregion
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdButton"/> class.
- /// </summary>
- public OpenIdButton() {
- }
-
- /// <summary>
- /// Gets or sets the text to display for the link.
- /// </summary>
- [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; }
- }
-
- /// <summary>
- /// Gets or sets the image to display.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to pre-discover the identifier so
- /// the user agent has an immediate redirect.
- /// </summary>
- [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; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating when to use a popup window to complete the login experience.
- /// </summary>
- /// <value>The default value is <see cref="PopupBehavior.Never"/>.</value>
- [Bindable(false), Browsable(false)]
- public override PopupBehavior Popup {
- get { return base.Popup; }
- set { ErrorUtilities.VerifySupported(value == base.Popup, OpenIdStrings.PropertyValueNotSupported); }
- }
-
- /// <summary>
- /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
- /// </summary>
- /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
- 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);
- }
- }
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
-
- if (!this.DesignMode) {
- ErrorUtilities.VerifyOperation(this.Identifier != null, OpenIdStrings.NoIdentifierSet);
- }
- }
-
- /// <summary>
- /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
- [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();
- }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdEventArgs.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdEventArgs.cs
deleted file mode 100644
index 5668cf4..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdEventArgs.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdEventArgs.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// The event details passed to event handlers.
- /// </summary>
- public class OpenIdEventArgs : EventArgs {
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdEventArgs"/> class
- /// with minimal information of an incomplete or failed authentication attempt.
- /// </summary>
- /// <param name="request">The outgoing authentication request.</param>
- internal OpenIdEventArgs(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- this.Request = request;
- this.ClaimedIdentifier = request.ClaimedIdentifier;
- this.IsDirectedIdentity = request.IsDirectedIdentity;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdEventArgs"/> class
- /// with information on a completed authentication attempt
- /// (whether that attempt was successful or not).
- /// </summary>
- /// <param name="response">The incoming authentication response.</param>
- internal OpenIdEventArgs(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
-
- this.Response = response;
- this.ClaimedIdentifier = response.ClaimedIdentifier;
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to cancel
- /// the OpenID authentication and/or login process.
- /// </summary>
- public bool Cancel { get; set; }
-
- /// <summary>
- /// Gets the Identifier the user is claiming to own. Or null if the user
- /// is using Directed Identity.
- /// </summary>
- public Identifier ClaimedIdentifier { get; private set; }
-
- /// <summary>
- /// Gets a value indicating whether the user has selected to let his Provider determine
- /// the ClaimedIdentifier to use as part of successful authentication.
- /// </summary>
- public bool IsDirectedIdentity { get; private set; }
-
- /// <summary>
- /// Gets the details of the OpenID authentication request,
- /// and allows for adding extensions.
- /// </summary>
- public IAuthenticationRequest Request { get; private set; }
-
- /// <summary>
- /// Gets the details of the OpenID authentication response.
- /// </summary>
- public IAuthenticationResponse Response { get; private set; }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdLogin.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdLogin.cs
deleted file mode 100644
index eccdacf..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdLogin.cs
+++ /dev/null
@@ -1,1001 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdLogin.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.ComponentModel;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Linq;
- using System.Web.UI;
- using System.Web.UI.HtmlControls;
- using System.Web.UI.WebControls;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// An ASP.NET control providing a complete OpenID login experience.
- /// </summary>
- [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
-
- /// <summary>
- /// The default value for the <see cref="RegisterToolTip"/> property.
- /// </summary>
- private const string RegisterToolTipDefault = "Sign up free for an OpenID with MyOpenID now.";
-
- /// <summary>
- /// The default value for the <see cref="RememberMeText"/> property.
- /// </summary>
- private const string RememberMeTextDefault = "Remember me";
-
- /// <summary>
- /// The default value for the <see cref="ButtonText"/> property.
- /// </summary>
- private const string ButtonTextDefault = "Login »";
-
- /// <summary>
- /// The default value for the <see cref="CanceledText"/> property.
- /// </summary>
- private const string CanceledTextDefault = "Login canceled.";
-
- /// <summary>
- /// The default value for the <see cref="FailedMessageText"/> property.
- /// </summary>
- private const string FailedMessageTextDefault = "Login failed: {0}";
-
- /// <summary>
- /// The default value for the <see cref="ExamplePrefix"/> property.
- /// </summary>
- private const string ExamplePrefixDefault = "Example:";
-
- /// <summary>
- /// The default value for the <see cref="ExampleUrl"/> property.
- /// </summary>
- private const string ExampleUrlDefault = "http://your.name.myopenid.com";
-
- /// <summary>
- /// The default value for the <see cref="LabelText"/> property.
- /// </summary>
- private const string LabelTextDefault = "OpenID Login:";
-
- /// <summary>
- /// The default value for the <see cref="RequiredText"/> property.
- /// </summary>
- private const string RequiredTextDefault = "Provide an OpenID first.";
-
- /// <summary>
- /// The default value for the <see cref="UriFormatText"/> property.
- /// </summary>
- private const string UriFormatTextDefault = "Invalid OpenID URL.";
-
- /// <summary>
- /// The default value for the <see cref="RegisterText"/> property.
- /// </summary>
- private const string RegisterTextDefault = "register";
-
- /// <summary>
- /// The default value for the <see cref="RegisterUrl"/> property.
- /// </summary>
- private const string RegisterUrlDefault = "https://www.myopenid.com/signup";
-
- /// <summary>
- /// The default value for the <see cref="ButtonToolTip"/> property.
- /// </summary>
- private const string ButtonToolTipDefault = "Account login";
-
- /// <summary>
- /// The default value for the <see cref="ValidationGroup"/> property.
- /// </summary>
- private const string ValidationGroupDefault = "OpenIdLogin";
-
- /// <summary>
- /// The default value for the <see cref="RegisterVisible"/> property.
- /// </summary>
- private const bool RegisterVisibleDefault = true;
-
- /// <summary>
- /// The default value for the <see cref="RememberMeVisible"/> property.
- /// </summary>
- private const bool RememberMeVisibleDefault = false;
-
- /// <summary>
- /// The default value for the <see cref="RememberMe"/> property.
- /// </summary>
- private const bool RememberMeDefault = false;
-
- /// <summary>
- /// The default value for the <see cref="UriValidatorEnabled"/> property.
- /// </summary>
- private const bool UriValidatorEnabledDefault = true;
-
- #endregion
-
- #region Property viewstate keys
-
- /// <summary>
- /// The viewstate key to use for the <see cref="FailedMessageText"/> property.
- /// </summary>
- private const string FailedMessageTextViewStateKey = "FailedMessageText";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="CanceledText"/> property.
- /// </summary>
- private const string CanceledTextViewStateKey = "CanceledText";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="IdSelectorIdentifier"/> property.
- /// </summary>
- private const string IdSelectorIdentifierViewStateKey = "IdSelectorIdentifier";
-
- #endregion
-
- /// <summary>
- /// The HTML to append to the <see cref="RequiredText"/> property value when rendering.
- /// </summary>
- private const string RequiredTextSuffix = "<br/>";
-
- /// <summary>
- /// The number to add to <see cref="TabIndex"/> to get the tab index of the textbox control.
- /// </summary>
- private const short TextBoxTabIndexOffset = 0;
-
- /// <summary>
- /// The number to add to <see cref="TabIndex"/> to get the tab index of the login button control.
- /// </summary>
- private const short LoginButtonTabIndexOffset = 1;
-
- /// <summary>
- /// The number to add to <see cref="TabIndex"/> to get the tab index of the remember me checkbox control.
- /// </summary>
- private const short RememberMeTabIndexOffset = 2;
-
- /// <summary>
- /// The number to add to <see cref="TabIndex"/> to get the tab index of the register link control.
- /// </summary>
- private const short RegisterTabIndexOffset = 3;
-
- #region Controls
-
- /// <summary>
- /// The control into which all other controls are added.
- /// </summary>
- private Panel panel;
-
- /// <summary>
- /// The Login button.
- /// </summary>
- private Button loginButton;
-
- /// <summary>
- /// The label that presents the text box.
- /// </summary>
- private HtmlGenericControl label;
-
- /// <summary>
- /// The validator that flags an empty text box.
- /// </summary>
- private RequiredFieldValidator requiredValidator;
-
- /// <summary>
- /// The validator that flags invalid formats of OpenID identifiers.
- /// </summary>
- private CustomValidator identifierFormatValidator;
-
- /// <summary>
- /// The label that precedes an example OpenID identifier.
- /// </summary>
- private Label examplePrefixLabel;
-
- /// <summary>
- /// The label that contains the example OpenID identifier.
- /// </summary>
- private Label exampleUrlLabel;
-
- /// <summary>
- /// A link to allow the user to create an account with a popular OpenID Provider.
- /// </summary>
- private HyperLink registerLink;
-
- /// <summary>
- /// The Remember Me checkbox.
- /// </summary>
- private CheckBox rememberMeCheckBox;
-
- /// <summary>
- /// The javascript snippet that activates the ID Selector javascript control.
- /// </summary>
- private Literal idselectorJavascript;
-
- /// <summary>
- /// The label that will display login failure messages.
- /// </summary>
- private Label errorLabel;
-
- #endregion
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdLogin"/> class.
- /// </summary>
- public OpenIdLogin() {
- }
-
- #region Events
-
- /// <summary>
- /// Fired when the Remember Me checkbox is changed by the user.
- /// </summary>
- [Description("Fires when the Remember Me checkbox is changed by the user.")]
- public event EventHandler RememberMeChanged;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets a <see cref="T:System.Web.UI.ControlCollection"/> object that represents the child controls for a specified server control in the UI hierarchy.
- /// </summary>
- /// <returns>
- /// The collection of child controls for the specified server control.
- /// </returns>
- public override ControlCollection Controls {
- get {
- this.EnsureChildControls();
- return base.Controls;
- }
- }
-
- /// <summary>
- /// Gets or sets the caption that appears before the text box.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the text that introduces the example OpenID url.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the example OpenID Identifier to display to the user.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the text to display if the user attempts to login
- /// without providing an Identifier.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the text to display if the user provides an invalid form for an Identifier.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to perform Identifier
- /// format validation prior to an authentication attempt.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the text of the link users can click on to obtain an OpenID.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the URL to link users to who click the link to obtain a new OpenID.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the text of the tooltip to display when the user hovers
- /// over the link to obtain a new OpenID.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to display a link to
- /// allow users to easily obtain a new OpenID.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the text that appears on the button that initiates login.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the text of the "Remember Me" checkbox.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the message display in the event of a failed
- /// authentication. {0} may be used to insert the actual error.
- /// </summary>
- [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; }
- }
-
- /// <summary>
- /// Gets or sets the text to display in the event of an authentication canceled at the Provider.
- /// </summary>
- [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; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether the "Remember Me" checkbox should be displayed.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether a successful authentication should result in a persistent
- /// cookie being saved to the browser.
- /// </summary>
- [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; }
- }
-
- /// <summary>
- /// Gets or sets the starting tab index to distribute across the controls.
- /// </summary>
- [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);
- }
- }
- }
-
- /// <summary>
- /// Gets or sets the tooltip to display when the user hovers over the login button.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the validation group that the login button and text box validator belong to.
- /// </summary>
- [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;
- }
- }
-
- /// <summary>
- /// Gets or sets the unique hash string that ends your idselector.com account.
- /// </summary>
- [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
-
- /// <summary>
- /// Gets or sets a value indicating whether a FormsAuthentication
- /// cookie should persist across user sessions.
- /// </summary>
- [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
-
- /// <summary>
- /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object and stores tracing information about the control if tracing is enabled.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HTmlTextWriter"/> object that receives the control content.</param>
- public override void RenderControl(HtmlTextWriter writer) {
- this.RenderChildren(writer);
- }
-
- /// <summary>
- /// Creates the child controls.
- /// </summary>
- protected override void CreateChildControls() {
- this.InitializeControls();
-
- // Just add the panel we've assembled earlier.
- base.Controls.Add(this.panel);
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
-
- this.EnsureChildControls();
- }
-
- /// <summary>
- /// Initializes the child controls.
- /// </summary>
- [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);
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnInit(EventArgs e) {
- this.SetChildControlReferenceIds();
-
- base.OnInit(e);
- }
-
- /// <summary>
- /// Renders the child controls.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the rendered content.</param>
- [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 = @"<script type='text/javascript'><!--
-idselector_input_id = '" + this.ClientID + @"';
-// --></script>
-<script type='text/javascript' id='__openidselector' src='https://www.idselector.com/selector/" + this.IdSelectorIdentifier + @"' charset='utf-8'></script>";
- } else {
- this.idselectorJavascript.Visible = false;
- }
- }
-
- base.RenderChildren(writer);
- }
-
- /// <summary>
- /// Adds failure handling to display an error message to the user.
- /// </summary>
- /// <param name="response">The response.</param>
- 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;
- }
- }
-
- /// <summary>
- /// Adds authentication cancellation behavior to display a message to the user.
- /// </summary>
- /// <param name="response">The response.</param>
- protected override void OnCanceled(IAuthenticationResponse response) {
- base.OnCanceled(response);
-
- if (!string.IsNullOrEmpty(this.CanceledText)) {
- this.errorLabel.Text = this.CanceledText;
- this.errorLabel.Visible = true;
- }
- }
-
- /// <summary>
- /// Fires the <see cref="RememberMeChanged"/> event.
- /// </summary>
- protected virtual void OnRememberMeChanged() {
- EventHandler rememberMeChanged = this.RememberMeChanged;
- if (rememberMeChanged != null) {
- rememberMeChanged(this, new EventArgs());
- }
- }
-
- /// <summary>
- /// Handles the ServerValidate event of the identifierFormatValidator control.
- /// </summary>
- /// <param name="source">The source of the event.</param>
- /// <param name="args">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs"/> instance containing the event data.</param>
- private void IdentifierFormatValidator_ServerValidate(object source, ServerValidateEventArgs args) {
- args.IsValid = Identifier.IsValid(args.Value);
- }
-
- /// <summary>
- /// Handles the CheckedChanged event of the rememberMeCheckBox control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- private void RememberMeCheckBox_CheckedChanged(object sender, EventArgs e) {
- this.RememberMe = this.rememberMeCheckBox.Checked;
- this.OnRememberMeChanged();
- }
-
- /// <summary>
- /// Handles the Click event of the loginButton control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- private void LoginButton_Click(object sender, EventArgs e) {
- if (!this.Page.IsValid) {
- return;
- }
-
- IAuthenticationRequest request = this.CreateRequests().FirstOrDefault();
- if (request != null) {
- this.LogOn(request);
- } else {
- if (!string.IsNullOrEmpty(this.FailedMessageText)) {
- this.errorLabel.Text = string.Format(CultureInfo.CurrentCulture, this.FailedMessageText, OpenIdStrings.OpenIdEndpointNotFound);
- this.errorLabel.Visible = true;
- }
- }
- }
-
- /// <summary>
- /// Renders the control inner.
- /// </summary>
- /// <param name="writer">The writer.</param>
- private void RenderControlInner(HtmlTextWriter writer) {
- base.RenderControl(writer);
- }
-
- /// <summary>
- /// Sets child control properties that depend on this control's ID.
- /// </summary>
- 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";
- }
-
- /// <summary>
- /// A control that acts as a placeholder to indicate where
- /// the OpenIdLogin control should render its OpenIdTextBox parent.
- /// </summary>
- private class InPlaceControl : PlaceHolder {
- /// <summary>
- /// The owning control to render.
- /// </summary>
- private OpenIdLogin renderControl;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="InPlaceControl"/> class.
- /// </summary>
- /// <param name="renderControl">The render control.</param>
- internal InPlaceControl(OpenIdLogin renderControl) {
- this.renderControl = renderControl;
- }
-
- /// <summary>
- /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
- protected override void Render(HtmlTextWriter writer) {
- this.renderControl.RenderControlInner(writer);
- }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdMobileTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdMobileTextBox.cs
deleted file mode 100644
index fc80b32..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdMobileTextBox.cs
+++ /dev/null
@@ -1,778 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdMobileTextBox.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdMobileTextBox.EmbeddedLogoResourceName, "image/gif")]
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Text.RegularExpressions;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.MobileControls;
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
-
- /// <summary>
- /// An ASP.NET control for mobile devices that provides a minimal text box that is OpenID-aware.
- /// </summary>
- [DefaultProperty("Text"), ValidationProperty("Text")]
- [ToolboxData("<{0}:OpenIdMobileTextBox runat=\"server\" />")]
- public class OpenIdMobileTextBox : TextBox {
- /// <summary>
- /// The name of the manifest stream containing the
- /// OpenID logo that is placed inside the text box.
- /// </summary>
- internal const string EmbeddedLogoResourceName = OpenIdTextBox.EmbeddedLogoResourceName;
-
- /// <summary>
- /// Default value of <see cref="UsePersistentCookie"/>.
- /// </summary>
- protected const bool UsePersistentCookieDefault = false;
-
- #region Property category constants
-
- /// <summary>
- /// The "Appearance" category for properties.
- /// </summary>
- private const string AppearanceCategory = "Appearance";
-
- /// <summary>
- /// The "Simple Registration" category for properties.
- /// </summary>
- private const string ProfileCategory = "Simple Registration";
-
- /// <summary>
- /// The "Behavior" category for properties.
- /// </summary>
- private const string BehaviorCategory = "Behavior";
-
- #endregion
-
- #region Property viewstate keys
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestEmail"/> property.
- /// </summary>
- private const string RequestEmailViewStateKey = "RequestEmail";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestNickname"/> property.
- /// </summary>
- private const string RequestNicknameViewStateKey = "RequestNickname";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestPostalCode"/> property.
- /// </summary>
- private const string RequestPostalCodeViewStateKey = "RequestPostalCode";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestCountry"/> property.
- /// </summary>
- private const string RequestCountryViewStateKey = "RequestCountry";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequireSsl"/> property.
- /// </summary>
- private const string RequireSslViewStateKey = "RequireSsl";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestLanguage"/> property.
- /// </summary>
- private const string RequestLanguageViewStateKey = "RequestLanguage";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestTimeZone"/> property.
- /// </summary>
- private const string RequestTimeZoneViewStateKey = "RequestTimeZone";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="EnableRequestProfile"/> property.
- /// </summary>
- private const string EnableRequestProfileViewStateKey = "EnableRequestProfile";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="PolicyUrl"/> property.
- /// </summary>
- private const string PolicyUrlViewStateKey = "PolicyUrl";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestFullName"/> property.
- /// </summary>
- private const string RequestFullNameViewStateKey = "RequestFullName";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="UsePersistentCookie"/> property.
- /// </summary>
- private const string UsePersistentCookieViewStateKey = "UsePersistentCookie";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestGender"/> property.
- /// </summary>
- private const string RequestGenderViewStateKey = "RequestGender";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="ReturnToUrl"/> property.
- /// </summary>
- private const string ReturnToUrlViewStateKey = "ReturnToUrl";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Stateless"/> property.
- /// </summary>
- private const string StatelessViewStateKey = "Stateless";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="ImmediateMode"/> property.
- /// </summary>
- private const string ImmediateModeViewStateKey = "ImmediateMode";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestBirthDate"/> property.
- /// </summary>
- private const string RequestBirthDateViewStateKey = "RequestBirthDate";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RealmUrl"/> property.
- /// </summary>
- private const string RealmUrlViewStateKey = "RealmUrl";
-
- #endregion
-
- #region Property defaults
-
- /// <summary>
- /// The default value for the <see cref="EnableRequestProfile"/> property.
- /// </summary>
- private const bool EnableRequestProfileDefault = true;
-
- /// <summary>
- /// The default value for the <see cref="RequireSsl"/> property.
- /// </summary>
- private const bool RequireSslDefault = false;
-
- /// <summary>
- /// The default value for the <see cref="ImmediateMode"/> property.
- /// </summary>
- private const bool ImmediateModeDefault = false;
-
- /// <summary>
- /// The default value for the <see cref="Stateless"/> property.
- /// </summary>
- private const bool StatelessDefault = false;
-
- /// <summary>
- /// The default value for the <see cref="PolicyUrl"/> property.
- /// </summary>
- private const string PolicyUrlDefault = "";
-
- /// <summary>
- /// The default value for the <see cref="ReturnToUrl"/> property.
- /// </summary>
- private const string ReturnToUrlDefault = "";
-
- /// <summary>
- /// The default value for the <see cref="RealmUrl"/> property.
- /// </summary>
- private const string RealmUrlDefault = "~/";
-
- /// <summary>
- /// The default value for the <see cref="RequestEmail"/> property.
- /// </summary>
- private const DemandLevel RequestEmailDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestPostalCode"/> property.
- /// </summary>
- private const DemandLevel RequestPostalCodeDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestCountry"/> property.
- /// </summary>
- private const DemandLevel RequestCountryDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestLanguage"/> property.
- /// </summary>
- private const DemandLevel RequestLanguageDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestTimeZone"/> property.
- /// </summary>
- private const DemandLevel RequestTimeZoneDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestNickname"/> property.
- /// </summary>
- private const DemandLevel RequestNicknameDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestFullName"/> property.
- /// </summary>
- private const DemandLevel RequestFullNameDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestBirthDate"/> property.
- /// </summary>
- private const DemandLevel RequestBirthDateDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestGender"/> property.
- /// </summary>
- private const DemandLevel RequestGenderDefault = DemandLevel.NoRequest;
-
- #endregion
-
- /// <summary>
- /// The callback parameter for use with persisting the <see cref="UsePersistentCookie"/> property.
- /// </summary>
- private const string UsePersistentCookieCallbackKey = "OpenIdTextBox_UsePersistentCookie";
-
- /// <summary>
- /// Backing field for the <see cref="RelyingParty"/> property.
- /// </summary>
- private OpenIdRelyingParty relyingParty;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdMobileTextBox"/> class.
- /// </summary>
- public OpenIdMobileTextBox() {
- Reporting.RecordFeatureUse(this);
- }
-
- #region Events
-
- /// <summary>
- /// Fired upon completion of a successful login.
- /// </summary>
- [Description("Fired upon completion of a successful login.")]
- public event EventHandler<OpenIdEventArgs> LoggedIn;
-
- /// <summary>
- /// Fired when a login attempt fails.
- /// </summary>
- [Description("Fired when a login attempt fails.")]
- public event EventHandler<OpenIdEventArgs> Failed;
-
- /// <summary>
- /// Fired when an authentication attempt is canceled at the OpenID Provider.
- /// </summary>
- [Description("Fired when an authentication attempt is canceled at the OpenID Provider.")]
- public event EventHandler<OpenIdEventArgs> Canceled;
-
- /// <summary>
- /// Fired when an Immediate authentication attempt fails, and the Provider suggests using non-Immediate mode.
- /// </summary>
- [Description("Fired when an Immediate authentication attempt fails, and the Provider suggests using non-Immediate mode.")]
- public event EventHandler<OpenIdEventArgs> SetupRequired;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets or sets the OpenID <see cref="Realm"/> of the relying party web site.
- /// </summary>
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "DotNetOpenAuth.OpenId.Realm", Justification = "Using Realm.ctor for validation.")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "DotNetOpenAuth.OpenId", Justification = "Using ctor for validation.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(RealmUrlDefault), Category(BehaviorCategory)]
- [Description("The OpenID Realm of the relying party web site.")]
- public string RealmUrl {
- get {
- return (string)(ViewState[RealmUrlViewStateKey] ?? RealmUrlDefault);
- }
-
- set {
- if (Page != null && !DesignMode) {
- // Validate new value by trying to construct a Realm object based on it.
- new Realm(OpenIdUtilities.GetResolvedRealm(this.Page, value, this.RelyingParty.Channel.GetRequestFromContext())); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value.Replace("*.", string.Empty)); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
- }
- ViewState[RealmUrlViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the OpenID ReturnTo of the relying party web site.
- /// </summary>
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Uri(Uri, string) accepts second arguments that Uri(Uri, new Uri(string)) does not that we must support.")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(ReturnToUrlDefault), Category(BehaviorCategory)]
- [Description("The OpenID ReturnTo of the relying party web site.")]
- public string ReturnToUrl {
- get {
- return (string)(ViewState[ReturnToUrlViewStateKey] ?? ReturnToUrlDefault);
- }
-
- set {
- if (Page != null && !DesignMode) {
- // Validate new value by trying to construct a Uri based on it.
- new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.Page.ResolveUrl(value)); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
- }
-
- ViewState[ReturnToUrlViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to use immediate mode in the
- /// OpenID protocol.
- /// </summary>
- /// <value>
- /// True if a Provider should reply immediately to the authentication request
- /// without interacting with the user. False if the Provider can take time
- /// to authenticate the user in order to complete an authentication attempt.
- /// </value>
- /// <remarks>
- /// Setting this to true is sometimes useful in AJAX scenarios. Setting this to
- /// true can cause failed authentications when the user truly controls an
- /// Identifier, but must complete an authentication step with the Provider before
- /// the Provider will approve the login from this relying party.
- /// </remarks>
- [Bindable(true), DefaultValue(ImmediateModeDefault), Category(BehaviorCategory)]
- [Description("Whether the Provider should respond immediately to an authentication attempt without interacting with the user.")]
- public bool ImmediateMode {
- get { return (bool)(ViewState[ImmediateModeViewStateKey] ?? ImmediateModeDefault); }
- set { ViewState[ImmediateModeViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether stateless mode is used.
- /// </summary>
- [Bindable(true), DefaultValue(StatelessDefault), Category(BehaviorCategory)]
- [Description("Controls whether stateless mode is used.")]
- public bool Stateless {
- get { return (bool)(ViewState[StatelessViewStateKey] ?? StatelessDefault); }
- set { ViewState[StatelessViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to send a persistent cookie upon successful
- /// login so the user does not have to log in upon returning to this site.
- /// </summary>
- [Bindable(true), DefaultValue(UsePersistentCookieDefault), Category(BehaviorCategory)]
- [Description("Whether to send a persistent cookie upon successful " +
- "login so the user does not have to log in upon returning to this site.")]
- public virtual bool UsePersistentCookie {
- get { return (bool)(this.ViewState[UsePersistentCookieViewStateKey] ?? UsePersistentCookieDefault); }
- set { this.ViewState[UsePersistentCookieViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's nickname from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestNicknameDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's nickname from the Provider.")]
- public DemandLevel RequestNickname {
- get { return (DemandLevel)(ViewState[RequestNicknameViewStateKey] ?? RequestNicknameDefault); }
- set { ViewState[RequestNicknameViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's email address from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestEmailDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's email address from the Provider.")]
- public DemandLevel RequestEmail {
- get { return (DemandLevel)(ViewState[RequestEmailViewStateKey] ?? RequestEmailDefault); }
- set { ViewState[RequestEmailViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's full name from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestFullNameDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's full name from the Provider")]
- public DemandLevel RequestFullName {
- get { return (DemandLevel)(ViewState[RequestFullNameViewStateKey] ?? RequestFullNameDefault); }
- set { ViewState[RequestFullNameViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's birthdate from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestBirthDateDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's birthdate from the Provider.")]
- public DemandLevel RequestBirthDate {
- get { return (DemandLevel)(ViewState[RequestBirthDateViewStateKey] ?? RequestBirthDateDefault); }
- set { ViewState[RequestBirthDateViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's gender from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestGenderDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's gender from the Provider.")]
- public DemandLevel RequestGender {
- get { return (DemandLevel)(ViewState[RequestGenderViewStateKey] ?? RequestGenderDefault); }
- set { ViewState[RequestGenderViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's postal code from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestPostalCodeDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's postal code from the Provider.")]
- public DemandLevel RequestPostalCode {
- get { return (DemandLevel)(ViewState[RequestPostalCodeViewStateKey] ?? RequestPostalCodeDefault); }
- set { ViewState[RequestPostalCodeViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's country from the Provider.
- /// </summary>
- [Bindable(true)]
- [Category(ProfileCategory)]
- [DefaultValue(RequestCountryDefault)]
- [Description("Your level of interest in receiving the user's country from the Provider.")]
- public DemandLevel RequestCountry {
- get { return (DemandLevel)(ViewState[RequestCountryViewStateKey] ?? RequestCountryDefault); }
- set { ViewState[RequestCountryViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's preferred language from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestLanguageDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's preferred language from the Provider.")]
- public DemandLevel RequestLanguage {
- get { return (DemandLevel)(ViewState[RequestLanguageViewStateKey] ?? RequestLanguageDefault); }
- set { ViewState[RequestLanguageViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's time zone from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestTimeZoneDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's time zone from the Provider.")]
- public DemandLevel RequestTimeZone {
- get { return (DemandLevel)(ViewState[RequestTimeZoneViewStateKey] ?? RequestTimeZoneDefault); }
- set { ViewState[RequestTimeZoneViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the URL to your privacy policy page that describes how
- /// claims will be used and/or shared.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(PolicyUrlDefault), Category(ProfileCategory)]
- [Description("The URL to your privacy policy page that describes how claims will be used and/or shared.")]
- public string PolicyUrl {
- get {
- return (string)ViewState[PolicyUrlViewStateKey] ?? PolicyUrlDefault;
- }
-
- set {
- UriUtil.ValidateResolvableUrl(Page, DesignMode, value);
- ViewState[PolicyUrlViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to use OpenID extensions
- /// to retrieve profile data of the authenticating user.
- /// </summary>
- [Bindable(true), DefaultValue(EnableRequestProfileDefault), Category(ProfileCategory)]
- [Description("Turns the entire Simple Registration extension on or off.")]
- public bool EnableRequestProfile {
- get { return (bool)(ViewState[EnableRequestProfileViewStateKey] ?? EnableRequestProfileDefault); }
- set { ViewState[EnableRequestProfileViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to enforce on high security mode,
- /// which requires the full authentication pipeline to be protected by SSL.
- /// </summary>
- [Bindable(true), DefaultValue(RequireSslDefault), Category(BehaviorCategory)]
- [Description("Turns on high security mode, requiring the full authentication pipeline to be protected by SSL.")]
- public bool RequireSsl {
- get { return (bool)(ViewState[RequireSslViewStateKey] ?? RequireSslDefault); }
- set { ViewState[RequireSslViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the type of the custom application store to use, or <c>null</c> to use the default.
- /// </summary>
- /// <remarks>
- /// If set, this property must be set in each Page Load event
- /// as it is not persisted across postbacks.
- /// </remarks>
- public IOpenIdApplicationStore CustomApplicationStore { get; set; }
-
- #endregion
-
- /// <summary>
- /// Gets or sets the <see cref="OpenIdRelyingParty"/> instance to use.
- /// </summary>
- /// <value>The default value is an <see cref="OpenIdRelyingParty"/> instance initialized according to the web.config file.</value>
- /// <remarks>
- /// A performance optimization would be to store off the
- /// instance as a static member in your web site and set it
- /// to this property in your <see cref="Control.Load">Page.Load</see>
- /// event since instantiating these instances can be expensive on
- /// heavily trafficked web pages.
- /// </remarks>
- public OpenIdRelyingParty RelyingParty {
- get {
- if (this.relyingParty == null) {
- this.relyingParty = this.CreateRelyingParty();
- }
- return this.relyingParty;
- }
-
- set {
- this.relyingParty = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the OpenID authentication request that is about to be sent.
- /// </summary>
- protected IAuthenticationRequest Request { get; set; }
-
- /// <summary>
- /// Immediately redirects to the OpenID Provider to verify the Identifier
- /// provided in the text box.
- /// </summary>
- public void LogOn() {
- if (this.Request == null) {
- this.CreateRequest(); // sets this.Request
- }
-
- if (this.Request != null) {
- this.Request.RedirectToProvider();
- }
- }
-
- /// <summary>
- /// Constructs the authentication request and returns it.
- /// </summary>
- /// <returns>The instantiated authentication request.</returns>
- /// <remarks>
- /// <para>This method need not be called before calling the <see cref="LogOn"/> method,
- /// but is offered in the event that adding extensions to the request is desired.</para>
- /// <para>The Simple Registration extension arguments are added to the request
- /// before returning if <see cref="EnableRequestProfile"/> is set to true.</para>
- /// </remarks>
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Uri(Uri, string) accepts second arguments that Uri(Uri, new Uri(string)) does not that we must support.")]
- public IAuthenticationRequest CreateRequest() {
- Contract.Requires<InvalidOperationException>(this.Request == null, OpenIdStrings.CreateRequestAlreadyCalled);
- Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.Text), OpenIdStrings.OpenIdTextBoxEmpty);
-
- try {
- // Resolve the trust root, and swap out the scheme and port if necessary to match the
- // return_to URL, since this match is required by OpenId, and the consumer app
- // may be using HTTP at some times and HTTPS at others.
- UriBuilder realm = OpenIdUtilities.GetResolvedRealm(this.Page, this.RealmUrl, this.RelyingParty.Channel.GetRequestFromContext());
- realm.Scheme = Page.Request.Url.Scheme;
- realm.Port = Page.Request.Url.Port;
-
- // Initiate openid request
- // We use TryParse here to avoid throwing an exception which
- // might slip through our validator control if it is disabled.
- Identifier userSuppliedIdentifier;
- if (Identifier.TryParse(this.Text, out userSuppliedIdentifier)) {
- Realm typedRealm = new Realm(realm);
- if (string.IsNullOrEmpty(this.ReturnToUrl)) {
- this.Request = this.RelyingParty.CreateRequest(userSuppliedIdentifier, typedRealm);
- } else {
- Uri returnTo = new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.ReturnToUrl);
- this.Request = this.RelyingParty.CreateRequest(userSuppliedIdentifier, typedRealm, returnTo);
- }
- this.Request.Mode = this.ImmediateMode ? AuthenticationRequestMode.Immediate : AuthenticationRequestMode.Setup;
- if (this.EnableRequestProfile) {
- this.AddProfileArgs(this.Request);
- }
-
- // Add state that needs to survive across the redirect.
- this.Request.SetUntrustedCallbackArgument(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString(CultureInfo.InvariantCulture));
- } else {
- Logger.OpenId.WarnFormat("An invalid identifier was entered ({0}), but not caught by any validation routine.", this.Text);
- this.Request = null;
- }
- } catch (ProtocolException ex) {
- this.OnFailed(new FailedAuthenticationResponse(ex));
- }
-
- return this.Request;
- }
-
- /// <summary>
- /// Checks for incoming OpenID authentication responses and fires appropriate events.
- /// </summary>
- /// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnLoad(EventArgs e) {
- base.OnLoad(e);
-
- if (Page.IsPostBack) {
- return;
- }
-
- var response = this.RelyingParty.GetResponse();
- if (response != null) {
- string persistentString = response.GetUntrustedCallbackArgument(UsePersistentCookieCallbackKey);
- bool persistentBool;
- if (persistentString != null && bool.TryParse(persistentString, out persistentBool)) {
- this.UsePersistentCookie = persistentBool;
- }
-
- switch (response.Status) {
- case AuthenticationStatus.Canceled:
- this.OnCanceled(response);
- break;
- case AuthenticationStatus.Authenticated:
- this.OnLoggedIn(response);
- break;
- case AuthenticationStatus.SetupRequired:
- this.OnSetupRequired(response);
- break;
- case AuthenticationStatus.Failed:
- this.OnFailed(response);
- break;
- default:
- throw new InvalidOperationException("Unexpected response status code.");
- }
- }
- }
-
- #region Events
-
- /// <summary>
- /// Fires the <see cref="LoggedIn"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnLoggedIn(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Authenticated, "Firing OnLoggedIn event without an authenticated response.");
-
- var loggedIn = this.LoggedIn;
- OpenIdEventArgs args = new OpenIdEventArgs(response);
- if (loggedIn != null) {
- loggedIn(this, args);
- }
-
- if (!args.Cancel) {
- FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie);
- }
- }
-
- /// <summary>
- /// Fires the <see cref="Failed"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnFailed(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Failed, "Firing Failed event for the wrong response type.");
-
- var failed = this.Failed;
- if (failed != null) {
- failed(this, new OpenIdEventArgs(response));
- }
- }
-
- /// <summary>
- /// Fires the <see cref="Canceled"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnCanceled(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Canceled, "Firing Canceled event for the wrong response type.");
-
- var canceled = this.Canceled;
- if (canceled != null) {
- canceled(this, new OpenIdEventArgs(response));
- }
- }
-
- /// <summary>
- /// Fires the <see cref="SetupRequired"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnSetupRequired(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.SetupRequired, "Firing SetupRequired event for the wrong response type.");
-
- // Why are we firing Failed when we're OnSetupRequired? Backward compatibility.
- var setupRequired = this.SetupRequired;
- if (setupRequired != null) {
- setupRequired(this, new OpenIdEventArgs(response));
- }
- }
-
- #endregion
-
- /// <summary>
- /// Adds extensions to a given authentication request to ask the Provider
- /// for user profile data.
- /// </summary>
- /// <param name="request">The authentication request to add the extensions to.</param>
- private void AddProfileArgs(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- request.AddExtension(new ClaimsRequest() {
- Nickname = this.RequestNickname,
- Email = this.RequestEmail,
- FullName = this.RequestFullName,
- BirthDate = this.RequestBirthDate,
- Gender = this.RequestGender,
- PostalCode = this.RequestPostalCode,
- Country = this.RequestCountry,
- Language = this.RequestLanguage,
- TimeZone = this.RequestTimeZone,
- PolicyUrl = string.IsNullOrEmpty(this.PolicyUrl) ?
- null : new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.Page.ResolveUrl(this.PolicyUrl)),
- });
- }
-
- /// <summary>
- /// Creates the relying party instance used to generate authentication requests.
- /// </summary>
- /// <returns>The instantiated relying party.</returns>
- private OpenIdRelyingParty CreateRelyingParty() {
- // If we're in stateful mode, first use the explicitly given one on this control if there
- // is one. Then try the configuration file specified one. Finally, use the default
- // in-memory one that's built into OpenIdRelyingParty.
- IOpenIdApplicationStore store = this.Stateless ? null :
- (this.CustomApplicationStore ?? OpenIdElement.Configuration.RelyingParty.ApplicationStore.CreateInstance(OpenIdRelyingParty.HttpApplicationStore));
- var rp = new OpenIdRelyingParty(store);
- try {
- // Only set RequireSsl to true, as we don't want to override
- // a .config setting of true with false.
- if (this.RequireSsl) {
- rp.SecuritySettings.RequireSsl = true;
- }
- return rp;
- } catch {
- rp.Dispose();
- throw;
- }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
deleted file mode 100644
index eaaba8c..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
+++ /dev/null
@@ -1,468 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdRelyingPartyAjaxControlBase.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyAjaxControlBase.EmbeddedAjaxJavascriptResource, "text/javascript")]
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Linq;
- using System.Text;
- using System.Web;
- using System.Web.Script.Serialization;
- using System.Web.UI;
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.Extensions;
-
- /// <summary>
- /// A common base class for OpenID Relying Party controls.
- /// </summary>
- public abstract class OpenIdRelyingPartyAjaxControlBase : OpenIdRelyingPartyControlBase, ICallbackEventHandler {
- /// <summary>
- /// The manifest resource name of the javascript file to include on the hosting page.
- /// </summary>
- internal const string EmbeddedAjaxJavascriptResource = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdRelyingPartyAjaxControlBase.js";
-
- /// <summary>
- /// The "dnoa.op_endpoint" string.
- /// </summary>
- internal const string OPEndpointParameterName = OpenIdUtilities.CustomParameterPrefix + "op_endpoint";
-
- /// <summary>
- /// The "dnoa.claimed_id" string.
- /// </summary>
- internal const string ClaimedIdParameterName = OpenIdUtilities.CustomParameterPrefix + "claimed_id";
-
- /// <summary>
- /// The name of the javascript field that stores the maximum time a positive assertion is
- /// good for before it must be refreshed.
- /// </summary>
- internal const string MaxPositiveAssertionLifetimeJsName = "window.dnoa_internal.maxPositiveAssertionLifetime";
-
- /// <summary>
- /// The name of the javascript function that will initiate an asynchronous callback.
- /// </summary>
- protected internal const string CallbackJSFunctionAsync = "window.dnoa_internal.callbackAsync";
-
- /// <summary>
- /// The name of the javascript function that will initiate a synchronous callback.
- /// </summary>
- protected const string CallbackJSFunction = "window.dnoa_internal.callback";
-
- #region Property viewstate keys
-
- /// <summary>
- /// The viewstate key to use for storing the value of a successful authentication.
- /// </summary>
- private const string AuthDataViewStateKey = "AuthData";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticationResponse"/> property.
- /// </summary>
- private const string AuthenticationResponseViewStateKey = "AuthenticationResponse";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticationProcessedAlready"/> property.
- /// </summary>
- private const string AuthenticationProcessedAlreadyViewStateKey = "AuthenticationProcessedAlready";
-
- #endregion
-
- /// <summary>
- /// Default value of the <see cref="Popup"/> property.
- /// </summary>
- private const PopupBehavior PopupDefault = PopupBehavior.Always;
-
- /// <summary>
- /// Default value of <see cref="LogOnMode"/> property..
- /// </summary>
- private const LogOnSiteNotification LogOnModeDefault = LogOnSiteNotification.None;
-
- /// <summary>
- /// The authentication response that just came in.
- /// </summary>
- private IAuthenticationResponse authenticationResponse;
-
- /// <summary>
- /// Stores the result of an AJAX discovery request while it is waiting
- /// to be picked up by ASP.NET on the way down to the user agent.
- /// </summary>
- private string discoveryResult;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdRelyingPartyAjaxControlBase"/> class.
- /// </summary>
- protected OpenIdRelyingPartyAjaxControlBase() {
- // The AJAX login style always uses popups (or invisible iframes).
- base.Popup = PopupDefault;
-
- // The expected use case for the AJAX login box is for comments... not logging in.
- this.LogOnMode = LogOnModeDefault;
- }
-
- /// <summary>
- /// Fired when a Provider sends back a positive assertion to this control,
- /// but the authentication has not yet been verified.
- /// </summary>
- /// <remarks>
- /// <b>No security critical decisions should be made within event handlers
- /// for this event</b> as the authenticity of the assertion has not been
- /// verified yet. All security related code should go in the event handler
- /// for the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event.
- /// </remarks>
- [Description("Fired when a Provider sends back a positive assertion to this control, but the authentication has not yet been verified.")]
- public event EventHandler<OpenIdEventArgs> UnconfirmedPositiveAssertion;
-
- /// <summary>
- /// Gets or sets a value indicating when to use a popup window to complete the login experience.
- /// </summary>
- /// <value>The default value is <see cref="PopupBehavior.Never"/>.</value>
- [Bindable(false), Browsable(false), DefaultValue(PopupDefault)]
- public override PopupBehavior Popup {
- get { return base.Popup; }
- set { ErrorUtilities.VerifySupported(value == base.Popup, OpenIdStrings.PropertyValueNotSupported); }
- }
-
- /// <summary>
- /// Gets or sets the way a completed login is communicated to the rest of the web site.
- /// </summary>
- [Bindable(true), DefaultValue(LogOnModeDefault), Category(BehaviorCategory)]
- [Description("The way a completed login is communicated to the rest of the web site.")]
- public override LogOnSiteNotification LogOnMode { // override to set new DefaultValue
- get { return base.LogOnMode; }
- set { base.LogOnMode = value; }
- }
-
- /// <summary>
- /// Gets or sets the <see cref="OpenIdRelyingParty"/> instance to use.
- /// </summary>
- /// <value>
- /// The default value is an <see cref="OpenIdRelyingParty"/> instance initialized according to the web.config file.
- /// </value>
- /// <remarks>
- /// A performance optimization would be to store off the
- /// instance as a static member in your web site and set it
- /// to this property in your <see cref="Control.Load">Page.Load</see>
- /// event since instantiating these instances can be expensive on
- /// heavily trafficked web pages.
- /// </remarks>
- public override OpenIdRelyingParty RelyingParty {
- get {
- return base.RelyingParty;
- }
-
- set {
- // Make sure we get an AJAX-ready instance.
- ErrorUtilities.VerifyArgument(value is OpenIdAjaxRelyingParty, OpenIdStrings.TypeMustImplementX, typeof(OpenIdAjaxRelyingParty).Name);
- base.RelyingParty = value;
- }
- }
-
- /// <summary>
- /// Gets the completed authentication response.
- /// </summary>
- public IAuthenticationResponse AuthenticationResponse {
- get {
- if (this.authenticationResponse == null) {
- // We will either validate a new response and return a live AuthenticationResponse
- // or we will try to deserialize a previous IAuthenticationResponse (snapshot)
- // from viewstate and return that.
- IAuthenticationResponse viewstateResponse = this.ViewState[AuthenticationResponseViewStateKey] as IAuthenticationResponse;
- string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
- string formAuthData = this.Page.Request.Form[this.OpenIdAuthDataFormKey];
-
- // First see if there is fresh auth data to be processed into a response.
- if (!string.IsNullOrEmpty(formAuthData) && !string.Equals(viewstateAuthData, formAuthData, StringComparison.Ordinal)) {
- this.ViewState[AuthDataViewStateKey] = formAuthData;
-
- Uri authUri = new Uri(formAuthData);
- HttpRequestInfo clientResponseInfo = new HttpRequestInfo {
- UrlBeforeRewriting = authUri,
- };
-
- this.authenticationResponse = this.RelyingParty.GetResponse(clientResponseInfo);
- Logger.Controls.DebugFormat(
- "The {0} control checked for an authentication response and found: {1}",
- this.ID,
- this.authenticationResponse.Status);
- this.AuthenticationProcessedAlready = false;
-
- // Save out the authentication response to viewstate so we can find it on
- // a subsequent postback.
- this.ViewState[AuthenticationResponseViewStateKey] = new PositiveAuthenticationResponseSnapshot(this.authenticationResponse);
- } else {
- this.authenticationResponse = viewstateResponse;
- }
- }
-
- return this.authenticationResponse;
- }
- }
-
- /// <summary>
- /// Gets the relying party as its AJAX type.
- /// </summary>
- protected OpenIdAjaxRelyingParty AjaxRelyingParty {
- get { return (OpenIdAjaxRelyingParty)this.RelyingParty; }
- }
-
- /// <summary>
- /// Gets the name of the open id auth data form key (for the value as stored at the user agent as a FORM field).
- /// </summary>
- /// <value>Usually a concatenation of the control's name and <c>"_openidAuthData"</c>.</value>
- protected abstract string OpenIdAuthDataFormKey { get; }
-
- /// <summary>
- /// Gets or sets a value indicating whether an authentication in the page's view state
- /// has already been processed and appropriate events fired.
- /// </summary>
- private bool AuthenticationProcessedAlready {
- get { return (bool)(ViewState[AuthenticationProcessedAlreadyViewStateKey] ?? false); }
- set { ViewState[AuthenticationProcessedAlreadyViewStateKey] = value; }
- }
-
- /// <summary>
- /// Allows an OpenID extension to read data out of an unverified positive authentication assertion
- /// and send it down to the client browser so that Javascript running on the page can perform
- /// some preprocessing on the extension data.
- /// </summary>
- /// <typeparam name="T">The extension <i>response</i> type that will read data from the assertion.</typeparam>
- /// <param name="propertyName">The property name on the openid_identifier input box object that will be used to store the extension data. For example: sreg</param>
- /// <remarks>
- /// This method should be called from the <see cref="UnconfirmedPositiveAssertion"/> event handler.
- /// </remarks>
- [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "By design")]
- public void RegisterClientScriptExtension<T>(string propertyName) where T : IClientScriptExtensionResponse {
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(propertyName));
- this.RelyingParty.RegisterClientScriptExtension<T>(propertyName);
- }
-
- #region ICallbackEventHandler Members
-
- /// <summary>
- /// Returns the result of discovery on some Identifier passed to <see cref="ICallbackEventHandler.RaiseCallbackEvent"/>.
- /// </summary>
- /// <returns>The result of the callback.</returns>
- /// <value>A whitespace delimited list of URLs that can be used to initiate authentication.</value>
- string ICallbackEventHandler.GetCallbackResult() {
- return this.GetCallbackResult();
- }
-
- /// <summary>
- /// Performs discovery on some OpenID Identifier. Called directly from the user agent via
- /// AJAX callback mechanisms.
- /// </summary>
- /// <param name="eventArgument">The identifier to perform discovery on.</param>
- [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "We want to preserve the signature of the interface.")]
- void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument) {
- this.RaiseCallbackEvent(eventArgument);
- }
-
- #endregion
-
- /// <summary>
- /// Returns the results of a callback event that targets a control.
- /// </summary>
- /// <returns>The result of the callback.</returns>
- [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "We want to preserve the signature of the interface.")]
- protected virtual string GetCallbackResult() {
- this.Page.Response.ContentType = "text/javascript";
- return this.discoveryResult;
- }
-
- /// <summary>
- /// Processes a callback event that targets a control.
- /// </summary>
- /// <param name="eventArgument">A string that represents an event argument to pass to the event handler.</param>
- [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "We want to preserve the signature of the interface.")]
- protected virtual void RaiseCallbackEvent(string eventArgument) {
- string userSuppliedIdentifier = eventArgument;
-
- ErrorUtilities.VerifyNonZeroLength(userSuppliedIdentifier, "userSuppliedIdentifier");
- Logger.OpenId.InfoFormat("AJAX discovery on {0} requested.", userSuppliedIdentifier);
-
- this.Identifier = userSuppliedIdentifier;
-
- var serializer = new JavaScriptSerializer();
- IEnumerable<IAuthenticationRequest> requests = this.CreateRequests(this.Identifier);
- this.discoveryResult = serializer.Serialize(this.AjaxRelyingParty.AsJsonDiscoveryResult(requests));
- }
-
- /// <summary>
- /// Creates the relying party instance used to generate authentication requests.
- /// </summary>
- /// <param name="store">The store to pass to the relying party constructor.</param>
- /// <returns>The instantiated relying party.</returns>
- protected override OpenIdRelyingParty CreateRelyingParty(IOpenIdApplicationStore store) {
- return new OpenIdAjaxRelyingParty(store);
- }
-
- /// <summary>
- /// Pre-discovers an identifier and makes the results available to the
- /// user agent for javascript as soon as the page loads.
- /// </summary>
- /// <param name="identifier">The identifier.</param>
- protected void PreloadDiscovery(Identifier identifier) {
- this.PreloadDiscovery(new[] { identifier });
- }
-
- /// <summary>
- /// Pre-discovers a given set of identifiers and makes the results available to the
- /// user agent for javascript as soon as the page loads.
- /// </summary>
- /// <param name="identifiers">The identifiers to perform discovery on.</param>
- protected void PreloadDiscovery(IEnumerable<Identifier> identifiers) {
- string script = this.AjaxRelyingParty.AsAjaxPreloadedDiscoveryResult(
- identifiers.SelectMany(id => this.CreateRequests(id)));
- this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyAjaxControlBase), this.ClientID, script, true);
- }
-
- /// <summary>
- /// Fires the <see cref="UnconfirmedPositiveAssertion"/> event.
- /// </summary>
- protected virtual void OnUnconfirmedPositiveAssertion() {
- var unconfirmedPositiveAssertion = this.UnconfirmedPositiveAssertion;
- if (unconfirmedPositiveAssertion != null) {
- unconfirmedPositiveAssertion(this, null);
- }
- }
-
- /// <summary>
- /// Raises the <see cref="E:Load"/> event.
- /// </summary>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- protected override void OnLoad(EventArgs e) {
- base.OnLoad(e);
-
- // Our parent control ignores all OpenID messages included in a postback,
- // but our AJAX controls hide an old OpenID message in a postback payload,
- // so we deserialize it and process it when appropriate.
- if (this.Page.IsPostBack) {
- if (this.AuthenticationResponse != null && !this.AuthenticationProcessedAlready) {
- // Only process messages targeted at this control.
- // Note that Stateless mode causes no receiver to be indicated.
- string receiver = this.AuthenticationResponse.GetUntrustedCallbackArgument(ReturnToReceivingControlId);
- if (receiver == null || receiver == this.ClientID) {
- this.ProcessResponse(this.AuthenticationResponse);
- this.AuthenticationProcessedAlready = true;
- }
- }
- }
- }
-
- /// <summary>
- /// Called when the <see cref="Identifier"/> property is changed.
- /// </summary>
- protected override void OnIdentifierChanged() {
- base.OnIdentifierChanged();
-
- // Since the identifier changed, make sure we reset any cached authentication on the user agent.
- this.ViewState.Remove(AuthDataViewStateKey);
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
-
- this.SetWebAppPathOnUserAgent();
- this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdRelyingPartyAjaxControlBase), EmbeddedAjaxJavascriptResource);
-
- StringBuilder initScript = new StringBuilder();
-
- initScript.AppendLine(CallbackJSFunctionAsync + " = " + this.GetJsCallbackConvenienceFunction(true));
- initScript.AppendLine(CallbackJSFunction + " = " + this.GetJsCallbackConvenienceFunction(false));
-
- // Positive assertions can last no longer than this library is willing to consider them valid,
- // and when they come with OP private associations they last no longer than the OP is willing
- // to consider them valid. We assume the OP will hold them valid for at least five minutes.
- double assertionLifetimeInMilliseconds = Math.Min(TimeSpan.FromMinutes(5).TotalMilliseconds, Math.Min(OpenIdElement.Configuration.MaxAuthenticationTime.TotalMilliseconds, DotNetOpenAuthSection.Messaging.MaximumMessageLifetime.TotalMilliseconds));
- initScript.AppendLine(MaxPositiveAssertionLifetimeJsName + " = " + assertionLifetimeInMilliseconds.ToString(CultureInfo.InvariantCulture) + ";");
-
- // We register this callback code explicitly with a specific type rather than the derived-type of the control
- // to ensure that this discovery callback function is only set ONCE for the HTML document.
- this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyControlBase), "initializer", initScript.ToString(), true);
- }
-
- /// <summary>
- /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
- protected override void Render(HtmlTextWriter writer) {
- Contract.Assume(writer != null, "Missing contract.");
- base.Render(writer);
-
- // Emit a hidden field to let the javascript on the user agent know if an
- // authentication has already successfully taken place.
- string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
- if (!string.IsNullOrEmpty(viewstateAuthData)) {
- writer.AddAttribute(HtmlTextWriterAttribute.Name, this.OpenIdAuthDataFormKey);
- writer.AddAttribute(HtmlTextWriterAttribute.Value, viewstateAuthData, true);
- writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden");
- writer.RenderBeginTag(HtmlTextWriterTag.Input);
- writer.RenderEndTag();
- }
- }
-
- /// <summary>
- /// Notifies the user agent via an AJAX response of a completed authentication attempt.
- /// </summary>
- protected override void ScriptClosingPopupOrIFrame() {
- Action<AuthenticationStatus> callback = status => {
- if (status == AuthenticationStatus.Authenticated) {
- this.OnUnconfirmedPositiveAssertion(); // event handler will fill the clientScriptExtensions collection.
- }
- };
-
- OutgoingWebResponse response = this.RelyingParty.ProcessResponseFromPopup(
- this.RelyingParty.Channel.GetRequestFromContext(),
- callback);
-
- response.Respond();
- }
-
- /// <summary>
- /// Constructs a function that will initiate an AJAX callback.
- /// </summary>
- /// <param name="async">if set to <c>true</c> causes the AJAX callback to be a little more asynchronous. Note that <c>false</c> does not mean the call is absolutely synchronous.</param>
- /// <returns>The string defining a javascript anonymous function that initiates a callback.</returns>
- private string GetJsCallbackConvenienceFunction(bool async) {
- string argumentParameterName = "argument";
- string callbackResultParameterName = "resultFunction";
- string callbackErrorCallbackParameterName = "errorCallback";
- string callback = Page.ClientScript.GetCallbackEventReference(
- this,
- argumentParameterName,
- callbackResultParameterName,
- argumentParameterName,
- callbackErrorCallbackParameterName,
- async);
- return string.Format(
- CultureInfo.InvariantCulture,
- "function({1}, {2}, {3}) {{{0}\treturn {4};{0}}};",
- Environment.NewLine,
- argumentParameterName,
- callbackResultParameterName,
- callbackErrorCallbackParameterName,
- callback);
- }
-
- /// <summary>
- /// Sets the window.aspnetapppath variable on the user agent so that cookies can be set with the proper path.
- /// </summary>
- private void SetWebAppPathOnUserAgent() {
- string script = "window.aspnetapppath = " + MessagingUtilities.GetSafeJavascriptValue(this.Page.Request.ApplicationPath) + ";";
- this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyAjaxControlBase), "webapppath", script, true);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
deleted file mode 100644
index 4de5188..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
+++ /dev/null
@@ -1,751 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdRelyingPartyAjaxControlBase.js" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// This file may be used and redistributed under the terms of the
-// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
-// </copyright>
-//-----------------------------------------------------------------------
-
-if (window.dnoa_internal === undefined) {
- window.dnoa_internal = {};
-}
-
-/// <summary>Removes a given element from the array.</summary>
-/// <returns>True if the element was in the array, or false if it was not found.</returns>
-Array.prototype.remove = function(element) {
- function elementToRemoveLast(a, b) {
- if (a == element) { return 1; }
- if (b == element) { return -1; }
- return 0;
- }
- this.sort(elementToRemoveLast);
- if (this[this.length - 1] == element) {
- this.pop();
- return true;
- } else {
- return false;
- }
-};
-
-// Renders all the parameters in their string form, surrounded by parentheses.
-window.dnoa_internal.argsToString = function() {
- result = "(";
- for (var i = 0; i < arguments.length; i++) {
- if (i > 0) { result += ', '; }
- var arg = arguments[i];
- if (typeof (arg) == 'string') {
- arg = '"' + arg + '"';
- } else if (arg === null) {
- arg = '[null]';
- } else if (arg === undefined) {
- arg = '[undefined]';
- }
- result += arg.toString();
- }
- result += ')';
- return result;
-};
-
-window.dnoa_internal.registerEvent = function(name) {
- var filterOnApplicability = function(fn, domElement) {
- /// <summary>Wraps a given function with a check so that the function only executes when a given element is still in the DOM.</summary>
- return function() {
- var args = Array.prototype.slice.call(arguments);
- if (!domElement) {
- // no element used as a basis of applicability indicates we always fire this callback.
- fn.apply(null, args);
- } else {
- var elements = document.getElementsByTagName(domElement.tagName);
- var isElementInDom = false;
- for (var i = 0; i < elements.length; i++) {
- if (elements[i] === domElement) {
- isElementInDom = true;
- break;
- }
- }
- if (isElementInDom) {
- fn.apply(null, args);
- }
- }
- }
- };
-
- window.dnoa_internal[name + 'Listeners'] = [];
- window.dnoa_internal['add' + name] = function(fn, whileDomElementApplicable) { window.dnoa_internal[name + 'Listeners'].push(filterOnApplicability(fn, whileDomElementApplicable)); };
- window.dnoa_internal['remove' + name] = function(fn) { window.dnoa_internal[name + 'Listeners'].remove(fn); };
- window.dnoa_internal['fire' + name] = function() {
- var args = Array.prototype.slice.call(arguments);
- trace('Firing event ' + name + window.dnoa_internal.argsToString.apply(null, args), 'blue');
- var listeners = window.dnoa_internal[name + 'Listeners'];
- for (var i = 0; i < listeners.length; i++) {
- listeners[i].apply(null, args);
- }
- };
-};
-
-window.dnoa_internal.registerEvent('DiscoveryStarted'); // (identifier) - fired when a discovery callback is ACTUALLY made to the RP
-window.dnoa_internal.registerEvent('DiscoverySuccess'); // (identifier, discoveryResult, { fresh: true|false }) - fired after a discovery callback is returned from the RP successfully or a cached result is retrieved
-window.dnoa_internal.registerEvent('DiscoveryFailed'); // (identifier, message) - fired after a discovery callback fails
-window.dnoa_internal.registerEvent('AuthStarted'); // (discoveryResult, serviceEndpoint, { background: true|false })
-window.dnoa_internal.registerEvent('AuthFailed'); // (discoveryResult, serviceEndpoint, { background: true|false }) - fired for each individual ServiceEndpoint, and once at last with serviceEndpoint==null if all failed
-window.dnoa_internal.registerEvent('AuthSuccess'); // (discoveryResult, serviceEndpoint, extensionResponses, { background: true|false, deserialized: true|false })
-window.dnoa_internal.registerEvent('AuthCleared'); // (discoveryResult, serviceEndpoint)
-
-window.dnoa_internal.discoveryResults = []; // user supplied identifiers and discovery results
-window.dnoa_internal.discoveryInProgress = []; // identifiers currently being discovered and their callbacks
-
-// The possible authentication results
-window.dnoa_internal.authSuccess = 'auth-success';
-window.dnoa_internal.authRefused = 'auth-refused';
-window.dnoa_internal.timedOut = 'timed-out';
-
-/// <summary>Instantiates a new FrameManager.</summary>
-/// <param name="maxFrames">The maximum number of concurrent 'jobs' (authentication attempts).</param>
-window.dnoa_internal.FrameManager = function(maxFrames) {
- this.queuedWork = [];
- this.frames = [];
- this.maxFrames = maxFrames;
-
- /// <summary>Called to queue up some work that will use an iframe as soon as it is available.</summary>
- /// <param name="job">
- /// A delegate that must return { url: /*to point the iframe to*/, onCanceled: /* callback */ }
- /// Its first parameter is the iframe created to service the request.
- /// It will only be called when the work actually begins.
- /// </param>
- /// <param name="p1">Arbitrary additional parameter to pass to the job.</param>
- this.enqueueWork = function(job, p1) {
- // Assign an iframe to this task immediately if there is one available.
- if (this.frames.length < this.maxFrames) {
- this.createIFrame(job, p1);
- } else {
- this.queuedWork.unshift({ job: job, p1: p1 });
- }
- };
-
- /// <summary>Clears the job queue and immediately closes all iframes.</summary>
- this.cancelAllWork = function() {
- trace('Canceling all open and pending iframes.');
- while (this.queuedWork.pop()) { }
- this.closeFrames();
- };
-
- /// <summary>An event fired when a frame is closing.</summary>
- this.onJobCompleted = function() {
- // If there is a job in the queue, go ahead and start it up.
- if (jobDesc = this.queuedWork.pop()) {
- this.createIFrame(jobDesc.job, jobDesc.p1);
- }
- };
-
- this.createIFrame = function(job, p1) {
- var iframe = document.createElement("iframe");
- if (!window.openid_visible_iframe) {
- iframe.setAttribute("width", 0);
- iframe.setAttribute("height", 0);
- iframe.setAttribute("style", "display: none");
- }
- var jobDescription = job(iframe, p1);
- iframe.setAttribute("src", jobDescription.url);
- iframe.onCanceled = jobDescription.onCanceled;
- iframe.dnoa_internal = window.dnoa_internal;
- document.body.insertBefore(iframe, document.body.firstChild);
- this.frames.push(iframe);
- return iframe;
- };
-
- this.closeFrames = function() {
- if (this.frames.length === 0) { return false; }
- for (var i = 0; i < this.frames.length; i++) {
- this.frames[i].src = "about:blank"; // doesn't have to exist. Just stop its processing.
- if (this.frames[i].parentNode) { this.frames[i].parentNode.removeChild(this.frames[i]); }
- }
- while (this.frames.length > 0) {
- var frame = this.frames.pop();
- if (frame.onCanceled) { frame.onCanceled(); }
- }
- return true;
- };
-
- this.closeFrame = function(frame) {
- frame.src = "about:blank"; // doesn't have to exist. Just stop its processing.
- if (frame.parentNode) { frame.parentNode.removeChild(frame); }
- var removed = this.frames.remove(frame);
- this.onJobCompleted();
- return removed;
- };
-};
-
-/// <summary>Instantiates an object that represents an OpenID Identifier.</summary>
-window.OpenIdIdentifier = function(identifier) {
- if (!identifier || identifier.length === 0) {
- throw 'Error: trying to create OpenIdIdentifier for null or empty string.';
- }
-
- /// <summary>Performs discovery on the identifier.</summary>
- /// <param name="onDiscoverSuccess">A function(DiscoveryResult) callback to be called when discovery has completed successfully.</param>
- /// <param name="onDiscoverFailure">A function callback to be called when discovery has completed in failure.</param>
- this.discover = function(onDiscoverSuccess, onDiscoverFailure) {
- /// <summary>Receives the results of a successful discovery (even if it yielded 0 results).</summary>
- function discoverSuccessCallback(discoveryResult, identifier) {
- trace('Discovery completed for: ' + identifier);
-
- // Deserialize the JSON object and store the result if it was a successful discovery.
- discoveryResult = eval('(' + discoveryResult + ')');
-
- // Add behavior for later use.
- discoveryResult = new window.dnoa_internal.DiscoveryResult(identifier, discoveryResult);
- window.dnoa_internal.discoveryResults[identifier] = discoveryResult;
-
- window.dnoa_internal.fireDiscoverySuccess(identifier, discoveryResult, { fresh: true });
-
- // Clear our "in discovery" state and fire callbacks
- var callbacks = window.dnoa_internal.discoveryInProgress[identifier];
- window.dnoa_internal.discoveryInProgress[identifier] = null;
-
- if (callbacks) {
- for (var i = 0; i < callbacks.onSuccess.length; i++) {
- if (callbacks.onSuccess[i]) {
- callbacks.onSuccess[i](discoveryResult);
- }
- }
- }
- }
-
- /// <summary>Receives the discovery failure notification.</summary>
- function discoverFailureCallback(message, userSuppliedIdentifier) {
- trace('Discovery failed for: ' + identifier);
-
- // Clear our "in discovery" state and fire callbacks
- var callbacks = window.dnoa_internal.discoveryInProgress[identifier];
- window.dnoa_internal.discoveryInProgress[identifier] = null;
-
- if (callbacks) {
- for (var i = 0; i < callbacks.onSuccess.length; i++) {
- if (callbacks.onFailure[i]) {
- callbacks.onFailure[i](message);
- }
- }
- }
-
- window.dnoa_internal.fireDiscoveryFailed(identifier, message);
- }
-
- if (window.dnoa_internal.discoveryResults[identifier]) {
- trace("We've already discovered " + identifier + " so we're using the cached version.");
-
- // In this special case, we never fire the DiscoveryStarted event.
- window.dnoa_internal.fireDiscoverySuccess(identifier, window.dnoa_internal.discoveryResults[identifier], { fresh: false });
-
- if (onDiscoverSuccess) {
- onDiscoverSuccess(window.dnoa_internal.discoveryResults[identifier]);
- }
-
- return;
- }
-
- window.dnoa_internal.fireDiscoveryStarted(identifier);
-
- if (!window.dnoa_internal.discoveryInProgress[identifier]) {
- trace('starting discovery on ' + identifier);
- window.dnoa_internal.discoveryInProgress[identifier] = {
- onSuccess: [onDiscoverSuccess],
- onFailure: [onDiscoverFailure]
- };
- window.dnoa_internal.callbackAsync(identifier, discoverSuccessCallback, discoverFailureCallback);
- } else {
- trace('Discovery on ' + identifier + ' already started. Registering an additional callback.');
- window.dnoa_internal.discoveryInProgress[identifier].onSuccess.push(onDiscoverSuccess);
- window.dnoa_internal.discoveryInProgress[identifier].onFailure.push(onDiscoverFailure);
- }
- };
-
- /// <summary>Performs discovery and immediately begins checkid_setup to authenticate the user using a given identifier.</summary>
- this.login = function(onSuccess, onLoginFailure) {
- this.discover(function(discoveryResult) {
- if (discoveryResult) {
- trace('Discovery succeeded and found ' + discoveryResult.length + ' OpenID service endpoints.');
- if (discoveryResult.length > 0) {
- discoveryResult[0].loginPopup(onSuccess, onLoginFailure);
- } else {
- trace("This doesn't look like an OpenID Identifier. Aborting login.");
- if (onLoginFailure) {
- onLoginFailure();
- }
- }
- }
- });
- };
-
- /// <summary>Performs discovery and immediately begins checkid_immediate on all discovered endpoints.</summary>
- this.loginBackground = function(frameManager, onLoginSuccess, onLoginFailure, timeout, onLoginLastFailure) {
- this.discover(function(discoveryResult) {
- if (discoveryResult) {
- trace('Discovery succeeded and found ' + discoveryResult.length + ' OpenID service endpoints.');
- if (discoveryResult.length > 0) {
- discoveryResult.loginBackground(frameManager, onLoginSuccess, onLoginFailure, onLoginLastFailure || onLoginFailure, timeout);
- } else {
- trace("This doesn't look like an OpenID Identifier. Aborting login.");
- if (onLoginFailure) {
- onLoginFailure();
- }
- }
- }
- });
- };
-
- this.toString = function() {
- return identifier;
- };
-};
-
-/// <summary>Invoked by RP web server when an authentication has completed.</summary>
-/// <remarks>The duty of this method is to distribute the notification to the appropriate tracking object.</remarks>
-window.dnoa_internal.processAuthorizationResult = function(resultUrl, extensionResponses) {
- //trace('processAuthorizationResult ' + resultUrl);
- var resultUri = new window.dnoa_internal.Uri(resultUrl);
- trace('processing auth result with extensionResponses: ' + extensionResponses);
- if (extensionResponses) {
- extensionResponses = eval(extensionResponses);
- }
-
- // Find the tracking object responsible for this request.
- var userSuppliedIdentifier = resultUri.getQueryArgValue('dnoa.userSuppliedIdentifier');
- if (!userSuppliedIdentifier) {
- throw 'processAuthorizationResult called but no userSuppliedIdentifier parameter was found. Exiting function.';
- }
- var discoveryResult = window.dnoa_internal.discoveryResults[userSuppliedIdentifier];
- if (!discoveryResult) {
- throw 'processAuthorizationResult called but no discovery result matching user supplied identifier ' + userSuppliedIdentifier + ' was found. Exiting function.';
- }
-
- var opEndpoint = resultUri.getQueryArgValue("openid.op_endpoint") ? resultUri.getQueryArgValue("openid.op_endpoint") : resultUri.getQueryArgValue("dnoa.op_endpoint");
- var respondingEndpoint = discoveryResult.findByEndpoint(opEndpoint);
- trace('Auth result for ' + respondingEndpoint.host + ' received.'); //: ' + resultUrl);
-
- if (window.dnoa_internal.isAuthSuccessful(resultUri)) {
- discoveryResult.successAuthData = resultUrl;
- respondingEndpoint.onAuthSuccess(resultUri, extensionResponses);
-
- var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(resultUri);
- if (parsedPositiveAssertion.claimedIdentifier && parsedPositiveAssertion.claimedIdentifier != discoveryResult.claimedIdentifier) {
- discoveryResult.claimedIdentifier = parsedPositiveAssertion.claimedIdentifier;
- trace('Authenticated as ' + parsedPositiveAssertion.claimedIdentifier);
- }
- } else {
- respondingEndpoint.onAuthFailed();
- }
-};
-
-window.dnoa_internal.isAuthSuccessful = function(resultUri) {
- if (window.dnoa_internal.isOpenID2Response(resultUri)) {
- return resultUri.getQueryArgValue("openid.mode") == "id_res";
- } else {
- return resultUri.getQueryArgValue("openid.mode") == "id_res" && !resultUri.containsQueryArg("openid.user_setup_url");
- }
-};
-
-window.dnoa_internal.isOpenID2Response = function(resultUri) {
- return resultUri.containsQueryArg("openid.ns");
-};
-
-/// <summary>Instantiates an object that stores discovery results of some identifier.</summary>
-window.dnoa_internal.DiscoveryResult = function(identifier, discoveryInfo) {
- var thisDiscoveryResult = this;
-
- /// <summary>
- /// Instantiates an object that describes an OpenID service endpoint and facilitates
- /// initiating and tracking an authentication request.
- /// </summary>
- function ServiceEndpoint(requestInfo, userSuppliedIdentifier) {
- this.immediate = requestInfo.immediate ? new window.dnoa_internal.Uri(requestInfo.immediate) : null;
- this.setup = requestInfo.setup ? new window.dnoa_internal.Uri(requestInfo.setup) : null;
- this.endpoint = new window.dnoa_internal.Uri(requestInfo.endpoint);
- this.host = this.endpoint.getHost();
- this.userSuppliedIdentifier = userSuppliedIdentifier;
- var thisServiceEndpoint = this; // closure so that delegates have the right instance
- this.loginPopup = function(onAuthSuccess, onAuthFailed) {
- thisServiceEndpoint.abort(); // ensure no concurrent attempts
- window.dnoa_internal.fireAuthStarted(thisDiscoveryResult, thisServiceEndpoint, { background: false });
- thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
- thisDiscoveryResult.onAuthFailed = onAuthFailed;
- var chromeHeight = 55; // estimated height of browser title bar and location bar
- var bottomMargin = 45; // estimated bottom space on screen likely to include a task bar
- var width = 1000;
- var height = 600;
- if (thisServiceEndpoint.setup.getQueryArgValue("openid.return_to").indexOf("dnoa.popupUISupported") >= 0) {
- trace('This OP supports the UI extension. Using smaller window size.');
- width = 500; // spec calls for 450px, but Yahoo needs 500px
- height = 500;
- } else {
- trace("This OP doesn't appear to support the UI extension. Using larger window size.");
- }
-
- var left = (screen.width - width) / 2;
- var top = (screen.height - bottomMargin - height - chromeHeight) / 2;
- thisServiceEndpoint.popup = window.open(thisServiceEndpoint.setup, 'opLogin', 'status=0,toolbar=0,location=1,resizable=1,scrollbars=1,left=' + left + ',top=' + top + ',width=' + width + ',height=' + height);
-
- // If the OP supports the UI extension it MAY close its own window
- // for a negative assertion. We must be able to recover from that scenario.
- var thisServiceEndpointLocal = thisServiceEndpoint;
- thisServiceEndpoint.popupCloseChecker = window.setInterval(function() {
- if (thisServiceEndpointLocal.popup) {
- try {
- if (thisServiceEndpointLocal.popup.closed) {
- // The window closed, either because the user closed it, canceled at the OP,
- // or approved at the OP and the popup window closed itself due to our script.
- // If we were graying out the entire page while the child window was up,
- // we would probably revert that here.
- window.clearInterval(thisServiceEndpointLocal.popupCloseChecker);
- thisServiceEndpointLocal.popup = null;
-
- // The popup may have managed to inform us of the result already,
- // so check whether the callback method was cleared already, which
- // would indicate we've already processed this.
- if (window.dnoa_internal.processAuthorizationResult) {
- trace('User or OP canceled by closing the window.');
- window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: false });
- if (thisDiscoveryResult.onAuthFailed) {
- thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
- }
- }
- }
- } catch (e) {
- // This usually happens because the popup is currently displaying the OP's
- // page from another domain, which makes the popup temporarily off limits to us.
- // Just skip this interval and wait for the next callback.
- }
- } else {
- // if there's no popup, there's no reason to keep this timer up.
- window.clearInterval(thisServiceEndpointLocal.popupCloseChecker);
- }
- }, 250);
- };
-
- this.loginBackgroundJob = function(iframe, timeout) {
- thisServiceEndpoint.abort(); // ensure no concurrent attempts
- if (timeout) {
- thisServiceEndpoint.timeout = setTimeout(function() { thisServiceEndpoint.onAuthenticationTimedOut(); }, timeout);
- }
- window.dnoa_internal.fireAuthStarted(thisDiscoveryResult, thisServiceEndpoint, { background: true });
- trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now OPENING (timeout ' + timeout + ').');
- //trace('initiating auth attempt with: ' + thisServiceEndpoint.immediate);
- thisServiceEndpoint.iframe = iframe;
- return {
- url: thisServiceEndpoint.immediate.toString(),
- onCanceled: function() {
- thisServiceEndpoint.abort();
- window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: true });
- }
- };
- };
-
- this.busy = function() {
- return thisServiceEndpoint.iframe || thisServiceEndpoint.popup;
- };
-
- this.completeAttempt = function(successful) {
- if (!thisServiceEndpoint.busy()) { return false; }
- window.clearInterval(thisServiceEndpoint.timeout);
- var background = thisServiceEndpoint.iframe !== null;
- if (thisServiceEndpoint.iframe) {
- trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now CLOSING.');
- thisDiscoveryResult.frameManager.closeFrame(thisServiceEndpoint.iframe);
- thisServiceEndpoint.iframe = null;
- }
- if (thisServiceEndpoint.popup) {
- thisServiceEndpoint.popup.close();
- thisServiceEndpoint.popup = null;
- }
- if (thisServiceEndpoint.timeout) {
- window.clearTimeout(thisServiceEndpoint.timeout);
- thisServiceEndpoint.timeout = null;
- }
-
- if (!successful && !thisDiscoveryResult.busy() && !thisDiscoveryResult.findSuccessfulRequest()) {
- // fire the failed event with NO service endpoint indicating the entire auth attempt has failed.
- window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, null, { background: background });
- if (thisDiscoveryResult.onLastAttemptFailed) {
- thisDiscoveryResult.onLastAttemptFailed(thisDiscoveryResult);
- }
- }
-
- return true;
- };
-
- this.onAuthenticationTimedOut = function() {
- var background = thisServiceEndpoint.iframe !== null;
- if (thisServiceEndpoint.completeAttempt()) {
- trace(thisServiceEndpoint.host + " timed out");
- thisServiceEndpoint.result = window.dnoa_internal.timedOut;
- }
- window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: background });
- };
-
- this.onAuthSuccess = function(authUri, extensionResponses) {
- var background = thisServiceEndpoint.iframe !== null;
- if (thisServiceEndpoint.completeAttempt(true)) {
- trace(thisServiceEndpoint.host + " authenticated!");
- thisServiceEndpoint.result = window.dnoa_internal.authSuccess;
- thisServiceEndpoint.successReceived = new Date();
- thisServiceEndpoint.claimedIdentifier = authUri.getQueryArgValue('openid.claimed_id');
- thisServiceEndpoint.response = authUri;
- thisServiceEndpoint.extensionResponses = extensionResponses;
- thisDiscoveryResult.abortAll();
- if (thisDiscoveryResult.onAuthSuccess) {
- thisDiscoveryResult.onAuthSuccess(thisDiscoveryResult, thisServiceEndpoint, extensionResponses);
- }
- window.dnoa_internal.fireAuthSuccess(thisDiscoveryResult, thisServiceEndpoint, extensionResponses, { background: background });
- }
- };
-
- this.onAuthFailed = function() {
- var background = thisServiceEndpoint.iframe !== null;
- if (thisServiceEndpoint.completeAttempt()) {
- trace(thisServiceEndpoint.host + " failed authentication");
- thisServiceEndpoint.result = window.dnoa_internal.authRefused;
- window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: background });
- if (thisDiscoveryResult.onAuthFailed) {
- thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
- }
- }
- };
-
- this.abort = function() {
- if (thisServiceEndpoint.completeAttempt()) {
- trace(thisServiceEndpoint.host + " aborted");
- // leave the result as whatever it was before.
- }
- };
-
- this.clear = function() {
- thisServiceEndpoint.result = null;
- thisServiceEndpoint.extensionResponses = null;
- thisServiceEndpoint.successReceived = null;
- thisServiceEndpoint.claimedIdentifier = null;
- thisServiceEndpoint.response = null;
- if (this.onCleared) {
- this.onCleared(thisServiceEndpoint, thisDiscoveryResult);
- }
- if (thisDiscoveryResult.onCleared) {
- thisDiscoveryResult.onCleared(thisDiscoveryResult, thisServiceEndpoint);
- }
- window.dnoa_internal.fireAuthCleared(thisDiscoveryResult, thisServiceEndpoint);
- };
-
- this.toString = function() {
- return "[ServiceEndpoint: " + thisServiceEndpoint.host + "]";
- };
- }
-
- this.cloneWithOneServiceEndpoint = function(serviceEndpoint) {
- var clone = window.dnoa_internal.clone(this);
- clone.userSuppliedIdentifier = serviceEndpoint.claimedIdentifier;
-
- // Erase all SEPs except the given one, and put it into first position.
- clone.length = 1;
- for (var i = 0; i < this.length; i++) {
- if (clone[i].endpoint.toString() == serviceEndpoint.endpoint.toString()) {
- var tmp = clone[i];
- clone[i] = null;
- clone[0] = tmp;
- } else {
- clone[i] = null;
- }
- }
-
- return clone;
- };
-
- this.userSuppliedIdentifier = identifier;
- this.error = discoveryInfo.error;
-
- if (discoveryInfo) {
- this.claimedIdentifier = discoveryInfo.claimedIdentifier; // The claimed identifier may be null if the user provided an OP Identifier.
- this.length = discoveryInfo.requests.length;
- for (var i = 0; i < discoveryInfo.requests.length; i++) {
- this[i] = new ServiceEndpoint(discoveryInfo.requests[i], identifier);
- }
- } else {
- this.length = 0;
- }
-
- if (this.length === 0) {
- trace('Discovery completed, but yielded no service endpoints.');
- } else {
- trace('Discovered claimed identifier: ' + (this.claimedIdentifier ? this.claimedIdentifier : "(directed identity)"));
- }
-
- // Add extra tracking bits and behaviors.
- this.findByEndpoint = function(opEndpoint) {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- if (thisDiscoveryResult[i].endpoint == opEndpoint) {
- return thisDiscoveryResult[i];
- }
- }
- };
-
- this.busy = function() {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- if (thisDiscoveryResult[i].busy()) {
- return true;
- }
- }
- };
-
- // Add extra tracking bits and behaviors.
- this.findSuccessfulRequest = function() {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- if (thisDiscoveryResult[i].result === window.dnoa_internal.authSuccess) {
- return thisDiscoveryResult[i];
- }
- }
- };
-
- this.abortAll = function() {
- if (thisDiscoveryResult.frameManager) {
- // Abort all other asynchronous authentication attempts that may be in progress
- // for this particular claimed identifier.
- thisDiscoveryResult.frameManager.cancelAllWork();
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- thisDiscoveryResult[i].abort();
- }
- } else {
- trace('abortAll called without a frameManager being previously set.');
- }
- };
-
- /// <summary>Initiates an asynchronous checkid_immediate login attempt against all possible service endpoints for an Identifier.</summary>
- /// <param name="frameManager">The work queue for authentication iframes.</param>
- /// <param name="onAuthSuccess">Fired when an endpoint responds affirmatively.</param>
- /// <param name="onAuthFailed">Fired when an endpoint responds negatively.</param>
- /// <param name="onLastAuthFailed">Fired when all authentication attempts have responded negatively or timed out.</param>
- /// <param name="timeout">Timeout for an individual service endpoint to respond before the iframe closes.</param>
- this.loginBackground = function(frameManager, onAuthSuccess, onAuthFailed, onLastAuthFailed, timeout) {
- if (!frameManager) {
- throw "No frameManager specified.";
- }
- var priorSuccessRespondingEndpoint = thisDiscoveryResult.findSuccessfulRequest();
- if (priorSuccessRespondingEndpoint) {
- // In this particular case, we do not fire an AuthStarted event.
- window.dnoa_internal.fireAuthSuccess(thisDiscoveryResult, priorSuccessRespondingEndpoint, priorSuccessRespondingEndpoint.extensionResponses, { background: true });
- if (onAuthSuccess) {
- onAuthSuccess(thisDiscoveryResult, priorSuccessRespondingEndpoint);
- }
- } else {
- if (thisDiscoveryResult.busy()) {
- trace('Warning: DiscoveryResult.loginBackground invoked while a login attempt is already in progress. Discarding second login request.', 'red');
- return;
- }
- thisDiscoveryResult.frameManager = frameManager;
- thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
- thisDiscoveryResult.onAuthFailed = onAuthFailed;
- thisDiscoveryResult.onLastAttemptFailed = onLastAuthFailed;
- // Notify listeners that general authentication is beginning. Individual ServiceEndpoints
- // will fire their own events as each of them begin their iframe 'job'.
- window.dnoa_internal.fireAuthStarted(thisDiscoveryResult, null, { background: true });
- if (thisDiscoveryResult.length > 0) {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- thisDiscoveryResult.frameManager.enqueueWork(thisDiscoveryResult[i].loginBackgroundJob, timeout);
- }
- }
- }
- };
-
- this.toString = function() {
- return "[DiscoveryResult: " + thisDiscoveryResult.userSuppliedIdentifier + "]";
- };
-};
-
-/// <summary>
-/// Called in a page had an AJAX control that had already obtained a positive assertion
-/// when a postback occurred, and now that control wants to restore its 'authenticated' state.
-/// </summary>
-/// <param name="positiveAssertion">The string form of the URI that contains the positive assertion.</param>
-window.dnoa_internal.deserializePreviousAuthentication = function(positiveAssertion) {
- if (!positiveAssertion || positiveAssertion.length === 0) {
- return;
- }
-
- trace('Revitalizing an old positive assertion from a prior postback.');
-
- // The control ensures that we ALWAYS have an OpenID 2.0-style claimed_id attribute, even against
- // 1.0 Providers via the return_to URL mechanism.
- var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(positiveAssertion);
-
- // We weren't given a full discovery history, but we can spoof this much from the
- // authentication assertion.
- trace('Deserialized claimed_id: ' + parsedPositiveAssertion.claimedIdentifier + ' and endpoint: ' + parsedPositiveAssertion.endpoint);
- var discoveryInfo = {
- claimedIdentifier: parsedPositiveAssertion.claimedIdentifier,
- requests: [{ endpoint: parsedPositiveAssertion.endpoint}]
- };
-
- discoveryResult = new window.dnoa_internal.DiscoveryResult(parsedPositiveAssertion.userSuppliedIdentifier, discoveryInfo);
- window.dnoa_internal.discoveryResults[parsedPositiveAssertion.userSuppliedIdentifier] = discoveryResult;
- discoveryResult[0].result = window.dnoa_internal.authSuccess;
- discoveryResult.successAuthData = positiveAssertion;
-
- // restore old state from before postback
- window.dnoa_internal.fireAuthSuccess(discoveryResult, discoveryResult[0], null, { background: true, deserialized: true });
-};
-
-window.dnoa_internal.PositiveAssertion = function(uri) {
- uri = new window.dnoa_internal.Uri(uri.toString());
- this.endpoint = new window.dnoa_internal.Uri(uri.getQueryArgValue("dnoa.op_endpoint"));
- this.userSuppliedIdentifier = uri.getQueryArgValue('dnoa.userSuppliedIdentifier');
- this.claimedIdentifier = uri.getQueryArgValue('openid.claimed_id');
- if (!this.claimedIdentifier) {
- this.claimedIdentifier = uri.getQueryArgValue('dnoa.claimed_id');
- }
- this.toString = function() { return uri.toString(); };
-};
-
-window.dnoa_internal.clone = function(obj) {
- if (obj === null || typeof (obj) != 'object' || !isNaN(obj)) { // !isNaN catches Date objects
- return obj;
- }
-
- var temp = {};
- for (var key in obj) {
- temp[key] = window.dnoa_internal.clone(obj[key]);
- }
-
- // Copy over some built-in methods that were not included in the above loop,
- // but nevertheless may have been overridden.
- temp.toString = window.dnoa_internal.clone(obj.toString);
-
- return temp;
-};
-
-// Deserialized the preloaded discovery results
-window.dnoa_internal.loadPreloadedDiscoveryResults = function(preloadedDiscoveryResults) {
- trace('found ' + preloadedDiscoveryResults.length + ' preloaded discovery results.');
- for (var i = 0; i < preloadedDiscoveryResults.length; i++) {
- var result = preloadedDiscoveryResults[i];
- if (!window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier]) {
- window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier] = new window.dnoa_internal.DiscoveryResult(result.userSuppliedIdentifier, result.discoveryResult);
- trace('Preloaded discovery on: ' + window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier].userSuppliedIdentifier);
- } else {
- trace('Skipped preloaded discovery on: ' + window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier].userSuppliedIdentifier + ' because we have a cached discovery result on it.');
- }
- }
-};
-
-window.dnoa_internal.clearExpiredPositiveAssertions = function() {
- for (identifier in window.dnoa_internal.discoveryResults) {
- var discoveryResult = window.dnoa_internal.discoveryResults[identifier];
- if (typeof (discoveryResult) != 'object') { continue; } // skip functions
- for (var i = 0; i < discoveryResult.length; i++) {
- if (discoveryResult[i] && discoveryResult[i].result === window.dnoa_internal.authSuccess) {
- if (new Date() - discoveryResult[i].successReceived > window.dnoa_internal.maxPositiveAssertionLifetime) {
- // This positive assertion is too old, and may eventually be rejected by DNOA during verification.
- // Let's clear out the positive assertion so it can be renewed.
- trace('Clearing out expired positive assertion from ' + discoveryResult[i].host);
- discoveryResult[i].clear();
- }
- }
- }
- }
-};
-
-window.setInterval(window.dnoa_internal.clearExpiredPositiveAssertions, 1000);
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
deleted file mode 100644
index 16ea839..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
+++ /dev/null
@@ -1,1054 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdRelyingPartyControlBase.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.EmbeddedJavascriptResource, "text/javascript")]
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Drawing.Design;
- using System.Globalization;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using DotNetOpenAuth.ComponentModel;
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.Extensions;
- using DotNetOpenAuth.OpenId.Extensions.UI;
- using DotNetOpenAuth.OpenId.Messages;
-
- /// <summary>
- /// Methods of indicating to the rest of the web site that the user has logged in.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "OnSite", Justification = "Two words intended.")]
- public enum LogOnSiteNotification {
- /// <summary>
- /// The rest of the web site is unaware that the user just completed an OpenID login.
- /// </summary>
- None,
-
- /// <summary>
- /// After the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event is fired
- /// the control automatically calls <see cref="System.Web.Security.FormsAuthentication.RedirectFromLoginPage(string, bool)"/>
- /// with the <see cref="IAuthenticationResponse.ClaimedIdentifier"/> as the username
- /// unless the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event handler sets
- /// <see cref="OpenIdEventArgs.Cancel"/> property to true.
- /// </summary>
- FormsAuthentication,
- }
-
- /// <summary>
- /// How an OpenID user session should be persisted across visits.
- /// </summary>
- public enum LogOnPersistence {
- /// <summary>
- /// The user should only be logged in as long as the browser window remains open.
- /// Nothing is persisted to help the user on a return visit. Public kiosk mode.
- /// </summary>
- Session,
-
- /// <summary>
- /// The user should only be logged in as long as the browser window remains open.
- /// The OpenID Identifier is persisted to help expedite re-authentication when
- /// the user visits the next time.
- /// </summary>
- SessionAndPersistentIdentifier,
-
- /// <summary>
- /// The user is issued a persistent authentication ticket so that no login is
- /// necessary on their return visit.
- /// </summary>
- PersistentAuthentication,
- }
-
- /// <summary>
- /// A common base class for OpenID Relying Party controls.
- /// </summary>
- [DefaultProperty("Identifier"), ValidationProperty("Identifier")]
- [ParseChildren(true), PersistChildren(false)]
- public abstract class OpenIdRelyingPartyControlBase : Control, IPostBackEventHandler, IDisposable {
- /// <summary>
- /// The manifest resource name of the javascript file to include on the hosting page.
- /// </summary>
- internal const string EmbeddedJavascriptResource = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdRelyingPartyControlBase.js";
-
- /// <summary>
- /// The cookie used to persist the Identifier the user logged in with.
- /// </summary>
- internal const string PersistentIdentifierCookieName = OpenIdUtilities.CustomParameterPrefix + "OpenIDIdentifier";
-
- /// <summary>
- /// The callback parameter name to use to store which control initiated the auth request.
- /// </summary>
- internal const string ReturnToReceivingControlId = OpenIdUtilities.CustomParameterPrefix + "receiver";
-
- #region Protected internal callback parameter names
-
- /// <summary>
- /// The callback parameter to use for recognizing when the callback is in a popup window or hidden iframe.
- /// </summary>
- protected internal const string UIPopupCallbackKey = OpenIdUtilities.CustomParameterPrefix + "uipopup";
-
- /// <summary>
- /// The parameter name to include in the formulated auth request so that javascript can know whether
- /// the OP advertises support for the UI extension.
- /// </summary>
- protected internal const string PopupUISupportedJSHint = OpenIdUtilities.CustomParameterPrefix + "popupUISupported";
-
- #endregion
-
- #region Property category constants
-
- /// <summary>
- /// The "Appearance" category for properties.
- /// </summary>
- protected const string AppearanceCategory = "Appearance";
-
- /// <summary>
- /// The "Behavior" category for properties.
- /// </summary>
- protected const string BehaviorCategory = "Behavior";
-
- /// <summary>
- /// The "OpenID" category for properties and events.
- /// </summary>
- protected const string OpenIdCategory = "OpenID";
-
- #endregion
-
- #region Private callback parameter names
-
- /// <summary>
- /// The callback parameter for use with persisting the <see cref="UsePersistentCookie"/> property.
- /// </summary>
- private const string UsePersistentCookieCallbackKey = OpenIdUtilities.CustomParameterPrefix + "UsePersistentCookie";
-
- /// <summary>
- /// The callback parameter to use for recognizing when the callback is in the parent window.
- /// </summary>
- private const string UIPopupCallbackParentKey = OpenIdUtilities.CustomParameterPrefix + "uipopupParent";
-
- #endregion
-
- #region Property default values
-
- /// <summary>
- /// The default value for the <see cref="Stateless"/> property.
- /// </summary>
- private const bool StatelessDefault = false;
-
- /// <summary>
- /// The default value for the <see cref="ReturnToUrl"/> property.
- /// </summary>
- private const string ReturnToUrlDefault = "";
-
- /// <summary>
- /// Default value of <see cref="UsePersistentCookie"/>.
- /// </summary>
- private const LogOnPersistence UsePersistentCookieDefault = LogOnPersistence.Session;
-
- /// <summary>
- /// Default value of <see cref="LogOnMode"/>.
- /// </summary>
- private const LogOnSiteNotification LogOnModeDefault = LogOnSiteNotification.FormsAuthentication;
-
- /// <summary>
- /// The default value for the <see cref="RealmUrl"/> property.
- /// </summary>
- private const string RealmUrlDefault = "~/";
-
- /// <summary>
- /// The default value for the <see cref="Popup"/> property.
- /// </summary>
- private const PopupBehavior PopupDefault = PopupBehavior.Never;
-
- /// <summary>
- /// The default value for the <see cref="RequireSsl"/> property.
- /// </summary>
- private const bool RequireSslDefault = false;
-
- #endregion
-
- #region Property view state keys
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Extensions"/> property.
- /// </summary>
- private const string ExtensionsViewStateKey = "Extensions";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Stateless"/> property.
- /// </summary>
- private const string StatelessViewStateKey = "Stateless";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="UsePersistentCookie"/> property.
- /// </summary>
- private const string UsePersistentCookieViewStateKey = "UsePersistentCookie";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="LogOnMode"/> property.
- /// </summary>
- private const string LogOnModeViewStateKey = "LogOnMode";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RealmUrl"/> property.
- /// </summary>
- private const string RealmUrlViewStateKey = "RealmUrl";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="ReturnToUrl"/> property.
- /// </summary>
- private const string ReturnToUrlViewStateKey = "ReturnToUrl";
-
- /// <summary>
- /// The key under which the value for the <see cref="Identifier"/> property will be stored.
- /// </summary>
- private const string IdentifierViewStateKey = "Identifier";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Popup"/> property.
- /// </summary>
- private const string PopupViewStateKey = "Popup";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequireSsl"/> property.
- /// </summary>
- private const string RequireSslViewStateKey = "RequireSsl";
-
- #endregion
-
- /// <summary>
- /// The lifetime of the cookie used to persist the Identifier the user logged in with.
- /// </summary>
- private static readonly TimeSpan PersistentIdentifierTimeToLiveDefault = TimeSpan.FromDays(14);
-
- /// <summary>
- /// Backing field for the <see cref="RelyingParty"/> property.
- /// </summary>
- private OpenIdRelyingParty relyingParty;
-
- /// <summary>
- /// A value indicating whether the <see cref="relyingParty"/> field contains
- /// an instance that we own and should Dispose.
- /// </summary>
- private bool relyingPartyOwned;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdRelyingPartyControlBase"/> class.
- /// </summary>
- protected OpenIdRelyingPartyControlBase() {
- Reporting.RecordFeatureUse(this);
- }
-
- #region Events
-
- /// <summary>
- /// Fired when the user has typed in their identifier, discovery was successful
- /// and a login attempt is about to begin.
- /// </summary>
- [Description("Fired when the user has typed in their identifier, discovery was successful and a login attempt is about to begin."), Category(OpenIdCategory)]
- public event EventHandler<OpenIdEventArgs> LoggingIn;
-
- /// <summary>
- /// Fired upon completion of a successful login.
- /// </summary>
- [Description("Fired upon completion of a successful login."), Category(OpenIdCategory)]
- public event EventHandler<OpenIdEventArgs> LoggedIn;
-
- /// <summary>
- /// Fired when a login attempt fails.
- /// </summary>
- [Description("Fired when a login attempt fails."), Category(OpenIdCategory)]
- public event EventHandler<OpenIdEventArgs> Failed;
-
- /// <summary>
- /// Fired when an authentication attempt is canceled at the OpenID Provider.
- /// </summary>
- [Description("Fired when an authentication attempt is canceled at the OpenID Provider."), Category(OpenIdCategory)]
- public event EventHandler<OpenIdEventArgs> Canceled;
-
- /// <summary>
- /// Occurs when the <see cref="Identifier"/> property is changed.
- /// </summary>
- protected event EventHandler IdentifierChanged;
-
- #endregion
-
- /// <summary>
- /// Gets or sets the <see cref="OpenIdRelyingParty"/> instance to use.
- /// </summary>
- /// <value>The default value is an <see cref="OpenIdRelyingParty"/> instance initialized according to the web.config file.</value>
- /// <remarks>
- /// A performance optimization would be to store off the
- /// instance as a static member in your web site and set it
- /// to this property in your <see cref="Control.Load">Page.Load</see>
- /// event since instantiating these instances can be expensive on
- /// heavily trafficked web pages.
- /// </remarks>
- [Browsable(false)]
- public virtual OpenIdRelyingParty RelyingParty {
- get {
- if (this.relyingParty == null) {
- this.relyingParty = this.CreateRelyingParty();
- this.ConfigureRelyingParty(this.relyingParty);
- this.relyingPartyOwned = true;
- }
- return this.relyingParty;
- }
-
- set {
- if (this.relyingPartyOwned && this.relyingParty != null) {
- this.relyingParty.Dispose();
- }
-
- this.relyingParty = value;
- this.relyingPartyOwned = false;
- }
- }
-
- /// <summary>
- /// Gets the collection of extension requests this selector should include in generated requests.
- /// </summary>
- [PersistenceMode(PersistenceMode.InnerProperty)]
- public Collection<IOpenIdMessageExtension> Extensions {
- get {
- if (this.ViewState[ExtensionsViewStateKey] == null) {
- var extensions = new Collection<IOpenIdMessageExtension>();
- this.ViewState[ExtensionsViewStateKey] = extensions;
- return extensions;
- } else {
- return (Collection<IOpenIdMessageExtension>)this.ViewState[ExtensionsViewStateKey];
- }
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether stateless mode is used.
- /// </summary>
- [Bindable(true), DefaultValue(StatelessDefault), Category(OpenIdCategory)]
- [Description("Controls whether stateless mode is used.")]
- public bool Stateless {
- get { return (bool)(ViewState[StatelessViewStateKey] ?? StatelessDefault); }
- set { ViewState[StatelessViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the OpenID <see cref="Realm"/> of the relying party web site.
- /// </summary>
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "DotNetOpenAuth.OpenId.Realm", Justification = "Using ctor for validation.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(RealmUrlDefault), Category(OpenIdCategory)]
- [Description("The OpenID Realm of the relying party web site.")]
- [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- public string RealmUrl {
- get {
- return (string)(ViewState[RealmUrlViewStateKey] ?? RealmUrlDefault);
- }
-
- set {
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(value));
-
- if (Page != null && !DesignMode) {
- // Validate new value by trying to construct a Realm object based on it.
- new Realm(OpenIdUtilities.GetResolvedRealm(this.Page, value, this.RelyingParty.Channel.GetRequestFromContext())); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value.Replace("*.", string.Empty)); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
- }
- ViewState[RealmUrlViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the OpenID ReturnTo of the relying party web site.
- /// </summary>
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Bindable property must be simple type")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(ReturnToUrlDefault), Category(OpenIdCategory)]
- [Description("The OpenID ReturnTo of the relying party web site.")]
- [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- public string ReturnToUrl {
- get {
- return (string)(this.ViewState[ReturnToUrlViewStateKey] ?? ReturnToUrlDefault);
- }
-
- set {
- if (this.Page != null && !this.DesignMode) {
- // Validate new value by trying to construct a Uri based on it.
- new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.Page.ResolveUrl(value)); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
- }
-
- this.ViewState[ReturnToUrlViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to send a persistent cookie upon successful
- /// login so the user does not have to log in upon returning to this site.
- /// </summary>
- [Bindable(true), DefaultValue(UsePersistentCookieDefault), Category(BehaviorCategory)]
- [Description("Whether to send a persistent cookie upon successful " +
- "login so the user does not have to log in upon returning to this site.")]
- public virtual LogOnPersistence UsePersistentCookie {
- get { return (LogOnPersistence)(this.ViewState[UsePersistentCookieViewStateKey] ?? UsePersistentCookieDefault); }
- set { this.ViewState[UsePersistentCookieViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the way a completed login is communicated to the rest of the web site.
- /// </summary>
- [Bindable(true), DefaultValue(LogOnModeDefault), Category(BehaviorCategory)]
- [Description("The way a completed login is communicated to the rest of the web site.")]
- public virtual LogOnSiteNotification LogOnMode {
- get { return (LogOnSiteNotification)(this.ViewState[LogOnModeViewStateKey] ?? LogOnModeDefault); }
- set { this.ViewState[LogOnModeViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating when to use a popup window to complete the login experience.
- /// </summary>
- /// <value>The default value is <see cref="PopupBehavior.Never"/>.</value>
- [Bindable(true), DefaultValue(PopupDefault), Category(BehaviorCategory)]
- [Description("When to use a popup window to complete the login experience.")]
- public virtual PopupBehavior Popup {
- get { return (PopupBehavior)(ViewState[PopupViewStateKey] ?? PopupDefault); }
- set { ViewState[PopupViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to enforce on high security mode,
- /// which requires the full authentication pipeline to be protected by SSL.
- /// </summary>
- [Bindable(true), DefaultValue(RequireSslDefault), Category(OpenIdCategory)]
- [Description("Turns on high security mode, requiring the full authentication pipeline to be protected by SSL.")]
- public bool RequireSsl {
- get { return (bool)(ViewState[RequireSslViewStateKey] ?? RequireSslDefault); }
- set { ViewState[RequireSslViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the Identifier that will be used to initiate login.
- /// </summary>
- [Bindable(true), Category(OpenIdCategory)]
- [Description("The OpenID Identifier that this button will use to initiate login.")]
- [TypeConverter(typeof(IdentifierConverter))]
- public virtual Identifier Identifier {
- get {
- return (Identifier)ViewState[IdentifierViewStateKey];
- }
-
- set {
- ViewState[IdentifierViewStateKey] = value;
- this.OnIdentifierChanged();
- }
- }
-
- /// <summary>
- /// Gets or sets the default association preference to set on authentication requests.
- /// </summary>
- internal AssociationPreference AssociationPreference { get; set; }
-
- /// <summary>
- /// Gets ancestor controls, starting with the immediate parent, and progressing to more distant ancestors.
- /// </summary>
- protected IEnumerable<Control> ParentControls {
- get {
- Control parent = this;
- while ((parent = parent.Parent) != null) {
- yield return parent;
- }
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this control is a child control of a composite OpenID control.
- /// </summary>
- /// <value>
- /// <c>true</c> if this instance is embedded in parent OpenID control; otherwise, <c>false</c>.
- /// </value>
- protected bool IsEmbeddedInParentOpenIdControl {
- get { return this.ParentControls.OfType<OpenIdRelyingPartyControlBase>().Any(); }
- }
-
- /// <summary>
- /// Clears any cookie set by this control to help the user on a returning visit next time.
- /// </summary>
- public static void LogOff() {
- HttpContext.Current.Response.SetCookie(CreateIdentifierPersistingCookie(null));
- }
-
- /// <summary>
- /// Immediately redirects to the OpenID Provider to verify the Identifier
- /// provided in the text box.
- /// </summary>
- public void LogOn() {
- IAuthenticationRequest request = this.CreateRequests().FirstOrDefault();
- ErrorUtilities.VerifyProtocol(request != null, OpenIdStrings.OpenIdEndpointNotFound);
- this.LogOn(request);
- }
-
- /// <summary>
- /// Immediately redirects to the OpenID Provider to verify the Identifier
- /// provided in the text box.
- /// </summary>
- /// <param name="request">The request.</param>
- public void LogOn(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- if (this.IsPopupAppropriate(request)) {
- this.ScriptPopupWindow(request);
- } else {
- request.RedirectToProvider();
- }
- }
-
- #region IPostBackEventHandler Members
-
- /// <summary>
- /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
- /// </summary>
- /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
- void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
- this.RaisePostBackEvent(eventArgument);
- }
-
- #endregion
-
- /// <summary>
- /// Enables a server control to perform final clean up before it is released from memory.
- /// </summary>
- [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Unavoidable because base class does not expose a protected virtual Dispose(bool) method."), SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Base class doesn't implement virtual Dispose(bool), so we must call its Dispose() method.")]
- public sealed override void Dispose() {
- this.Dispose(true);
- base.Dispose();
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Creates the authentication requests for a given user-supplied Identifier.
- /// </summary>
- /// <param name="identifier">The identifier to create a request for.</param>
- /// <returns>
- /// A sequence of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
- /// </returns>
- protected internal virtual IEnumerable<IAuthenticationRequest> CreateRequests(Identifier identifier) {
- Contract.Requires<ArgumentNullException>(identifier != null);
-
- // If this control is actually a member of another OpenID RP control,
- // delegate creation of requests to the parent control.
- var parentOwner = this.ParentControls.OfType<OpenIdRelyingPartyControlBase>().FirstOrDefault();
- if (parentOwner != null) {
- return parentOwner.CreateRequests(identifier);
- } else {
- // Delegate to a private method to keep 'yield return' and Code Contract separate.
- return this.CreateRequestsCore(identifier);
- }
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources
- /// </summary>
- /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool disposing) {
- if (disposing) {
- if (this.relyingPartyOwned && this.relyingParty != null) {
- this.relyingParty.Dispose();
- this.relyingParty = null;
- }
- }
- }
-
- /// <summary>
- /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
- /// </summary>
- /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
- [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Predefined signature.")]
- protected virtual void RaisePostBackEvent(string eventArgument) {
- }
-
- /// <summary>
- /// Creates the authentication requests for the value set in the <see cref="Identifier"/> property.
- /// </summary>
- /// <returns>
- /// A sequence of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
- /// </returns>
- protected IEnumerable<IAuthenticationRequest> CreateRequests() {
- Contract.Requires<InvalidOperationException>(this.Identifier != null, OpenIdStrings.NoIdentifierSet);
- return this.CreateRequests(this.Identifier);
- }
-
- /// <summary>
- /// Raises the <see cref="E:Load"/> event.
- /// </summary>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- protected override void OnLoad(EventArgs e) {
- base.OnLoad(e);
-
- if (Page.IsPostBack) {
- // OpenID responses NEVER come in the form of a postback.
- return;
- }
-
- if (this.Identifier == null) {
- this.TryPresetIdentifierWithCookie();
- }
-
- // Take an unreliable sneek peek to see if we're in a popup and an OpenID
- // assertion is coming in. We shouldn't process assertions in a popup window.
- if (this.Page.Request.QueryString[UIPopupCallbackKey] == "1" && this.Page.Request.QueryString[UIPopupCallbackParentKey] == null) {
- // We're in a popup window. We need to close it and pass the
- // message back to the parent window for processing.
- this.ScriptClosingPopupOrIFrame();
- return; // don't do any more processing on it now
- }
-
- // Only sniff for an OpenID response if it is targeted at this control.
- // Note that Stateless mode causes no receiver to be indicated, and
- // we want to handle that, but only if there isn't a parent control that
- // will be handling that.
- string receiver = this.Page.Request.QueryString[ReturnToReceivingControlId] ?? this.Page.Request.Form[ReturnToReceivingControlId];
- if (receiver == this.ClientID || (receiver == null && !this.IsEmbeddedInParentOpenIdControl)) {
- var response = this.RelyingParty.GetResponse();
- Logger.Controls.DebugFormat(
- "The {0} control checked for an authentication response and found: {1}",
- this.ID,
- response != null ? response.Status.ToString() : "nothing");
- this.ProcessResponse(response);
- }
- }
-
- /// <summary>
- /// Notifies the user agent via an AJAX response of a completed authentication attempt.
- /// </summary>
- protected virtual void ScriptClosingPopupOrIFrame() {
- this.RelyingParty.ProcessResponseFromPopup();
- }
-
- /// <summary>
- /// Called when the <see cref="Identifier"/> property is changed.
- /// </summary>
- protected virtual void OnIdentifierChanged() {
- var identifierChanged = this.IdentifierChanged;
- if (identifierChanged != null) {
- identifierChanged(this, EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Processes the response.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void ProcessResponse(IAuthenticationResponse response) {
- if (response == null) {
- return;
- }
- string persistentString = response.GetUntrustedCallbackArgument(UsePersistentCookieCallbackKey);
- if (persistentString != null) {
- this.UsePersistentCookie = (LogOnPersistence)Enum.Parse(typeof(LogOnPersistence), persistentString);
- }
-
- switch (response.Status) {
- case AuthenticationStatus.Authenticated:
- this.OnLoggedIn(response);
- break;
- case AuthenticationStatus.Canceled:
- this.OnCanceled(response);
- break;
- case AuthenticationStatus.Failed:
- this.OnFailed(response);
- break;
- case AuthenticationStatus.SetupRequired:
- case AuthenticationStatus.ExtensionsOnly:
- default:
- // The NotApplicable (extension-only assertion) is NOT one that we support
- // in this control because that scenario is primarily interesting to RPs
- // that are asking a specific OP, and it is not user-initiated as this textbox
- // is designed for.
- throw new InvalidOperationException(MessagingStrings.UnexpectedMessageReceivedOfMany);
- }
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
-
- this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdRelyingPartyControlBase), EmbeddedJavascriptResource);
- }
-
- /// <summary>
- /// Fires the <see cref="LoggedIn"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnLoggedIn(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
- Contract.Requires<ArgumentException>(response.Status == AuthenticationStatus.Authenticated);
-
- var loggedIn = this.LoggedIn;
- OpenIdEventArgs args = new OpenIdEventArgs(response);
- if (loggedIn != null) {
- loggedIn(this, args);
- }
-
- if (!args.Cancel) {
- if (this.UsePersistentCookie == LogOnPersistence.SessionAndPersistentIdentifier) {
- Page.Response.SetCookie(CreateIdentifierPersistingCookie(response));
- }
-
- switch (this.LogOnMode) {
- case LogOnSiteNotification.FormsAuthentication:
- FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie == LogOnPersistence.PersistentAuthentication);
- break;
- case LogOnSiteNotification.None:
- default:
- break;
- }
- }
- }
-
- /// <summary>
- /// Fires the <see cref="LoggingIn"/> event.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>
- /// Returns whether the login should proceed. False if some event handler canceled the request.
- /// </returns>
- protected virtual bool OnLoggingIn(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- EventHandler<OpenIdEventArgs> loggingIn = this.LoggingIn;
-
- OpenIdEventArgs args = new OpenIdEventArgs(request);
- if (loggingIn != null) {
- loggingIn(this, args);
- }
-
- return !args.Cancel;
- }
-
- /// <summary>
- /// Fires the <see cref="Canceled"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnCanceled(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
- Contract.Requires<ArgumentException>(response.Status == AuthenticationStatus.Canceled);
-
- var canceled = this.Canceled;
- if (canceled != null) {
- canceled(this, new OpenIdEventArgs(response));
- }
- }
-
- /// <summary>
- /// Fires the <see cref="Failed"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnFailed(IAuthenticationResponse response) {
- Contract.Requires<ArgumentNullException>(response != null);
- Contract.Requires<ArgumentException>(response.Status == AuthenticationStatus.Failed);
-
- var failed = this.Failed;
- if (failed != null) {
- failed(this, new OpenIdEventArgs(response));
- }
- }
-
- /// <summary>
- /// Creates the relying party instance used to generate authentication requests.
- /// </summary>
- /// <returns>The instantiated relying party.</returns>
- protected OpenIdRelyingParty CreateRelyingParty() {
- IOpenIdApplicationStore store = this.Stateless ? null : OpenIdElement.Configuration.RelyingParty.ApplicationStore.CreateInstance(OpenIdRelyingParty.HttpApplicationStore);
- return this.CreateRelyingParty(store);
- }
-
- /// <summary>
- /// Creates the relying party instance used to generate authentication requests.
- /// </summary>
- /// <param name="store">The store to pass to the relying party constructor.</param>
- /// <returns>The instantiated relying party.</returns>
- protected virtual OpenIdRelyingParty CreateRelyingParty(IOpenIdApplicationStore store) {
- return new OpenIdRelyingParty(store);
- }
-
- /// <summary>
- /// Configures the relying party.
- /// </summary>
- /// <param name="relyingParty">The relying party.</param>
- [SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "relyingParty", Justification = "This makes it possible for overrides to see the value before it is set on a field.")]
- protected virtual void ConfigureRelyingParty(OpenIdRelyingParty relyingParty) {
- Contract.Requires<ArgumentNullException>(relyingParty != null);
-
- // Only set RequireSsl to true, as we don't want to override
- // a .config setting of true with false.
- if (this.RequireSsl) {
- relyingParty.SecuritySettings.RequireSsl = true;
- }
- }
-
- /// <summary>
- /// Detects whether a popup window should be used to show the Provider's UI.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>
- /// <c>true</c> if a popup should be used; <c>false</c> otherwise.
- /// </returns>
- protected virtual bool IsPopupAppropriate(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- switch (this.Popup) {
- case PopupBehavior.Never:
- return false;
- case PopupBehavior.Always:
- return true;
- case PopupBehavior.IfProviderSupported:
- return request.DiscoveryResult.IsExtensionSupported<UIRequest>();
- default:
- throw ErrorUtilities.ThrowInternal("Unexpected value for Popup property.");
- }
- }
-
- /// <summary>
- /// Adds attributes to an HTML &lt;A&gt; tag that will be written by the caller using
- /// <see cref="HtmlTextWriter.RenderBeginTag(HtmlTextWriterTag)"/> after this method.
- /// </summary>
- /// <param name="writer">The HTML writer.</param>
- /// <param name="request">The outgoing authentication request.</param>
- /// <param name="windowStatus">The text to try to display in the status bar on mouse hover.</param>
- protected void RenderOpenIdMessageTransmissionAsAnchorAttributes(HtmlTextWriter writer, IAuthenticationRequest request, string windowStatus) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentNullException>(request != null);
-
- // We render a standard HREF attribute for non-javascript browsers.
- writer.AddAttribute(HtmlTextWriterAttribute.Href, request.RedirectingResponse.GetDirectUriRequest(this.RelyingParty.Channel).AbsoluteUri);
-
- // And for the Javascript ones we do the extra work to use form POST where necessary.
- writer.AddAttribute(HtmlTextWriterAttribute.Onclick, this.CreateGetOrPostAHrefValue(request) + " return false;");
-
- writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
- if (!string.IsNullOrEmpty(windowStatus)) {
- writer.AddAttribute("onMouseOver", "window.status = " + MessagingUtilities.GetSafeJavascriptValue(windowStatus));
- writer.AddAttribute("onMouseOut", "window.status = null");
- }
- }
-
- /// <summary>
- /// Creates the identifier-persisting cookie, either for saving or deleting.
- /// </summary>
- /// <param name="response">The positive authentication response; or <c>null</c> to clear the cookie.</param>
- /// <returns>An persistent cookie.</returns>
- private static HttpCookie CreateIdentifierPersistingCookie(IAuthenticationResponse response) {
- HttpCookie cookie = new HttpCookie(PersistentIdentifierCookieName);
- bool clearingCookie = false;
-
- // We'll try to store whatever it was the user originally typed in, but fallback
- // to the final claimed_id.
- if (response != null && response.Status == AuthenticationStatus.Authenticated) {
- var positiveResponse = (PositiveAuthenticationResponse)response;
-
- // We must escape the value because XRIs start with =, and any leading '=' gets dropped (by ASP.NET?)
- cookie.Value = Uri.EscapeDataString(positiveResponse.Endpoint.UserSuppliedIdentifier ?? response.ClaimedIdentifier);
- } else {
- clearingCookie = true;
- cookie.Value = string.Empty;
- if (HttpContext.Current.Request.Browser["supportsEmptyStringInCookieValue"] == "false") {
- cookie.Value = "NoCookie";
- }
- }
-
- if (clearingCookie) {
- // mark the cookie has having already expired to cause the user agent to delete
- // the old persisted cookie.
- cookie.Expires = DateTime.Now.Subtract(TimeSpan.FromDays(1));
- } else {
- // Make the cookie persistent by setting an expiration date
- cookie.Expires = DateTime.Now + PersistentIdentifierTimeToLiveDefault;
- }
-
- return cookie;
- }
-
- /// <summary>
- /// Creates the authentication requests for a given user-supplied Identifier.
- /// </summary>
- /// <param name="identifier">The identifier to create a request for.</param>
- /// <returns>
- /// A sequence of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
- /// </returns>
- private IEnumerable<IAuthenticationRequest> CreateRequestsCore(Identifier identifier) {
- ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier"); // NO CODE CONTRACTS! (yield return used here)
- IEnumerable<IAuthenticationRequest> requests;
-
- // Approximate the returnTo (either based on the customize property or the page URL)
- // so we can use it to help with Realm resolution.
- Uri returnToApproximation;
- if (this.ReturnToUrl != null) {
- string returnToResolvedPath = this.ResolveUrl(this.ReturnToUrl);
- returnToApproximation = new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, returnToResolvedPath);
- } else {
- returnToApproximation = this.Page.Request.Url;
- }
-
- // Resolve the trust root, and swap out the scheme and port if necessary to match the
- // return_to URL, since this match is required by OpenID, and the consumer app
- // may be using HTTP at some times and HTTPS at others.
- UriBuilder realm = OpenIdUtilities.GetResolvedRealm(this.Page, this.RealmUrl, this.RelyingParty.Channel.GetRequestFromContext());
- realm.Scheme = returnToApproximation.Scheme;
- realm.Port = returnToApproximation.Port;
-
- // Initiate OpenID request
- // We use TryParse here to avoid throwing an exception which
- // might slip through our validator control if it is disabled.
- Realm typedRealm = new Realm(realm);
- if (string.IsNullOrEmpty(this.ReturnToUrl)) {
- requests = this.RelyingParty.CreateRequests(identifier, typedRealm);
- } else {
- // Since the user actually gave us a return_to value,
- // the "approximation" is exactly what we want.
- requests = this.RelyingParty.CreateRequests(identifier, typedRealm, returnToApproximation);
- }
-
- // Some OPs may be listed multiple times (one with HTTPS and the other with HTTP, for example).
- // Since we're gathering OPs to try one after the other, just take the first choice of each OP
- // and don't try it multiple times.
- requests = requests.Distinct(DuplicateRequestedHostsComparer.Instance);
-
- // Configure each generated request.
- foreach (var req in requests) {
- if (this.IsPopupAppropriate(req)) {
- // Inform ourselves in return_to that we're in a popup.
- req.SetUntrustedCallbackArgument(UIPopupCallbackKey, "1");
-
- if (req.DiscoveryResult.IsExtensionSupported<UIRequest>()) {
- // Inform the OP that we'll be using a popup window consistent with the UI extension.
- // But beware that the extension MAY have already been added if we're using
- // the OpenIdAjaxRelyingParty class.
- if (!((AuthenticationRequest)req).Extensions.OfType<UIRequest>().Any()) {
- req.AddExtension(new UIRequest());
- }
-
- // Provide a hint for the client javascript about whether the OP supports the UI extension.
- // This is so the window can be made the correct size for the extension.
- // If the OP doesn't advertise support for the extension, the javascript will use
- // a bigger popup window.
- req.SetUntrustedCallbackArgument(PopupUISupportedJSHint, "1");
- }
- }
-
- // Add the extensions injected into the control.
- foreach (var extension in this.Extensions) {
- req.AddExtension(extension);
- }
-
- // Add state that needs to survive across the redirect, but at this point
- // only save those properties that are not expected to be changed by a
- // LoggingIn event handler.
- req.SetUntrustedCallbackArgument(ReturnToReceivingControlId, this.ClientID);
-
- // Apply the control's association preference to this auth request, but only if
- // it is less demanding (greater ordinal value) than the existing one.
- // That way, we protect against retrying an association that was already attempted.
- var authReq = ((AuthenticationRequest)req);
- if (authReq.AssociationPreference < this.AssociationPreference) {
- authReq.AssociationPreference = this.AssociationPreference;
- }
-
- if (this.OnLoggingIn(req)) {
- // We save this property after firing OnLoggingIn so that the host page can
- // change its value and have that value saved.
- req.SetUntrustedCallbackArgument(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString());
-
- yield return req;
- }
- }
- }
-
- /// <summary>
- /// Gets the javascript to executee to redirect or POST an OpenID message to a remote party.
- /// </summary>
- /// <param name="request">The authentication request to send.</param>
- /// <returns>The javascript that should execute.</returns>
- private string CreateGetOrPostAHrefValue(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- Uri directUri = request.RedirectingResponse.GetDirectUriRequest(this.RelyingParty.Channel);
- return "window.dnoa_internal.GetOrPost(" + MessagingUtilities.GetSafeJavascriptValue(directUri.AbsoluteUri) + ");";
- }
-
- /// <summary>
- /// Wires the return page to immediately display a popup window with the Provider in it.
- /// </summary>
- /// <param name="request">The request.</param>
- private void ScriptPopupWindow(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
- Contract.Requires<InvalidOperationException>(this.RelyingParty != null);
-
- StringBuilder startupScript = new StringBuilder();
-
- // Add a callback function that the popup window can call on this, the
- // parent window, to pass back the authentication result.
- startupScript.AppendLine("window.dnoa_internal = {};");
- startupScript.AppendLine("window.dnoa_internal.processAuthorizationResult = function(uri) { window.location = uri; };");
- startupScript.AppendLine("window.dnoa_internal.popupWindow = function() {");
- startupScript.AppendFormat(
- @"\tvar openidPopup = {0}",
- UIUtilities.GetWindowPopupScript(this.RelyingParty, request, "openidPopup"));
- startupScript.AppendLine("};");
-
- this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "loginPopup", startupScript.ToString(), true);
- }
-
- /// <summary>
- /// Tries to preset the <see cref="Identifier"/> property based on a persistent
- /// cookie on the browser.
- /// </summary>
- /// <returns>
- /// A value indicating whether the <see cref="Identifier"/> property was
- /// successfully preset to some non-empty value.
- /// </returns>
- private bool TryPresetIdentifierWithCookie() {
- HttpCookie cookie = this.Page.Request.Cookies[PersistentIdentifierCookieName];
- if (cookie != null) {
- this.Identifier = Uri.UnescapeDataString(cookie.Value);
- return true;
- }
-
- return false;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js
deleted file mode 100644
index 58b283d..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js
+++ /dev/null
@@ -1,172 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdRelyingPartyControlBase.js" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// This file may be used and redistributed under the terms of the
-// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
-// </copyright>
-//-----------------------------------------------------------------------
-
-// Options that can be set on the host page:
-//window.openid_visible_iframe = true; // causes the hidden iframe to show up
-//window.openid_trace = true; // causes lots of messages
-
-trace = function(msg, color) {
- if (window.openid_trace) {
- if (!window.openid_tracediv) {
- window.openid_tracediv = document.createElement("ol");
- document.body.appendChild(window.openid_tracediv);
- }
- var el = document.createElement("li");
- if (color) { el.style.color = color; }
- el.appendChild(document.createTextNode(msg));
- window.openid_tracediv.appendChild(el);
- //alert(msg);
- }
-};
-
-if (window.dnoa_internal === undefined) {
- window.dnoa_internal = {};
-}
-
-/// <summary>Instantiates an object that provides string manipulation services for URIs.</summary>
-window.dnoa_internal.Uri = function(url) {
- this.originalUri = url.toString();
-
- this.toString = function() {
- return this.originalUri;
- };
-
- this.getAuthority = function() {
- var authority = this.getScheme() + "://" + this.getHost();
- return authority;
- };
-
- this.getHost = function() {
- var hostStartIdx = this.originalUri.indexOf("://") + 3;
- var hostEndIndex = this.originalUri.indexOf("/", hostStartIdx);
- if (hostEndIndex < 0) { hostEndIndex = this.originalUri.length; }
- var host = this.originalUri.substr(hostStartIdx, hostEndIndex - hostStartIdx);
- return host;
- };
-
- this.getScheme = function() {
- var schemeStartIdx = this.indexOf("://");
- return this.originalUri.substr(this.originalUri, schemeStartIdx);
- };
-
- this.trimFragment = function() {
- var hashmark = this.originalUri.indexOf('#');
- if (hashmark >= 0) {
- return new window.dnoa_internal.Uri(this.originalUri.substr(0, hashmark));
- }
- return this;
- };
-
- this.appendQueryVariable = function(name, value) {
- var pair = encodeURI(name) + "=" + encodeURI(value);
- if (this.originalUri.indexOf('?') >= 0) {
- this.originalUri = this.originalUri + "&" + pair;
- } else {
- this.originalUri = this.originalUri + "?" + pair;
- }
- };
-
- function KeyValuePair(key, value) {
- this.key = key;
- this.value = value;
- }
-
- this.pairs = [];
-
- var queryBeginsAt = this.originalUri.indexOf('?');
- if (queryBeginsAt >= 0) {
- this.queryString = this.originalUri.substr(queryBeginsAt + 1);
- var queryStringPairs = this.queryString.split('&');
-
- for (var i = 0; i < queryStringPairs.length; i++) {
- var equalsAt = queryStringPairs[i].indexOf('=');
- left = (equalsAt >= 0) ? queryStringPairs[i].substring(0, equalsAt) : null;
- right = (equalsAt >= 0) ? queryStringPairs[i].substring(equalsAt + 1) : queryStringPairs[i];
- this.pairs.push(new KeyValuePair(unescape(left), unescape(right)));
- }
- }
-
- this.getQueryArgValue = function(key) {
- for (var i = 0; i < this.pairs.length; i++) {
- if (this.pairs[i].key == key) {
- return this.pairs[i].value;
- }
- }
- };
-
- this.getPairs = function() {
- return this.pairs;
- };
-
- this.containsQueryArg = function(key) {
- return this.getQueryArgValue(key);
- };
-
- this.getUriWithoutQueryOrFragement = function() {
- var queryBeginsAt = this.originalUri.indexOf('?');
- if (queryBeginsAt >= 0) {
- return this.originalUri.substring(0, queryBeginsAt);
- } else {
- var fragmentBeginsAt = this.originalUri.indexOf('#');
- if (fragmentBeginsAt >= 0) {
- return this.originalUri.substring(0, fragmentBeginsAt);
- } else {
- return this.originalUri;
- }
- }
- };
-
- this.indexOf = function(args) {
- return this.originalUri.indexOf(args);
- };
-
- return this;
-};
-
-/// <summary>Creates a hidden iframe.</summary>
-window.dnoa_internal.createHiddenIFrame = function() {
- var iframe = document.createElement("iframe");
- if (!window.openid_visible_iframe) {
- iframe.setAttribute("width", 0);
- iframe.setAttribute("height", 0);
- iframe.setAttribute("style", "display: none");
- iframe.setAttribute("border", 0);
- }
-
- return iframe;
-};
-
-/// <summary>Redirects the current window/frame to the given URI,
-/// either using a GET or a POST as required by the length of the URL.</summary>
-window.dnoa_internal.GetOrPost = function(uri) {
- var maxGetLength = 2 * 1024; // keep in sync with DotNetOpenAuth.Messaging.Channel.IndirectMessageGetToPostThreshold
- uri = new window.dnoa_internal.Uri(uri);
-
- if (uri.toString().length <= maxGetLength) {
- window.location = uri.toString();
- } else {
- trace("Preparing to POST: " + uri.toString());
- var iframe = window.dnoa_internal.createHiddenIFrame();
- document.body.appendChild(iframe);
- var doc = iframe.ownerDocument;
- var form = doc.createElement('form');
- form.action = uri.getUriWithoutQueryOrFragement();
- form.method = "POST";
- form.target = "_top";
- for (var i = 0; i < uri.getPairs().length; i++) {
- var input = doc.createElement('input');
- input.type = 'hidden';
- input.name = uri.getPairs()[i].key;
- input.value = uri.getPairs()[i].value;
- trace(input.name + " = " + input.value);
- form.appendChild(input);
- }
- doc.body.appendChild(form);
- form.submit();
- }
-};
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.cs
deleted file mode 100644
index ae1037b..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.cs
+++ /dev/null
@@ -1,455 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdSelector.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector.EmbeddedScriptResourceName, "text/javascript")]
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector.EmbeddedStylesheetResourceName, "text/css")]
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.IdentityModel.Claims;
- using System.Linq;
- using System.Text;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.HtmlControls;
- using System.Web.UI.WebControls;
- using DotNetOpenAuth.ComponentModel;
- ////using DotNetOpenAuth.InfoCard;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// An ASP.NET control that provides a user-friendly way of logging into a web site using OpenID.
- /// </summary>
- [ToolboxData("<{0}:OpenIdSelector runat=\"server\"></{0}:OpenIdSelector>")]
- public class OpenIdSelector : OpenIdRelyingPartyAjaxControlBase {
- /// <summary>
- /// The name of the manifest stream containing the OpenIdButtonPanel.js file.
- /// </summary>
- internal const string EmbeddedScriptResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdSelector.js";
-
- /// <summary>
- /// The name of the manifest stream containing the OpenIdButtonPanel.css file.
- /// </summary>
- internal const string EmbeddedStylesheetResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdSelector.css";
-
- /// <summary>
- /// The substring to append to the end of the id or name of this control to form the
- /// unique name of the hidden field that will carry the positive assertion on postback.
- /// </summary>
- private const string AuthDataFormKeySuffix = "_openidAuthData";
-
- #region ViewState keys
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Buttons"/> property.
- /// </summary>
- private const string ButtonsViewStateKey = "Buttons";
-
- /// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticatedAsToolTip"/> property.
- /// </summary>
- private const string AuthenticatedAsToolTipViewStateKey = "AuthenticatedAsToolTip";
-
- #endregion
-
- #region Property defaults
-
- /// <summary>
- /// The default value for the <see cref="AuthenticatedAsToolTip"/> property.
- /// </summary>
- private const string AuthenticatedAsToolTipDefault = "We recognize you!";
-
- #endregion
-
- /// <summary>
- /// The OpenIdAjaxTextBox that remains hidden until the user clicks the OpenID button.
- /// </summary>
- private OpenIdAjaxTextBox textBox;
-
- /// <summary>
- /// The hidden field that will transmit the positive assertion to the RP.
- /// </summary>
- private HiddenField positiveAssertionField;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdSelector"/> class.
- /// </summary>
- public OpenIdSelector() {
- }
-
- /////// <summary>
- /////// Occurs when an InfoCard has been submitted and decoded.
- /////// </summary>
- ////public event EventHandler<ReceivedTokenEventArgs> ReceivedToken;
-
- /////// <summary>
- /////// Occurs when [token processing error].
- /////// </summary>
- ////public event EventHandler<TokenProcessingErrorEventArgs> TokenProcessingError;
-
- /// <summary>
- /// Gets the text box where applicable.
- /// </summary>
- public OpenIdAjaxTextBox TextBox {
- get {
- this.EnsureChildControlsAreCreatedSafe();
- return this.textBox;
- }
- }
-
- /// <summary>
- /// Gets or sets the maximum number of OpenID Providers to simultaneously try to authenticate with.
- /// </summary>
- [Browsable(true), DefaultValue(OpenIdAjaxTextBox.ThrottleDefault), Category(BehaviorCategory)]
- [Description("The maximum number of OpenID Providers to simultaneously try to authenticate with.")]
- public int Throttle {
- get {
- this.EnsureChildControlsAreCreatedSafe();
- return this.textBox.Throttle;
- }
-
- set {
- this.EnsureChildControlsAreCreatedSafe();
- this.textBox.Throttle = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the time duration for the AJAX control to wait for an OP to respond before reporting failure to the user.
- /// </summary>
- [Browsable(true), DefaultValue(typeof(TimeSpan), "00:00:08"), Category(BehaviorCategory)]
- [Description("The time duration for the AJAX control to wait for an OP to respond before reporting failure to the user.")]
- public TimeSpan Timeout {
- get {
- this.EnsureChildControlsAreCreatedSafe();
- return this.textBox.Timeout;
- }
-
- set {
- this.EnsureChildControlsAreCreatedSafe();
- this.textBox.Timeout = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the tool tip text that appears on the green checkmark when authentication succeeds.
- /// </summary>
- [Bindable(true), DefaultValue(AuthenticatedAsToolTipDefault), Localizable(true), Category(AppearanceCategory)]
- [Description("The tool tip text that appears on the green checkmark when authentication succeeds.")]
- public string AuthenticatedAsToolTip {
- get { return (string)(this.ViewState[AuthenticatedAsToolTipViewStateKey] ?? AuthenticatedAsToolTipDefault); }
- set { this.ViewState[AuthenticatedAsToolTipViewStateKey] = value ?? string.Empty; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether the Yahoo! User Interface Library (YUI)
- /// will be downloaded in order to provide a login split button.
- /// </summary>
- /// <value>
- /// <c>true</c> to use a split button; otherwise, <c>false</c> to use a standard HTML button
- /// or a split button by downloading the YUI library yourself on the hosting web page.
- /// </value>
- /// <remarks>
- /// The split button brings in about 180KB of YUI javascript dependencies.
- /// </remarks>
- [Bindable(true), DefaultValue(OpenIdAjaxTextBox.DownloadYahooUILibraryDefault), Category(BehaviorCategory)]
- [Description("Whether a split button will be used for the \"log in\" when the user provides an identifier that delegates to more than one Provider.")]
- public bool DownloadYahooUILibrary {
- get {
- this.EnsureChildControlsAreCreatedSafe();
- return this.textBox.DownloadYahooUILibrary;
- }
-
- set {
- this.EnsureChildControlsAreCreatedSafe();
- this.textBox.DownloadYahooUILibrary = value;
- }
- }
-
- /// <summary>
- /// Gets the collection of buttons this selector should render to the browser.
- /// </summary>
- [PersistenceMode(PersistenceMode.InnerProperty)]
- public Collection<SelectorButton> Buttons {
- get {
- if (this.ViewState[ButtonsViewStateKey] == null) {
- var providers = new Collection<SelectorButton>();
- this.ViewState[ButtonsViewStateKey] = providers;
- return providers;
- } else {
- return (Collection<SelectorButton>)this.ViewState[ButtonsViewStateKey];
- }
- }
- }
-
- /// <summary>
- /// Gets a <see cref="T:System.Web.UI.ControlCollection"/> object that represents the child controls for a specified server control in the UI hierarchy.
- /// </summary>
- /// <returns>
- /// The collection of child controls for the specified server control.
- /// </returns>
- public override ControlCollection Controls {
- get {
- this.EnsureChildControls();
- return base.Controls;
- }
- }
-
- /// <summary>
- /// Gets the name of the open id auth data form key (for the value as stored at the user agent as a FORM field).
- /// </summary>
- /// <value>
- /// Usually a concatenation of the control's name and <c>"_openidAuthData"</c>.
- /// </value>
- protected override string OpenIdAuthDataFormKey {
- get { return this.UniqueID + AuthDataFormKeySuffix; }
- }
-
- /// <summary>
- /// Gets a value indicating whether some button in the selector will want
- /// to display the <see cref="OpenIdAjaxTextBox"/> control.
- /// </summary>
- protected virtual bool OpenIdTextBoxVisible {
- get { return this.Buttons.OfType<SelectorOpenIdButton>().Any(); }
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources
- /// </summary>
- /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool disposing) {
- if (disposing) {
- foreach (var button in this.Buttons.OfType<IDisposable>()) {
- button.Dispose();
- }
- }
-
- base.Dispose(disposing);
- }
-
- /// <summary>
- /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
- /// </summary>
- protected override void CreateChildControls() {
- this.EnsureChildControlsAreCreatedSafe();
-
- base.CreateChildControls();
-
- // Now do the ID specific work.
- this.EnsureID();
- ErrorUtilities.VerifyInternal(!string.IsNullOrEmpty(this.UniqueID), "Control.EnsureID() failed to give us a unique ID. Try setting an ID on the OpenIdSelector control. But please also file this bug with the project owners.");
-
- this.Controls.Add(this.textBox);
-
- this.positiveAssertionField.ID = this.ID + AuthDataFormKeySuffix;
- this.Controls.Add(this.positiveAssertionField);
- }
-
- /// <summary>
- /// Ensures that the child controls have been built, but doesn't set control
- /// properties that require executing <see cref="Control.EnsureID"/> in order to avoid
- /// certain initialization order problems.
- /// </summary>
- /// <remarks>
- /// We don't just call EnsureChildControls() and then set the property on
- /// this.textBox itself because (apparently) setting this property in the ASPX
- /// page and thus calling this EnsureID() via EnsureChildControls() this early
- /// results in no ID.
- /// </remarks>
- protected virtual void EnsureChildControlsAreCreatedSafe() {
- // If we've already created the child controls, this method is a no-op.
- if (this.textBox != null) {
- return;
- }
-
- ////var selectorButton = this.Buttons.OfType<SelectorInfoCardButton>().FirstOrDefault();
- ////if (selectorButton != null) {
- //// var selector = selectorButton.InfoCardSelector;
- //// selector.ClaimsRequested.Add(new ClaimType { Name = ClaimTypes.PPID });
- //// selector.ImageSize = InfoCardImageSize.Size60x42;
- //// selector.ReceivedToken += this.InfoCardSelector_ReceivedToken;
- //// selector.TokenProcessingError += this.InfoCardSelector_TokenProcessingError;
- //// this.Controls.Add(selector);
- ////}
-
- this.textBox = new OpenIdAjaxTextBox();
- this.textBox.ID = "openid_identifier";
- this.textBox.HookFormSubmit = false;
- this.textBox.ShowLogOnPostBackButton = true;
-
- this.positiveAssertionField = new HiddenField();
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnInit(EventArgs e) {
- base.OnInit(e);
-
- // We force child control creation here so that they can get postback events.
- EnsureChildControls();
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
-
- this.EnsureValidButtons();
-
- var css = new HtmlLink();
- try {
- css.Href = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedStylesheetResourceName);
- css.Attributes["rel"] = "stylesheet";
- css.Attributes["type"] = "text/css";
- ErrorUtilities.VerifyHost(this.Page.Header != null, OpenIdStrings.HeadTagMustIncludeRunatServer);
- this.Page.Header.Controls.AddAt(0, css); // insert at top so host page can override
- } catch {
- css.Dispose();
- throw;
- }
-
- // Import the .js file where most of the code is.
- this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdSelector), EmbeddedScriptResourceName);
-
- // Provide javascript with a way to post the login assertion.
- const string PostLoginAssertionMethodName = "postLoginAssertion";
- const string PositiveAssertionParameterName = "positiveAssertion";
- const string ScriptFormat = @"window.{2} = function({0}) {{
- $('#{3}')[0].setAttribute('value', {0});
- {1};
-}};";
- string script = string.Format(
- CultureInfo.InvariantCulture,
- ScriptFormat,
- PositiveAssertionParameterName,
- this.Page.ClientScript.GetPostBackEventReference(this, null, false),
- PostLoginAssertionMethodName,
- this.positiveAssertionField.ClientID);
- this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Postback", script, true);
-
- this.PreloadDiscovery(this.Buttons.OfType<SelectorProviderButton>().Select(op => op.OPIdentifier).Where(id => id != null));
- this.textBox.Visible = this.OpenIdTextBoxVisible;
- }
-
- /// <summary>
- /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
- protected override void Render(HtmlTextWriter writer) {
- Contract.Assume(writer != null, "Missing contract");
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "OpenIdProviders");
- writer.RenderBeginTag(HtmlTextWriterTag.Ul);
-
- foreach (var button in this.Buttons) {
- button.RenderLeadingAttributes(writer);
-
- writer.RenderBeginTag(HtmlTextWriterTag.Li);
-
- writer.AddAttribute(HtmlTextWriterAttribute.Href, "#");
- writer.RenderBeginTag(HtmlTextWriterTag.A);
-
- writer.RenderBeginTag(HtmlTextWriterTag.Div);
- writer.RenderBeginTag(HtmlTextWriterTag.Div);
-
- button.RenderButtonContent(writer, this);
-
- writer.RenderEndTag(); // </div>
-
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "ui-widget-overlay");
- writer.RenderBeginTag(HtmlTextWriterTag.Div);
- writer.RenderEndTag();
-
- writer.RenderEndTag(); // </div>
- writer.RenderEndTag(); // </a>
- writer.RenderEndTag(); // </li>
- }
-
- writer.RenderEndTag(); // </ul>
-
- if (this.textBox.Visible) {
- writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none");
- writer.AddAttribute(HtmlTextWriterAttribute.Id, "OpenIDForm");
- writer.RenderBeginTag(HtmlTextWriterTag.Div);
-
- this.textBox.RenderControl(writer);
-
- writer.RenderEndTag(); // </div>
- }
-
- this.positiveAssertionField.RenderControl(writer);
- }
-
- /////// <summary>
- /////// Fires the <see cref="ReceivedToken"/> event.
- /////// </summary>
- /////// <param name="e">The token, if it was decrypted.</param>
- ////protected virtual void OnReceivedToken(ReceivedTokenEventArgs e) {
- //// Contract.Requires(e != null);
- //// ErrorUtilities.VerifyArgumentNotNull(e, "e");
-
- //// var receivedInfoCard = this.ReceivedToken;
- //// if (receivedInfoCard != null) {
- //// receivedInfoCard(this, e);
- //// }
- ////}
-
- /////// <summary>
- /////// Raises the <see cref="E:TokenProcessingError"/> event.
- /////// </summary>
- /////// <param name="e">The <see cref="DotNetOpenAuth.InfoCard.TokenProcessingErrorEventArgs"/> instance containing the event data.</param>
- ////protected virtual void OnTokenProcessingError(TokenProcessingErrorEventArgs e) {
- //// Contract.Requires(e != null);
- //// ErrorUtilities.VerifyArgumentNotNull(e, "e");
-
- //// var tokenProcessingError = this.TokenProcessingError;
- //// if (tokenProcessingError != null) {
- //// tokenProcessingError(this, e);
- //// }
- ////}
-
- /////// <summary>
- /////// Handles the ReceivedToken event of the infoCardSelector control.
- /////// </summary>
- /////// <param name="sender">The source of the event.</param>
- /////// <param name="e">The <see cref="DotNetOpenAuth.InfoCard.ReceivedTokenEventArgs"/> instance containing the event data.</param>
- ////private void InfoCardSelector_ReceivedToken(object sender, ReceivedTokenEventArgs e) {
- //// this.Page.Response.SetCookie(new HttpCookie("openid_identifier", "infocard") {
- //// Path = this.Page.Request.ApplicationPath,
- //// });
- //// this.OnReceivedToken(e);
- ////}
-
- /////// <summary>
- /////// Handles the TokenProcessingError event of the infoCardSelector control.
- /////// </summary>
- /////// <param name="sender">The source of the event.</param>
- /////// <param name="e">The <see cref="DotNetOpenAuth.InfoCard.TokenProcessingErrorEventArgs"/> instance containing the event data.</param>
- ////private void InfoCardSelector_TokenProcessingError(object sender, TokenProcessingErrorEventArgs e) {
- //// this.OnTokenProcessingError(e);
- ////}
-
- /// <summary>
- /// Ensures the <see cref="Buttons"/> collection has a valid set of buttons.
- /// </summary>
- private void EnsureValidButtons() {
- foreach (var button in this.Buttons) {
- button.EnsureValid();
- }
-
- // Also make sure that there are appropriate numbers of each type of button.
- // TODO: code here
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.css b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.css
deleted file mode 100644
index e7eafc7..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.css
+++ /dev/null
@@ -1,109 +0,0 @@
-ul.OpenIdProviders
-{
- padding: 0;
- margin: 0px 0px 0px 0px;
- list-style-type: none;
- text-align: center;
-}
-
-ul.OpenIdProviders li
-{
- background-color: White;
- display: inline-block;
- border: 1px solid #DDD;
- margin: 0px 2px 4px 2px;
- height: 50px;
- width: 100px;
- text-align: center;
- vertical-align: middle;
-}
-
-ul.OpenIdProviders li div
-{
- margin: 0;
- padding: 0;
- height: 50px;
- width: 100px;
- text-align: center;
- display: table;
- position: relative;
- overflow: hidden;
-}
-
-ul.OpenIdProviders li div div
-{
- margin: 0;
- padding: 0;
- top: 50%;
- display: table-cell;
- vertical-align: middle;
- position: static;
-}
-
-ul.OpenIdProviders li img
-{
-}
-
-ul.OpenIdProviders li a img
-{
- border-width: 0;
-}
-
-ul.OpenIdProviders li img.loginSuccess
-{
- position: absolute;
- right: 0;
- bottom: 0;
- display: none;
-}
-
-ul.OpenIdProviders li.loginSuccess img.loginSuccess
-{
- display: inline;
-}
-
-ul.OpenIdProviders li a
-{
- display: block; /* Chrome needs this for proper position of grayed out overlay */
- position: relative;
-}
-
-ul.OpenIdProviders li div.ui-widget-overlay
-{
- display: none;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- bottom: 0;
-}
-
-ul.OpenIdProviders li.grayedOut div.ui-widget-overlay
-{
- display: block;
-}
-
-ul.OpenIdProviders li.focused
-{
- border: solid 2px yellow;
-}
-
-ul.OpenIdProviders li.infocard
-{
- display: none; /* default to hiding InfoCard until the user agent determines it's supported */
- cursor: pointer;
-}
-
-#openid_identifier
-{
- width: 298px;
-}
-
-#OpenIDForm
-{
- text-align: center;
-}
-
-#openid_login_button
-{
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.js b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.js
deleted file mode 100644
index 297ea23..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdSelector.js
+++ /dev/null
@@ -1,196 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdSelector.js" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// This file may be used and redistributed under the terms of the
-// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
-// </copyright>
-//-----------------------------------------------------------------------
-
-$(function() {
- var hint = $.cookie('openid_identifier') || '';
-
- var ajaxbox = document.getElementsByName('openid_identifier')[0];
- if (ajaxbox && hint != 'infocard') {
- ajaxbox.setValue(hint);
- }
-
- if (document.infoCard && document.infoCard.isSupported()) {
- $('ul.OpenIdProviders li.infocard')[0].style.display = 'inline-block';
- }
-
- if (hint.length > 0) {
- var ops = $('ul.OpenIdProviders li');
- ops.addClass('grayedOut');
- var matchFound = false;
- ops.each(function(i, li) {
- if (li.id == hint || (hint == 'infocard' && $(li).hasClass('infocard'))) {
- $(li)
- .removeClass('grayedOut')
- .addClass('focused');
- matchFound = true;
- }
- });
- if (!matchFound) {
- if (ajaxbox) {
- $('#OpenIDButton')
- .removeClass('grayedOut')
- .addClass('focused');
- $('#OpenIDForm').show('slow', function() {
- ajaxbox.focus();
- });
- } else {
- // No OP button matched the last identifier, and there is no text box,
- // so just un-gray all buttons.
- ops.removeClass('grayedOut');
- }
- }
- }
-
- function showLoginSuccess(userSuppliedIdentifier, success) {
- var li = document.getElementById(userSuppliedIdentifier);
- if (li) {
- if (success) {
- $(li).addClass('loginSuccess');
- } else {
- $(li).removeClass('loginSuccess');
- }
- }
- }
-
- window.dnoa_internal.addAuthSuccess(function(discoveryResult, serviceEndpoint, extensionResponses, state) {
- showLoginSuccess(discoveryResult.userSuppliedIdentifier, true);
- });
-
- window.dnoa_internal.addAuthCleared(function(discoveryResult, serviceEndpoint) {
- showLoginSuccess(discoveryResult.userSuppliedIdentifier, false);
-
- // If this is an OP button, renew the positive assertion.
- var li = document.getElementById(discoveryResult.userSuppliedIdentifier);
- if (li) {
- li.loginBackground();
- }
- });
-
- if (ajaxbox) {
- ajaxbox.onStateChanged = function(state) {
- if (state == "authenticated") {
- showLoginSuccess('OpenIDButton', true);
- } else {
- showLoginSuccess('OpenIDButton', false); // hide checkmark
- }
- };
- }
-
- function checkidSetup(identifier, timerBased) {
- var openid = new window.OpenIdIdentifier(identifier);
- if (!openid) { throw 'checkidSetup called without an identifier.'; }
- openid.login(function(discoveryResult, respondingEndpoint, extensionResponses) {
- doLogin(discoveryResult, respondingEndpoint);
- });
- }
-
- // Sends the positive assertion we've collected to the server and actually logs the user into the RP.
- function doLogin(discoveryResult, respondingEndpoint) {
- var retain = true; //!$('#NotMyComputer')[0].selected;
- $.cookie('openid_identifier', retain ? discoveryResult.userSuppliedIdentifier : null, { path: window.aspnetapppath });
- window.postLoginAssertion(respondingEndpoint.response.toString(), window.parent.location.href);
- }
-
- if (ajaxbox) {
- // take over how the text box does postbacks.
- ajaxbox.dnoi_internal.postback = doLogin;
- }
-
- // This FrameManager will be used for background logins for the OP buttons
- // and the last used identifier. It is NOT the frame manager used by the
- // OpenIdAjaxTextBox, as it has its own.
- var backgroundTimeout = 3000;
-
- $(document).ready(function() {
- var ops = $('ul.OpenIdProviders li');
- ops.each(function(i, li) {
- if ($(li).hasClass('OPButton')) {
- li.authenticationIFrames = new window.dnoa_internal.FrameManager(1/*throttle*/);
- var openid = new window.OpenIdIdentifier(li.id);
- var authFrames = li.authenticationIFrames;
- if ($(li).hasClass('NoAsyncAuth')) {
- li.loginBackground = function() { };
- } else {
- li.loginBackground = function() {
- openid.loginBackground(authFrames, null, null, backgroundTimeout);
- };
- }
- li.loginBackground();
- }
- });
- });
-
- $('ul.OpenIdProviders li').click(function() {
- var lastFocus = $('.focused')[0];
- if (lastFocus != $(this)[0]) {
- $('ul.OpenIdProviders li').removeClass('focused');
- $(this).addClass('focused');
- }
-
- // Make sure we're not graying out any OPs if the user clicked on a gray button.
- var wasGrayedOut = false;
- if ($(this).hasClass('grayedOut')) {
- wasGrayedOut = true;
- $('ul.OpenIdProviders li').removeClass('grayedOut');
- }
-
- // Be sure to hide the openid_identifier text box unless the OpenID button is selected.
- if ($(this)[0] != $('#OpenIDButton')[0] && $('#OpenIDForm').is(':visible')) {
- $('#OpenIDForm').hide('slow');
- }
-
- var relevantUserSuppliedIdentifier = null;
- // Don't immediately login if the user clicked OpenID and he can't see the identifier box.
- if ($(this)[0].id != 'OpenIDButton') {
- relevantUserSuppliedIdentifier = $(this)[0].id;
- } else if (ajaxbox && $('#OpenIDForm').is(':visible')) {
- relevantUserSuppliedIdentifier = ajaxbox.value;
- }
-
- var discoveryResult = window.dnoa_internal.discoveryResults[relevantUserSuppliedIdentifier];
- var respondingEndpoint = discoveryResult ? discoveryResult.findSuccessfulRequest() : null;
-
- // If the user clicked on a button that has the "we're ready to log you in immediately",
- // then log them in!
- if (respondingEndpoint) {
- doLogin(discoveryResult, respondingEndpoint);
- } else if ($(this).hasClass('OPButton')) {
- checkidSetup($(this)[0].id);
- } else if ($(this).hasClass('infocard') && wasGrayedOut) {
- // we need to forward the click onto the InfoCard image so it is handled, since our
- // gray overlaying div captured the click event.
- $('img', this)[0].click();
- }
- });
- if (ajaxbox) {
- $('#OpenIDButton').click(function() {
- // Be careful to only try to select the text box once it is available.
- if ($('#OpenIDForm').is(':hidden')) {
- $('#OpenIDForm').show('slow', function() {
- ajaxbox.focus();
- });
- } else {
- ajaxbox.focus();
- }
- });
-
- $(ajaxbox.form).keydown(function(e) {
- if (e.keyCode == $.ui.keyCode.ENTER) {
- // we do NOT want to submit the form on ENTER.
- e.preventDefault();
- }
- });
- }
-
- // Make popup window close on escape (the dialog style is already taken care of)
- $(document).keydown(function(e) {
- if (e.keyCode == $.ui.keyCode.ESCAPE) {
- window.close();
- }
- });
-}); \ No newline at end of file
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdTextBox.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdTextBox.cs
deleted file mode 100644
index 335b435..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdTextBox.cs
+++ /dev/null
@@ -1,708 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OpenIdTextBox.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdTextBox.EmbeddedLogoResourceName, "image/png")]
-
-#pragma warning disable 0809 // marking inherited, unsupported properties as obsolete to discourage their use
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Drawing.Design;
- using System.Globalization;
- using System.Net;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
- using DotNetOpenAuth.OpenId.Extensions.UI;
-
- /// <summary>
- /// An ASP.NET control that provides a minimal text box that is OpenID-aware.
- /// </summary>
- /// <remarks>
- /// This control offers greater UI flexibility than the <see cref="OpenIdLogin"/>
- /// control, but requires more work to be done by the hosting web site to
- /// assemble a complete login experience.
- /// </remarks>
- [DefaultProperty("Text"), ValidationProperty("Text")]
- [ToolboxData("<{0}:OpenIdTextBox runat=\"server\" />")]
- public class OpenIdTextBox : OpenIdRelyingPartyControlBase, IEditableTextControl, ITextControl, IPostBackDataHandler {
- /// <summary>
- /// The name of the manifest stream containing the
- /// OpenID logo that is placed inside the text box.
- /// </summary>
- internal const string EmbeddedLogoResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.openid_login.png";
-
- /// <summary>
- /// Default value for <see cref="TabIndex"/> property.
- /// </summary>
- protected const short TabIndexDefault = 0;
-
- #region Property category constants
-
- /// <summary>
- /// The "Simple Registration" category for properties.
- /// </summary>
- private const string ProfileCategory = "Simple Registration";
-
- #endregion
-
- #region Property viewstate keys
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestEmail"/> property.
- /// </summary>
- private const string RequestEmailViewStateKey = "RequestEmail";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestNickname"/> property.
- /// </summary>
- private const string RequestNicknameViewStateKey = "RequestNickname";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestPostalCode"/> property.
- /// </summary>
- private const string RequestPostalCodeViewStateKey = "RequestPostalCode";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestCountry"/> property.
- /// </summary>
- private const string RequestCountryViewStateKey = "RequestCountry";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestLanguage"/> property.
- /// </summary>
- private const string RequestLanguageViewStateKey = "RequestLanguage";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestTimeZone"/> property.
- /// </summary>
- private const string RequestTimeZoneViewStateKey = "RequestTimeZone";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="EnableRequestProfile"/> property.
- /// </summary>
- private const string EnableRequestProfileViewStateKey = "EnableRequestProfile";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="PolicyUrl"/> property.
- /// </summary>
- private const string PolicyUrlViewStateKey = "PolicyUrl";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestFullName"/> property.
- /// </summary>
- private const string RequestFullNameViewStateKey = "RequestFullName";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="PresetBorder"/> property.
- /// </summary>
- private const string PresetBorderViewStateKey = "PresetBorder";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="ShowLogo"/> property.
- /// </summary>
- private const string ShowLogoViewStateKey = "ShowLogo";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestGender"/> property.
- /// </summary>
- private const string RequestGenderViewStateKey = "RequestGender";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="RequestBirthDate"/> property.
- /// </summary>
- private const string RequestBirthDateViewStateKey = "RequestBirthDate";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="CssClass"/> property.
- /// </summary>
- private const string CssClassViewStateKey = "CssClass";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="MaxLength"/> property.
- /// </summary>
- private const string MaxLengthViewStateKey = "MaxLength";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Columns"/> property.
- /// </summary>
- private const string ColumnsViewStateKey = "Columns";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="TabIndex"/> property.
- /// </summary>
- private const string TabIndexViewStateKey = "TabIndex";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Enabled"/> property.
- /// </summary>
- private const string EnabledViewStateKey = "Enabled";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Name"/> property.
- /// </summary>
- private const string NameViewStateKey = "Name";
-
- /// <summary>
- /// The viewstate key to use for the <see cref="Text"/> property.
- /// </summary>
- private const string TextViewStateKey = "Text";
-
- #endregion
-
- #region Property defaults
-
- /// <summary>
- /// The default value for the <see cref="Columns"/> property.
- /// </summary>
- private const int ColumnsDefault = 40;
-
- /// <summary>
- /// The default value for the <see cref="MaxLength"/> property.
- /// </summary>
- private const int MaxLengthDefault = 40;
-
- /// <summary>
- /// The default value for the <see cref="Name"/> property.
- /// </summary>
- private const string NameDefault = "openid_identifier";
-
- /// <summary>
- /// The default value for the <see cref="EnableRequestProfile"/> property.
- /// </summary>
- private const bool EnableRequestProfileDefault = true;
-
- /// <summary>
- /// The default value for the <see cref="ShowLogo"/> property.
- /// </summary>
- private const bool ShowLogoDefault = true;
-
- /// <summary>
- /// The default value for the <see cref="PresetBorder"/> property.
- /// </summary>
- private const bool PresetBorderDefault = true;
-
- /// <summary>
- /// The default value for the <see cref="PolicyUrl"/> property.
- /// </summary>
- private const string PolicyUrlDefault = "";
-
- /// <summary>
- /// The default value for the <see cref="CssClass"/> property.
- /// </summary>
- private const string CssClassDefault = "openid";
-
- /// <summary>
- /// The default value for the <see cref="Text"/> property.
- /// </summary>
- private const string TextDefault = "";
-
- /// <summary>
- /// The default value for the <see cref="RequestEmail"/> property.
- /// </summary>
- private const DemandLevel RequestEmailDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestPostalCode"/> property.
- /// </summary>
- private const DemandLevel RequestPostalCodeDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestCountry"/> property.
- /// </summary>
- private const DemandLevel RequestCountryDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestLanguage"/> property.
- /// </summary>
- private const DemandLevel RequestLanguageDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestTimeZone"/> property.
- /// </summary>
- private const DemandLevel RequestTimeZoneDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestNickname"/> property.
- /// </summary>
- private const DemandLevel RequestNicknameDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestFullName"/> property.
- /// </summary>
- private const DemandLevel RequestFullNameDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestBirthDate"/> property.
- /// </summary>
- private const DemandLevel RequestBirthDateDefault = DemandLevel.NoRequest;
-
- /// <summary>
- /// The default value for the <see cref="RequestGender"/> property.
- /// </summary>
- private const DemandLevel RequestGenderDefault = DemandLevel.NoRequest;
-
- #endregion
-
- /// <summary>
- /// An empty sreg request, used to compare with others to see if they too are empty.
- /// </summary>
- private static readonly ClaimsRequest EmptyClaimsRequest = new ClaimsRequest();
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdTextBox"/> class.
- /// </summary>
- public OpenIdTextBox() {
- }
-
- #region IEditableTextControl Members
-
- /// <summary>
- /// Occurs when the content of the text changes between posts to the server.
- /// </summary>
- public event EventHandler TextChanged;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets or sets the content of the text box.
- /// </summary>
- [Bindable(true), DefaultValue(""), Category(AppearanceCategory)]
- [Description("The content of the text box.")]
- public string Text {
- get {
- return this.Identifier != null ? this.Identifier.OriginalString : (this.ViewState[TextViewStateKey] as string ?? string.Empty);
- }
-
- set {
- // Try to store it as a validated identifier,
- // but failing that at least store the text.
- Identifier id;
- if (Identifier.TryParse(value, out id)) {
- this.Identifier = id;
- } else {
- // Be sure to set the viewstate AFTER setting the Identifier,
- // since setting the Identifier clears the viewstate in OnIdentifierChanged.
- this.Identifier = null;
- this.ViewState[TextViewStateKey] = value;
- }
- }
- }
-
- /// <summary>
- /// Gets or sets the form name to use for this input field.
- /// </summary>
- [Bindable(true), DefaultValue(NameDefault), Category(BehaviorCategory)]
- [Description("The form name of this input field.")]
- public string Name {
- get { return (string)(this.ViewState[NameViewStateKey] ?? NameDefault); }
- set { this.ViewState[NameViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the CSS class assigned to the text box.
- /// </summary>
- [Bindable(true), DefaultValue(CssClassDefault), Category(AppearanceCategory)]
- [Description("The CSS class assigned to the text box.")]
- public string CssClass {
- get { return (string)this.ViewState[CssClassViewStateKey]; }
- set { this.ViewState[CssClassViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to show the OpenID logo in the text box.
- /// </summary>
- [Bindable(true), DefaultValue(ShowLogoDefault), Category(AppearanceCategory)]
- [Description("The visibility of the OpenID logo in the text box.")]
- public bool ShowLogo {
- get { return (bool)(this.ViewState[ShowLogoViewStateKey] ?? ShowLogoDefault); }
- set { this.ViewState[ShowLogoViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to use inline styling to force a solid gray border.
- /// </summary>
- [Bindable(true), DefaultValue(PresetBorderDefault), Category(AppearanceCategory)]
- [Description("Whether to use inline styling to force a solid gray border.")]
- public bool PresetBorder {
- get { return (bool)(this.ViewState[PresetBorderViewStateKey] ?? PresetBorderDefault); }
- set { this.ViewState[PresetBorderViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the width of the text box in characters.
- /// </summary>
- [Bindable(true), DefaultValue(ColumnsDefault), Category(AppearanceCategory)]
- [Description("The width of the text box in characters.")]
- public int Columns {
- get { return (int)(this.ViewState[ColumnsViewStateKey] ?? ColumnsDefault); }
- set { this.ViewState[ColumnsViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the maximum number of characters the browser should allow
- /// </summary>
- [Bindable(true), DefaultValue(MaxLengthDefault), Category(AppearanceCategory)]
- [Description("The maximum number of characters the browser should allow.")]
- public int MaxLength {
- get { return (int)(this.ViewState[MaxLengthViewStateKey] ?? MaxLengthDefault); }
- set { this.ViewState[MaxLengthViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the tab index of the Web server control.
- /// </summary>
- /// <value></value>
- /// <returns>
- /// The tab index of the Web server control. The default is 0, which indicates that this property is not set.
- /// </returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException">
- /// The specified tab index is not between -32768 and 32767.
- /// </exception>
- [Bindable(true), DefaultValue(TabIndexDefault), Category(BehaviorCategory)]
- [Description("The tab index of the text box control.")]
- public virtual short TabIndex {
- get { return (short)(this.ViewState[TabIndexViewStateKey] ?? TabIndexDefault); }
- set { this.ViewState[TabIndexViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether this <see cref="OpenIdTextBox"/> is enabled
- /// in the browser for editing and will respond to incoming OpenID messages.
- /// </summary>
- /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
- [Bindable(true), DefaultValue(true), Category(BehaviorCategory)]
- [Description("Whether the control is editable in the browser and will respond to OpenID messages.")]
- public bool Enabled {
- get { return (bool)(this.ViewState[EnabledViewStateKey] ?? true); }
- set { this.ViewState[EnabledViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's nickname from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestNicknameDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's nickname from the Provider.")]
- public DemandLevel RequestNickname {
- get { return (DemandLevel)(ViewState[RequestNicknameViewStateKey] ?? RequestNicknameDefault); }
- set { ViewState[RequestNicknameViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's email address from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestEmailDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's email address from the Provider.")]
- public DemandLevel RequestEmail {
- get { return (DemandLevel)(ViewState[RequestEmailViewStateKey] ?? RequestEmailDefault); }
- set { ViewState[RequestEmailViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's full name from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestFullNameDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's full name from the Provider")]
- public DemandLevel RequestFullName {
- get { return (DemandLevel)(ViewState[RequestFullNameViewStateKey] ?? RequestFullNameDefault); }
- set { ViewState[RequestFullNameViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's birthdate from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestBirthDateDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's birthdate from the Provider.")]
- public DemandLevel RequestBirthDate {
- get { return (DemandLevel)(ViewState[RequestBirthDateViewStateKey] ?? RequestBirthDateDefault); }
- set { ViewState[RequestBirthDateViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's gender from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestGenderDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's gender from the Provider.")]
- public DemandLevel RequestGender {
- get { return (DemandLevel)(ViewState[RequestGenderViewStateKey] ?? RequestGenderDefault); }
- set { ViewState[RequestGenderViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's postal code from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestPostalCodeDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's postal code from the Provider.")]
- public DemandLevel RequestPostalCode {
- get { return (DemandLevel)(ViewState[RequestPostalCodeViewStateKey] ?? RequestPostalCodeDefault); }
- set { ViewState[RequestPostalCodeViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's country from the Provider.
- /// </summary>
- [Bindable(true)]
- [Category(ProfileCategory)]
- [DefaultValue(RequestCountryDefault)]
- [Description("Your level of interest in receiving the user's country from the Provider.")]
- public DemandLevel RequestCountry {
- get { return (DemandLevel)(ViewState[RequestCountryViewStateKey] ?? RequestCountryDefault); }
- set { ViewState[RequestCountryViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's preferred language from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestLanguageDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's preferred language from the Provider.")]
- public DemandLevel RequestLanguage {
- get { return (DemandLevel)(ViewState[RequestLanguageViewStateKey] ?? RequestLanguageDefault); }
- set { ViewState[RequestLanguageViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets your level of interest in receiving the user's time zone from the Provider.
- /// </summary>
- [Bindable(true), DefaultValue(RequestTimeZoneDefault), Category(ProfileCategory)]
- [Description("Your level of interest in receiving the user's time zone from the Provider.")]
- public DemandLevel RequestTimeZone {
- get { return (DemandLevel)(ViewState[RequestTimeZoneViewStateKey] ?? RequestTimeZoneDefault); }
- set { ViewState[RequestTimeZoneViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the URL to your privacy policy page that describes how
- /// claims will be used and/or shared.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(PolicyUrlDefault), Category(ProfileCategory)]
- [Description("The URL to your privacy policy page that describes how claims will be used and/or shared.")]
- [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- public string PolicyUrl {
- get {
- return (string)ViewState[PolicyUrlViewStateKey] ?? PolicyUrlDefault;
- }
-
- set {
- UriUtil.ValidateResolvableUrl(Page, DesignMode, value);
- ViewState[PolicyUrlViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether to use OpenID extensions
- /// to retrieve profile data of the authenticating user.
- /// </summary>
- [Bindable(true), DefaultValue(EnableRequestProfileDefault), Category(ProfileCategory)]
- [Description("Turns the entire Simple Registration extension on or off.")]
- public bool EnableRequestProfile {
- get { return (bool)(ViewState[EnableRequestProfileViewStateKey] ?? EnableRequestProfileDefault); }
- set { ViewState[EnableRequestProfileViewStateKey] = value; }
- }
-
- #endregion
-
- #region IPostBackDataHandler Members
-
- /// <summary>
- /// When implemented by a class, processes postback data for an ASP.NET server control.
- /// </summary>
- /// <param name="postDataKey">The key identifier for the control.</param>
- /// <param name="postCollection">The collection of all incoming name values.</param>
- /// <returns>
- /// true if the server control's state changes as a result of the postback; otherwise, false.
- /// </returns>
- bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection) {
- return this.LoadPostData(postDataKey, postCollection);
- }
-
- /// <summary>
- /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
- /// </summary>
- void IPostBackDataHandler.RaisePostDataChangedEvent() {
- this.RaisePostDataChangedEvent();
- }
-
- #endregion
-
- /// <summary>
- /// Creates the authentication requests for a given user-supplied Identifier.
- /// </summary>
- /// <param name="identifier">The identifier to create a request for.</param>
- /// <returns>
- /// A sequence of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
- /// </returns>
- protected internal override IEnumerable<IAuthenticationRequest> CreateRequests(Identifier identifier) {
- ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
-
- // We delegate all our logic to another method, since invoking base. methods
- // within an iterator method results in unverifiable code.
- return this.CreateRequestsCore(base.CreateRequests(identifier));
- }
-
- /// <summary>
- /// Checks for incoming OpenID authentication responses and fires appropriate events.
- /// </summary>
- /// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnLoad(EventArgs e) {
- if (!this.Enabled) {
- return;
- }
-
- this.Page.RegisterRequiresPostBack(this);
- base.OnLoad(e);
- }
-
- /// <summary>
- /// Called when the <see cref="Identifier"/> property is changed.
- /// </summary>
- protected override void OnIdentifierChanged() {
- this.ViewState.Remove(TextViewStateKey);
- base.OnIdentifierChanged();
- }
-
- /// <summary>
- /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
- protected override void Render(HtmlTextWriter writer) {
- Contract.Assume(writer != null, "Missing contract.");
-
- if (this.ShowLogo) {
- string logoUrl = Page.ClientScript.GetWebResourceUrl(
- typeof(OpenIdTextBox), EmbeddedLogoResourceName);
- writer.AddStyleAttribute(
- HtmlTextWriterStyle.BackgroundImage,
- string.Format(CultureInfo.InvariantCulture, "url({0})", HttpUtility.HtmlEncode(logoUrl)));
- writer.AddStyleAttribute("background-repeat", "no-repeat");
- writer.AddStyleAttribute("background-position", "0 50%");
- writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, "18px");
- }
-
- if (this.PresetBorder) {
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "solid");
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "1px");
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, "lightgray");
- }
-
- if (!string.IsNullOrEmpty(this.CssClass)) {
- writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
- }
-
- writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
- writer.AddAttribute(HtmlTextWriterAttribute.Name, HttpUtility.HtmlEncode(this.Name));
- writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
- writer.AddAttribute(HtmlTextWriterAttribute.Size, this.Columns.ToString(CultureInfo.InvariantCulture));
- writer.AddAttribute(HtmlTextWriterAttribute.Value, HttpUtility.HtmlEncode(this.Text));
- writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, this.TabIndex.ToString(CultureInfo.CurrentCulture));
-
- writer.RenderBeginTag(HtmlTextWriterTag.Input);
- writer.RenderEndTag();
- }
-
- /// <summary>
- /// When implemented by a class, processes postback data for an ASP.NET server control.
- /// </summary>
- /// <param name="postDataKey">The key identifier for the control.</param>
- /// <param name="postCollection">The collection of all incoming name values.</param>
- /// <returns>
- /// true if the server control's state changes as a result of the postback; otherwise, false.
- /// </returns>
- protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
- Contract.Assume(postCollection != null, "Missing contract");
-
- // If the control was temporarily hidden, it won't be in the Form data,
- // and we'll just implicitly keep the last Text setting.
- if (postCollection[this.Name] != null) {
- this.Text = postCollection[this.Name];
- return true;
- }
-
- return false;
- }
-
- /// <summary>
- /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Preserve signature of interface we're implementing.")]
- protected virtual void RaisePostDataChangedEvent() {
- this.OnTextChanged();
- }
-
- /// <summary>
- /// Called on a postback when the Text property has changed.
- /// </summary>
- protected virtual void OnTextChanged() {
- EventHandler textChanged = this.TextChanged;
- if (textChanged != null) {
- textChanged(this, EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Creates the authentication requests for a given user-supplied Identifier.
- /// </summary>
- /// <param name="requests">The authentication requests to prepare.</param>
- /// <returns>
- /// A sequence of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
- /// </returns>
- private IEnumerable<IAuthenticationRequest> CreateRequestsCore(IEnumerable<IAuthenticationRequest> requests) {
- Contract.Requires(requests != null);
-
- foreach (var request in requests) {
- if (this.EnableRequestProfile) {
- this.AddProfileArgs(request);
- }
-
- yield return request;
- }
- }
-
- /// <summary>
- /// Adds extensions to a given authentication request to ask the Provider
- /// for user profile data.
- /// </summary>
- /// <param name="request">The authentication request to add the extensions to.</param>
- private void AddProfileArgs(IAuthenticationRequest request) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- var sreg = new ClaimsRequest() {
- Nickname = this.RequestNickname,
- Email = this.RequestEmail,
- FullName = this.RequestFullName,
- BirthDate = this.RequestBirthDate,
- Gender = this.RequestGender,
- PostalCode = this.RequestPostalCode,
- Country = this.RequestCountry,
- Language = this.RequestLanguage,
- TimeZone = this.RequestTimeZone,
- PolicyUrl = string.IsNullOrEmpty(this.PolicyUrl) ?
- null : new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.Page.ResolveUrl(this.PolicyUrl)),
- };
-
- // Only actually add the extension request if fields are actually being requested.
- if (!sreg.Equals(EmptyClaimsRequest)) {
- request.AddExtension(sreg);
- }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PopupBehavior.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PopupBehavior.cs
deleted file mode 100644
index e84f4f5..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/PopupBehavior.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="PopupBehavior.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- /// <summary>
- /// Several ways that the relying party can direct the user to the Provider
- /// to complete authentication.
- /// </summary>
- public enum PopupBehavior {
- /// <summary>
- /// A full browser window redirect will be used to send the
- /// user to the Provider.
- /// </summary>
- Never,
-
- /// <summary>
- /// A popup window will be used to send the user to the Provider.
- /// </summary>
- Always,
-
- /// <summary>
- /// A popup window will be used to send the user to the Provider
- /// if the Provider advertises support for the popup UI extension;
- /// otherwise a standard redirect is used.
- /// </summary>
- IfProviderSupported,
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButton.cs
deleted file mode 100644
index 0be3a5f..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButton.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="SelectorButton.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Diagnostics.Contracts;
- using System.Web.UI;
-
- /// <summary>
- /// A button that would appear in the <see cref="OpenIdSelector"/> control via its <see cref="OpenIdSelector.Buttons"/> collection.
- /// </summary>
- [ContractClass(typeof(SelectorButtonContract))]
- public abstract class SelectorButton {
- /// <summary>
- /// Initializes a new instance of the <see cref="SelectorButton"/> class.
- /// </summary>
- protected SelectorButton() {
- }
-
- /// <summary>
- /// Ensures that this button has been initialized to a valid state.
- /// </summary>
- /// <remarks>
- /// This is "internal" -- NOT "protected internal" deliberately. It makes it impossible
- /// to derive from this class outside the assembly, which suits our purposes since the
- /// <see cref="OpenIdSelector"/> control is not designed for an extensible set of button types.
- /// </remarks>
- internal abstract void EnsureValid();
-
- /// <summary>
- /// Renders the leading attributes for the LI tag.
- /// </summary>
- /// <param name="writer">The writer.</param>
- protected internal abstract void RenderLeadingAttributes(HtmlTextWriter writer);
-
- /// <summary>
- /// Renders the content of the button.
- /// </summary>
- /// <param name="writer">The writer.</param>
- /// <param name="selector">The containing selector control.</param>
- protected internal abstract void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector);
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButtonContract.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButtonContract.cs
deleted file mode 100644
index c70218a..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorButtonContract.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="SelectorButtonContract.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.Diagnostics.Contracts;
- using System.Web.UI;
-
- /// <summary>
- /// The contract class for the <see cref="SelectorButton"/> class.
- /// </summary>
- [ContractClassFor(typeof(SelectorButton))]
- internal abstract class SelectorButtonContract : SelectorButton {
- /// <summary>
- /// Ensures that this button has been initialized to a valid state.
- /// </summary>
- /// <remarks>
- /// This is "internal" -- NOT "protected internal" deliberately. It makes it impossible
- /// to derive from this class outside the assembly, which suits our purposes since the
- /// <see cref="OpenIdSelector"/> control is not designed for an extensible set of button types.
- /// </remarks>
- internal override void EnsureValid() {
- }
-
- /// <summary>
- /// Renders the leading attributes for the LI tag.
- /// </summary>
- /// <param name="writer">The writer.</param>
- protected internal override void RenderLeadingAttributes(HtmlTextWriter writer) {
- Contract.Requires<ArgumentNullException>(writer != null);
- }
-
- /// <summary>
- /// Renders the content of the button.
- /// </summary>
- /// <param name="writer">The writer.</param>
- /// <param name="selector">The containing selector control.</param>
- protected internal override void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector) {
- Contract.Requires<ArgumentNullException>(writer != null);
- Contract.Requires<ArgumentNullException>(selector != null);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorOpenIdButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorOpenIdButton.cs
deleted file mode 100644
index ac4dcbf..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorOpenIdButton.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="SelectorOpenIdButton.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.ComponentModel;
- using System.Diagnostics.Contracts;
- using System.Drawing.Design;
- using System.Web.UI;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// A button that appears in the <see cref="OpenIdSelector"/> control that
- /// allows the user to type in a user-supplied identifier.
- /// </summary>
- public class SelectorOpenIdButton : SelectorButton {
- /// <summary>
- /// Initializes a new instance of the <see cref="SelectorOpenIdButton"/> class.
- /// </summary>
- public SelectorOpenIdButton() {
- Reporting.RecordFeatureUse(this);
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SelectorOpenIdButton"/> class.
- /// </summary>
- /// <param name="imageUrl">The image to display on the button.</param>
- public SelectorOpenIdButton(string imageUrl)
- : this() {
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
-
- this.Image = imageUrl;
- }
-
- /// <summary>
- /// Gets or sets the path to the image to display on the button's surface.
- /// </summary>
- /// <value>The virtual path to the image.</value>
- [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- [UrlProperty]
- public string Image { get; set; }
-
- /// <summary>
- /// Ensures that this button has been initialized to a valid state.
- /// </summary>
- internal override void EnsureValid() {
- Contract.Ensures(!string.IsNullOrEmpty(this.Image));
-
- // Every button must have an image.
- ErrorUtilities.VerifyOperation(!string.IsNullOrEmpty(this.Image), OpenIdStrings.PropertyNotSet, "SelectorButton.Image");
- }
-
- /// <summary>
- /// Renders the leading attributes for the LI tag.
- /// </summary>
- /// <param name="writer">The writer.</param>
- protected internal override void RenderLeadingAttributes(HtmlTextWriter writer) {
- writer.AddAttribute(HtmlTextWriterAttribute.Id, "OpenIDButton");
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "OpenIDButton");
- }
-
- /// <summary>
- /// Renders the content of the button.
- /// </summary>
- /// <param name="writer">The writer.</param>
- /// <param name="selector">The containing selector control.</param>
- protected internal override void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector) {
- writer.AddAttribute(HtmlTextWriterAttribute.Src, selector.Page.ResolveUrl(this.Image));
- writer.RenderBeginTag(HtmlTextWriterTag.Img);
- writer.RenderEndTag();
-
- writer.AddAttribute(HtmlTextWriterAttribute.Src, selector.Page.ClientScript.GetWebResourceUrl(typeof(OpenIdAjaxTextBox), OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName));
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess");
- writer.AddAttribute(HtmlTextWriterAttribute.Title, selector.AuthenticatedAsToolTip);
- writer.RenderBeginTag(HtmlTextWriterTag.Img);
- writer.RenderEndTag();
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorProviderButton.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorProviderButton.cs
deleted file mode 100644
index 2195e73..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/SelectorProviderButton.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="SelectorProviderButton.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.RelyingParty {
- using System;
- using System.ComponentModel;
- using System.Diagnostics.Contracts;
- using System.Drawing.Design;
- using System.Web.UI;
- using DotNetOpenAuth.ComponentModel;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// A button that appears in the <see cref="OpenIdSelector"/> control that
- /// provides one-click access to a popular OpenID Provider.
- /// </summary>
- public class SelectorProviderButton : SelectorButton {
- /// <summary>
- /// Initializes a new instance of the <see cref="SelectorProviderButton"/> class.
- /// </summary>
- public SelectorProviderButton() {
- Reporting.RecordFeatureUse(this);
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SelectorProviderButton"/> class.
- /// </summary>
- /// <param name="providerIdentifier">The OP Identifier.</param>
- /// <param name="imageUrl">The image to display on the button.</param>
- public SelectorProviderButton(Identifier providerIdentifier, string imageUrl)
- : this() {
- Contract.Requires<ArgumentNullException>(providerIdentifier != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl));
-
- this.OPIdentifier = providerIdentifier;
- this.Image = imageUrl;
- }
-
- /// <summary>
- /// Gets or sets the path to the image to display on the button's surface.
- /// </summary>
- /// <value>The virtual path to the image.</value>
- [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- [UrlProperty]
- public string Image { get; set; }
-
- /// <summary>
- /// Gets or sets the OP Identifier represented by the button.
- /// </summary>
- /// <value>
- /// The OP identifier, which may be provided in the easiest "user-supplied identifier" form,
- /// but for security should be provided with a leading https:// if possible.
- /// For example: "yahoo.com" or "https://me.yahoo.com/".
- /// </value>
- [TypeConverter(typeof(IdentifierConverter))]
- public Identifier OPIdentifier { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this Provider doesn't handle
- /// checkid_immediate messages correctly and background authentication
- /// should not be attempted.
- /// </summary>
- public bool SkipBackgroundAuthentication { get; set; }
-
- /// <summary>
- /// Ensures that this button has been initialized to a valid state.
- /// </summary>
- internal override void EnsureValid() {
- Contract.Ensures(!string.IsNullOrEmpty(this.Image));
- Contract.Ensures(this.OPIdentifier != null);
-
- // Every button must have an image.
- ErrorUtilities.VerifyOperation(!string.IsNullOrEmpty(this.Image), OpenIdStrings.PropertyNotSet, "SelectorButton.Image");
-
- // Every button must have exactly one purpose.
- ErrorUtilities.VerifyOperation(this.OPIdentifier != null, OpenIdStrings.PropertyNotSet, "SelectorButton.OPIdentifier");
- }
-
- /// <summary>
- /// Renders the leading attributes for the LI tag.
- /// </summary>
- /// <param name="writer">The writer.</param>
- protected internal override void RenderLeadingAttributes(HtmlTextWriter writer) {
- writer.AddAttribute(HtmlTextWriterAttribute.Id, this.OPIdentifier);
-
- string style = "OPButton";
- if (this.SkipBackgroundAuthentication) {
- style += " NoAsyncAuth";
- }
- writer.AddAttribute(HtmlTextWriterAttribute.Class, style);
- }
-
- /// <summary>
- /// Renders the content of the button.
- /// </summary>
- /// <param name="writer">The writer.</param>
- /// <param name="selector">The containing selector control.</param>
- protected internal override void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector) {
- writer.AddAttribute(HtmlTextWriterAttribute.Src, selector.Page.ResolveUrl(this.Image));
- writer.RenderBeginTag(HtmlTextWriterTag.Img);
- writer.RenderEndTag();
-
- writer.AddAttribute(HtmlTextWriterAttribute.Src, selector.Page.ClientScript.GetWebResourceUrl(typeof(OpenIdAjaxTextBox), OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName));
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess");
- writer.AddAttribute(HtmlTextWriterAttribute.Title, selector.AuthenticatedAsToolTip);
- writer.RenderBeginTag(HtmlTextWriterTag.Img);
- writer.RenderEndTag();
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_failure.png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_failure.png
deleted file mode 100644
index 8003700..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_failure.png
+++ /dev/null
Binary files differ
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success (lock).png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success (lock).png
deleted file mode 100644
index bc0c0c8..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success (lock).png
+++ /dev/null
Binary files differ
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success.png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success.png
deleted file mode 100644
index 0ae1365..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/login_success.png
+++ /dev/null
Binary files differ
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/openid_login.png b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/openid_login.png
deleted file mode 100644
index caebd58..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/openid_login.png
+++ /dev/null
Binary files differ
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/spinner.gif b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/spinner.gif
deleted file mode 100644
index 9cb298e..0000000
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/spinner.gif
+++ /dev/null
Binary files differ
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/Properties/AssemblyInfo.cs
index 2961dc2..e2dd3d0 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/Properties/AssemblyInfo.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty/Properties/AssemblyInfo.cs
@@ -50,7 +50,9 @@ using System.Web.UI;
[assembly: InternalsVisibleTo("DotNetOpenAuth.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")]
[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.Provider, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.RelyingParty.UI, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")]
#else
[assembly: InternalsVisibleTo("DotNetOpenAuth.Test")]
[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.Provider")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OpenId.RelyingParty.UI")]
#endif