summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs14
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs69
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs93
3 files changed, 78 insertions, 98 deletions
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index a52f51b..8ae228d 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -473,6 +473,20 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Flattens the specified sequence of sequences.
+ /// </summary>
+ /// <typeparam name="T">The type of element contained in the sequence.</typeparam>
+ /// <param name="sequence">The sequence of sequences to flatten.</param>
+ /// <returns>A sequence of the contained items.</returns>
+ internal static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> sequence) {
+ foreach (IEnumerable<T> subsequence in sequence) {
+ foreach (T item in subsequence) {
+ yield return item;
+ }
+ }
+ }
+
+ /// <summary>
/// Tests whether two arrays are equal in contents and ordering.
/// </summary>
/// <typeparam name="T">The type of elements in the arrays.</typeparam>
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
index e2ddf16..536019b 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxRelyingParty.cs
@@ -112,9 +112,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
- /// Performs discovery on some identifier on behalf of Javascript running on the browser.
+ /// Serializes discovery results on some <i>single</i> identifier on behalf of Javascript running on the browser.
/// </summary>
- /// <param name="requests">The identifier discovery results to serialize as a JSON response.</param>
+ /// <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>
@@ -139,36 +139,81 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
public OutgoingWebResponse AsAjaxDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
Contract.Requires<ArgumentNullException>(requests != null);
+ var serializer = new JavaScriptSerializer();
return new OutgoingWebResponse {
- Body = this.AsJsonDiscoveryResult(requests),
+ 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 authentication requests.</param>
- /// <returns>A JSON string.</returns>
- private string AsJsonDiscoveryResult(IEnumerable<IAuthenticationRequest> requests) {
+ /// <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();
- JavaScriptSerializer serializer = new JavaScriptSerializer();
- string json;
if (requests.Any()) {
- json = serializer.Serialize(new {
+ return new {
claimedIdentifier = 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 {
- json = serializer.Serialize(new {
+ 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 = requestsByIdentifier.Key.ToString(),
+ discoveryResult = this.AsJsonDiscoveryResult(requestsByIdentifier),
+ }).ToArray();
return json;
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
index 7153aa2..37ba8c1 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
@@ -16,6 +16,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.Linq;
using System.Text;
using System.Web;
+ using System.Web.Script.Serialization;
using System.Web.UI;
using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
@@ -289,7 +290,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
Logger.OpenId.InfoFormat("AJAX discovery on {0} requested.", userSuppliedIdentifier);
this.Identifier = userSuppliedIdentifier;
- this.discoveryResult = this.SerializeDiscoveryAsJson(this.Identifier);
+
+ var serializer = new JavaScriptSerializer();
+ IEnumerable<IAuthenticationRequest> requests = this.CreateRequests(this.Identifier);
+ this.discoveryResult = serializer.Serialize(this.AjaxRelyingParty.AsJsonDiscoveryResult(requests));
}
/// <summary>
@@ -316,8 +320,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="identifiers">The identifiers to perform discovery on.</param>
protected void PreloadDiscovery(IEnumerable<Identifier> identifiers) {
- string discoveryResults = this.SerializeDiscoveryAsJson(identifiers);
- string script = "window.dnoa_internal.loadPreloadedDiscoveryResults(" + discoveryResults + ");";
+ string script = this.AjaxRelyingParty.AsAjaxPreloadedDiscoveryResult(
+ identifiers.Select(id => this.CreateRequests(id)).Flatten());
this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyAjaxControlBase), this.ClientID, script, true);
}
@@ -427,89 +431,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
- /// Serializes the discovery of multiple identifiers as a JSON object.
- /// </summary>
- /// <param name="identifiers">The identifiers to perform discovery on and create requests for.</param>
- /// <returns>The serialized JSON object.</returns>
- private string SerializeDiscoveryAsJson(IEnumerable<Identifier> identifiers) {
- ErrorUtilities.VerifyArgumentNotNull(identifiers, "identifiers");
-
- // 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)
- // }
- StringBuilder discoveryResultBuilder = new StringBuilder();
- discoveryResultBuilder.Append("[");
- foreach (var identifier in identifiers) { // TODO: parallelize discovery on these identifiers
- discoveryResultBuilder.Append("{");
- discoveryResultBuilder.AppendFormat("userSuppliedIdentifier: {0},", MessagingUtilities.GetSafeJavascriptValue(identifier));
- discoveryResultBuilder.AppendFormat("discoveryResult: {0}", this.SerializeDiscoveryAsJson(identifier));
- discoveryResultBuilder.Append("},");
- }
-
- discoveryResultBuilder.Length -= 1; // trim last comma
- discoveryResultBuilder.Append("]");
- return discoveryResultBuilder.ToString();
- }
-
- /// <summary>
- /// Serializes the results of discovery and the created auth requests as a JSON object
- /// for the user agent to initiate.
- /// </summary>
- /// <param name="identifier">The identifier to perform discovery on.</param>
- /// <returns>The JSON string.</returns>
- private string SerializeDiscoveryAsJson(Identifier identifier) {
- ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
-
- // We prepare a JSON object with this interface:
- // class jsonResponse {
- // string claimedIdentifier;
- // Array requests; // never null
- // string error; // null if no error
- // }
- // Each element in the requests array looks like this:
- // 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.
- // }
- StringBuilder discoveryResultBuilder = new StringBuilder();
- discoveryResultBuilder.Append("{");
- try {
- IEnumerable<IAuthenticationRequest> requests = this.CreateRequests(identifier).CacheGeneratedResults();
- if (requests.Any()) {
- discoveryResultBuilder.AppendFormat("claimedIdentifier: {0},", MessagingUtilities.GetSafeJavascriptValue(requests.First().ClaimedIdentifier));
- discoveryResultBuilder.Append("requests: [");
- foreach (IAuthenticationRequest request in requests) {
- discoveryResultBuilder.Append("{");
- discoveryResultBuilder.AppendFormat("endpoint: {0},", MessagingUtilities.GetSafeJavascriptValue(request.Provider.Uri.AbsoluteUri));
- request.Mode = AuthenticationRequestMode.Immediate;
- OutgoingWebResponse response = request.RedirectingResponse;
- discoveryResultBuilder.AppendFormat("immediate: {0},", MessagingUtilities.GetSafeJavascriptValue(response.GetDirectUriRequest(this.RelyingParty.Channel).AbsoluteUri));
- request.Mode = AuthenticationRequestMode.Setup;
- response = request.RedirectingResponse;
- discoveryResultBuilder.AppendFormat("setup: {0}", MessagingUtilities.GetSafeJavascriptValue(response.GetDirectUriRequest(this.RelyingParty.Channel).AbsoluteUri));
- discoveryResultBuilder.Append("},");
- }
- discoveryResultBuilder.Length -= 1; // trim off last comma
- discoveryResultBuilder.Append("]");
- } else {
- discoveryResultBuilder.Append("requests: [],");
- discoveryResultBuilder.AppendFormat("error: {0}", MessagingUtilities.GetSafeJavascriptValue(OpenIdStrings.OpenIdEndpointNotFound));
- }
- } catch (ProtocolException ex) {
- discoveryResultBuilder.Append("requests: [],");
- discoveryResultBuilder.AppendFormat("error: {0}", MessagingUtilities.GetSafeJavascriptValue(ex.Message));
- }
-
- discoveryResultBuilder.Append("}");
- return discoveryResultBuilder.ToString();
- }
-
- /// <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>