summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-12-01 07:37:00 -0800
committerAndrew <andrewarnott@gmail.com>2008-12-01 07:37:00 -0800
commit9c85108a3a0b242c4ed5ae33da52df16c95c0ce3 (patch)
tree7aea92ec71dab0d1932f277cd77e4a2823b0c211 /src
parent98f10d7920e2d957f6aff937b9dd253f84145668 (diff)
downloadDotNetOpenAuth-9c85108a3a0b242c4ed5ae33da52df16c95c0ce3.zip
DotNetOpenAuth-9c85108a3a0b242c4ed5ae33da52df16c95c0ce3.tar.gz
DotNetOpenAuth-9c85108a3a0b242c4ed5ae33da52df16c95c0ce3.tar.bz2
Lots of stylecop work.
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/TestSupport.cs4
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs4
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs2
-rw-r--r--src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs24
-rw-r--r--src/DotNetOpenAuth/OpenId/Protocol.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/ProviderDescription.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs75
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs6
-rw-r--r--src/DotNetOpenAuth/OpenId/UriIdentifier.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/XriIdentifier.cs15
-rw-r--r--src/DotNetOpenAuth/Util.cs49
-rw-r--r--src/DotNetOpenAuth/Xrds/ServiceElement.cs51
-rw-r--r--src/DotNetOpenAuth/Xrds/TypeElement.cs11
-rw-r--r--src/DotNetOpenAuth/Xrds/UriElement.cs32
-rw-r--r--src/DotNetOpenAuth/Xrds/XrdElement.cs36
-rw-r--r--src/DotNetOpenAuth/Xrds/XrdsDocument.cs76
-rw-r--r--src/DotNetOpenAuth/Xrds/XrdsNode.cs21
-rw-r--r--src/DotNetOpenAuth/Yadis/HtmlParser.cs54
-rw-r--r--src/DotNetOpenAuth/Yadis/Yadis.cs25
20 files changed, 441 insertions, 63 deletions
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs
index 94d6f81..6c853af 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs
@@ -133,7 +133,7 @@ namespace DotNetOpenAuth.Test.Mocks {
directedIdentityAssignedIdentifier,
directedIdentityAssignedIdentifier,
providerEndpoint.ProviderEndpoint,
- new string[] { providerEndpoint.Protocol.ClaimedIdentifierServiceTypeURI },
+ providerEndpoint.ProviderDescription,
10,
10);
this.RegisterMockXrdsResponse(identityEndpoint);
diff --git a/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs b/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs
index 665c041..c80fa97 100644
--- a/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs
@@ -144,11 +144,11 @@ namespace DotNetOpenAuth.Test.OpenId {
}
internal static ServiceEndpoint GetServiceEndpoint(Scenarios scenario, ProtocolVersion providerVersion, int servicePriority, bool useSsl) {
+ var providerEndpoint = new ProviderEndpointDescription(GetFullUrl("/" + ProviderPage, null, useSsl), new string[] { Protocol.Lookup(providerVersion).ClaimedIdentifierServiceTypeURI });
return ServiceEndpoint.CreateForClaimedIdentifier(
GetIdentityUrl(scenario, providerVersion, useSsl),
GetDelegateUrl(scenario, useSsl),
- GetFullUrl("/" + ProviderPage, null, useSsl),
- new string[] { Protocol.Lookup(providerVersion).ClaimedIdentifierServiceTypeURI },
+ providerEndpoint,
servicePriority,
10);
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs
index f4433f0..91dd5f4 100644
--- a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs
@@ -375,8 +375,8 @@ namespace DotNetOpenAuth.Test.OpenId {
Assert.AreSame(protocol, se.Protocol);
Assert.AreEqual(claimedId, se.ClaimedIdentifier);
Assert.AreEqual(expectedLocalId, se.ProviderLocalIdentifier);
- Assert.AreEqual(expectSreg ? 2 : 1, se.ProviderSupportedServiceTypeUris.Length);
- Assert.IsTrue(Array.IndexOf(se.ProviderSupportedServiceTypeUris, protocol.ClaimedIdentifierServiceTypeURI) >= 0);
+ Assert.AreEqual(expectSreg ? 2 : 1, se.ProviderSupportedServiceTypeUris.Count);
+ Assert.IsTrue(se.ProviderSupportedServiceTypeUris.Contains(protocol.ClaimedIdentifierServiceTypeURI));
// TODO: re-enable this line once extensions support is added back in.
////Assert.AreEqual(expectSreg, se.IsExtensionSupported(new ClaimsRequest()));
diff --git a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs
index b6b2e55..d84b8b1 100644
--- a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs
@@ -463,7 +463,7 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy
if (expectedClaimedIdentifier != null) {
Assert.IsNotNull(se);
Assert.AreEqual(expectedClaimedIdentifier, se.ClaimedIdentifier.ToString(), "i-name {0} discovery resulted in unexpected CanonicalId", iname);
- Assert.IsTrue(se.ProviderSupportedServiceTypeUris.Length > 0);
+ Assert.IsTrue(se.ProviderSupportedServiceTypeUris.Count > 0);
} else {
Assert.IsNull(se);
}
diff --git a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
index 5678cc4..24a989c 100644
--- a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
+++ b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
@@ -275,6 +275,13 @@ namespace DotNetOpenAuth.Messaging {
#endregion
+ /// <summary>
+ /// Determines whether a given host is whitelisted.
+ /// </summary>
+ /// <param name="host">The host name to test.</param>
+ /// <returns>
+ /// <c>true</c> if the host is whitelisted; otherwise, <c>false</c>.
+ /// </returns>
private bool IsHostWhitelisted(string host) {
return this.IsHostInList(host, this.WhitelistHosts, this.WhitelistHostsRegex);
}
@@ -330,7 +337,7 @@ namespace DotNetOpenAuth.Messaging {
/// Determines whether a URI is allowed based on scheme and host name.
/// No requireSSL check is done here
/// </summary>
- /// <param name="uri">The URI.</param>
+ /// <param name="uri">The URI to test for whether it should be allowed.</param>
/// <returns>
/// <c>true</c> if [is URI allowable] [the specified URI]; otherwise, <c>false</c>.
/// </returns>
@@ -389,6 +396,13 @@ namespace DotNetOpenAuth.Messaging {
return true;
}
+ /// <summary>
+ /// Determines whether an IP address is the IPv6 equivalent of "localhost/127.0.0.1".
+ /// </summary>
+ /// <param name="ip">The ip address to check.</param>
+ /// <returns>
+ /// <c>true</c> if this is a loopback IP address; <c>false</c> otherwise.
+ /// </returns>
private bool IsIPv6Loopback(IPAddress ip) {
ErrorUtilities.VerifyArgumentNotNull(ip, "ip");
byte[] addressBytes = ip.GetAddressBytes();
@@ -403,7 +417,11 @@ namespace DotNetOpenAuth.Messaging {
return true;
}
- private HttpWebRequest PrepareRequest(HttpWebRequest request) {
+ /// <summary>
+ /// Prepares the request by setting timeout and redirect policies.
+ /// </summary>
+ /// <param name="request">The request to prepare.</param>
+ private void PrepareRequest(HttpWebRequest request) {
// Set/override a few properties of the request to apply our policies for untrusted requests.
request.ReadWriteTimeout = (int)this.ReadWriteTimeout.TotalMilliseconds;
request.Timeout = (int)this.Timeout.TotalMilliseconds;
@@ -413,8 +431,6 @@ namespace DotNetOpenAuth.Messaging {
// it may include a pass through an unprotected HTTP request.
// We have to follow redirects manually.
request.AllowAutoRedirect = false;
-
- return request;
}
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Protocol.cs b/src/DotNetOpenAuth/OpenId/Protocol.cs
index 77041cb..5f2807b 100644
--- a/src/DotNetOpenAuth/OpenId/Protocol.cs
+++ b/src/DotNetOpenAuth/OpenId/Protocol.cs
@@ -168,7 +168,7 @@ namespace DotNetOpenAuth.OpenId {
/// Attemps to detect the highest OpenID protocol version supported given a set
/// of XRDS Service Type URIs included for some service.
/// </summary>
- internal static Protocol Detect(string[] serviceTypeURIs) {
+ internal static Protocol Detect(IEnumerable<string> serviceTypeURIs) {
if (serviceTypeURIs == null) throw new ArgumentNullException("serviceTypeURIs");
return FindBestVersion(p => p.OPIdentifierServiceTypeURI, serviceTypeURIs) ??
FindBestVersion(p => p.ClaimedIdentifierServiceTypeURI, serviceTypeURIs) ??
diff --git a/src/DotNetOpenAuth/OpenId/ProviderDescription.cs b/src/DotNetOpenAuth/OpenId/ProviderDescription.cs
index 0995d93..6a72e06 100644
--- a/src/DotNetOpenAuth/OpenId/ProviderDescription.cs
+++ b/src/DotNetOpenAuth/OpenId/ProviderDescription.cs
@@ -31,6 +31,11 @@ namespace DotNetOpenAuth.OpenId {
this.ProtocolVersion = openIdVersion;
}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProviderEndpointDescription"/> class.
+ /// </summary>
+ /// <param name="providerEndpoint">The URI the provider listens on for OpenID requests.</param>
+ /// <param name="serviceTypeURIs">The set of services offered by this endpoint.</param>
internal ProviderEndpointDescription(Uri providerEndpoint, IEnumerable<string> serviceTypeURIs) {
ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
ErrorUtilities.VerifyArgumentNotNull(serviceTypeURIs, "serviceTypeURIs");
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs
index 386e9c9..98a0d3c 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs
@@ -6,9 +6,8 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
- using System.Collections.Generic;
+ using System.Collections.ObjectModel;
using System.Diagnostics;
- using System.Globalization;
using System.IO;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -18,20 +17,35 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
[DebuggerDisplay("ClaimedIdentifier: {ClaimedIdentifier}, ProviderEndpoint: {ProviderEndpoint}, OpenId: {Protocol.Version}")]
internal class ServiceEndpoint : IXrdsProviderEndpoint {
+ /// <summary>
+ /// The i-name identifier the user actually typed in
+ /// or the url identifier with the scheme stripped off.
+ /// </summary>
private string friendlyIdentifierForDisplay;
+
+ /// <summary>
+ /// The OpenID protocol version used at the identity Provider.
+ /// </summary>
private Protocol protocol;
+
+ /// <summary>
+ /// The @priority given in the XRDS document for this specific OP endpoint.
+ /// </summary>
private int? uriPriority;
+
+ /// <summary>
+ /// The @priority given in the XRDS document for this service
+ /// (which may consist of several endpoints).
+ /// </summary>
private int? servicePriority;
- private ServiceEndpoint(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Uri providerEndpoint, Identifier providerLocalIdentifier, string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) {
+ private ServiceEndpoint(ProviderEndpointDescription providerEndpoint, Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, int? servicePriority, int? uriPriority) {
ErrorUtilities.VerifyArgumentNotNull(claimedIdentifier, "claimedIdentifier");
ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
- ErrorUtilities.VerifyArgumentNotNull(providerSupportedServiceTypeUris, "providerSupportedServiceTypeUris");
+ this.ProviderDescription = providerEndpoint;
this.ClaimedIdentifier = claimedIdentifier;
this.UserSuppliedIdentifier = userSuppliedIdentifier;
- this.ProviderEndpoint = providerEndpoint;
this.ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier;
- this.ProviderSupportedServiceTypeUris = providerSupportedServiceTypeUris;
this.servicePriority = servicePriority;
this.uriPriority = uriPriority;
}
@@ -42,7 +56,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private ServiceEndpoint(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Uri providerEndpoint, Identifier providerLocalIdentifier, Protocol protocol) {
this.ClaimedIdentifier = claimedIdentifier;
this.UserSuppliedIdentifier = userSuppliedIdentifier;
- this.ProviderEndpoint = providerEndpoint;
+ this.ProviderDescription = new ProviderEndpointDescription(providerEndpoint, protocol.Version);
this.ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier;
this.protocol = protocol;
}
@@ -56,7 +70,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Obtained by performing discovery on the User-Supplied Identifier.
/// This value MUST be an absolute HTTP or HTTPS URL.
/// </remarks>
- public Uri ProviderEndpoint { get; private set; }
+ public Uri ProviderEndpoint {
+ get { return this.ProviderDescription.Endpoint; }
+ }
/*
/// <summary>
@@ -124,7 +140,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Gets the list of services available at this OP Endpoint for the
/// claimed Identifier. May be null.
/// </summary>
- public string[] ProviderSupportedServiceTypeUris { get; private set; }
+ public ReadOnlyCollection<string> ProviderSupportedServiceTypeUris {
+ get { return this.ProviderDescription.Capabilities; }
+ }
/// <summary>
/// Gets the OpenID protocol used by the Provider.
@@ -160,6 +178,17 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
+ Version IProviderEndpoint.Version { get { return Protocol.Version; } }
+
+ /// <summary>
+ /// Gets a value indicating whether the <see cref="ProviderEndpoint"/> is using an encrypted channel.
+ /// </summary>
+ internal bool IsSecure {
+ get { return string.Equals(this.ProviderEndpoint.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase); }
+ }
+
+ internal ProviderEndpointDescription ProviderDescription { get; set; }
+
public static bool operator ==(ServiceEndpoint se1, ServiceEndpoint se2) {
return se1.EqualsNullSafe(se2);
}
@@ -176,7 +205,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
if (this.ProviderSupportedServiceTypeUris == null) {
throw new InvalidOperationException("Cannot lookup extension support on a rehydrated ServiceEndpoint.");
}
- return Array.IndexOf(this.ProviderSupportedServiceTypeUris, extensionUri) >= 0;
+ return this.ProviderSupportedServiceTypeUris.Contains(extensionUri);
}
////public bool IsExtensionSupported(IExtension extension) {
@@ -212,15 +241,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
//// return IsExtensionSupported(extension);
////}
- Version IProviderEndpoint.Version { get { return Protocol.Version; } }
-
- /// <summary>
- /// Gets a value indicating whether the <see cref="ProviderEndpoint"/> is using an encrypted channel.
- /// </summary>
- internal bool IsSecure {
- get { return string.Equals(this.ProviderEndpoint.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase); }
- }
-
public override bool Equals(object obj) {
ServiceEndpoint other = obj as ServiceEndpoint;
if (other == null) {
@@ -289,25 +309,26 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
return new ServiceEndpoint(claimedIdentifier, userSuppliedIdentifier, providerEndpoint, providerLocalIdentifier, protocol);
}
- internal static ServiceEndpoint CreateForProviderIdentifier(Identifier providerIdentifier, Uri providerEndpoint, string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) {
- Protocol protocol = Protocol.Detect(providerSupportedServiceTypeUris);
+ internal static ServiceEndpoint CreateForProviderIdentifier(Identifier providerIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) {
+ ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
+
+ Protocol protocol = Protocol.Detect(providerEndpoint.Capabilities);
return new ServiceEndpoint(
+ providerEndpoint,
protocol.ClaimedIdentifierForOPIdentifier,
providerIdentifier,
- providerEndpoint,
protocol.ClaimedIdentifierForOPIdentifier,
- providerSupportedServiceTypeUris,
servicePriority,
uriPriority);
}
- internal static ServiceEndpoint CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier providerLocalIdentifier, Uri providerEndpoint, string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) {
- return CreateForClaimedIdentifier(claimedIdentifier, null, providerLocalIdentifier, providerEndpoint, providerSupportedServiceTypeUris, servicePriority, uriPriority);
+ internal static ServiceEndpoint CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier providerLocalIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) {
+ return CreateForClaimedIdentifier(claimedIdentifier, null, providerLocalIdentifier, providerEndpoint, servicePriority, uriPriority);
}
- internal static ServiceEndpoint CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, Uri providerEndpoint, string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) {
- return new ServiceEndpoint(claimedIdentifier, userSuppliedIdentifier, providerEndpoint, providerLocalIdentifier, providerSupportedServiceTypeUris, servicePriority, uriPriority);
+ internal static ServiceEndpoint CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) {
+ return new ServiceEndpoint(providerEndpoint, claimedIdentifier, userSuppliedIdentifier, providerLocalIdentifier, servicePriority, uriPriority);
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs
index 56851cf..112506b 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs
@@ -39,6 +39,12 @@ namespace DotNetOpenAuth.OpenId {
/// </summary>
public Protocol Protocol { get; private set; }
+ /// <summary>
+ /// Derives the highest OpenID protocol that this library and the OpenID Provider have
+ /// in common.
+ /// </summary>
+ /// <param name="supportedServiceTypeUris">The supported service type URIs.</param>
+ /// <returns>The best OpenID protocol version to use when communicating with this Provider.</returns>
private static Protocol GetProtocolFromServices(string[] supportedServiceTypeUris) {
Protocol protocol = Protocol.FindBestVersion(p => p.RPReturnToTypeURI, supportedServiceTypeUris);
if (protocol == null) {
diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
index 194dafe..af8dd66 100644
--- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
@@ -196,6 +196,13 @@ namespace DotNetOpenAuth.OpenId {
return true;
}
+ /// <summary>
+ /// Performs discovery on the Identifier.
+ /// </summary>
+ /// <param name="requestHandler">The web request handler to use for discovery.</param>
+ /// <returns>
+ /// An initialized structure containing the discovered provider endpoint information.
+ /// </returns>
internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) {
List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>();
@@ -353,7 +360,8 @@ namespace DotNetOpenAuth.OpenId {
// Choose the TypeURI to match the OpenID version detected.
string[] typeURIs = { discoveredProtocol.ClaimedIdentifierServiceTypeURI };
- return ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, providerLocalIdentifier, providerEndpoint, typeURIs, (int?)null, (int?)null);
+ var providerDescription = new ProviderEndpointDescription(providerEndpoint, typeURIs);
+ return ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, providerLocalIdentifier, providerDescription, (int?)null, (int?)null);
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
index 058a8a4..22e1f7c 100644
--- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
@@ -149,6 +149,13 @@ namespace DotNetOpenAuth.OpenId {
|| xri.StartsWith(XriScheme, StringComparison.OrdinalIgnoreCase);
}
+ /// <summary>
+ /// Performs discovery on the Identifier.
+ /// </summary>
+ /// <param name="requestHandler">The web request handler to use for discovery.</param>
+ /// <returns>
+ /// An initialized structure containing the discovered provider endpoint information.
+ /// </returns>
internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) {
return this.DownloadXrds(requestHandler).CreateServiceEndpoints(this);
}
@@ -157,6 +164,9 @@ namespace DotNetOpenAuth.OpenId {
/// Performs discovery on THIS identifier, but generates <see cref="ServiceEndpoint"/>
/// instances that treat another given identifier as the user-supplied identifier.
/// </summary>
+ /// <param name="requestHandler">The request handler to use in discovery.</param>
+ /// <param name="userSuppliedIdentifier">The user supplied identifier, which may differ from this XRI instance due to multiple discovery steps.</param>
+ /// <returns>A list of service endpoints offered for this identifier.</returns>
internal IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler, XriIdentifier userSuppliedIdentifier) {
return this.DownloadXrds(requestHandler).CreateServiceEndpoints(userSuppliedIdentifier);
}
@@ -209,6 +219,11 @@ namespace DotNetOpenAuth.OpenId {
return xri;
}
+ /// <summary>
+ /// Downloads the XRDS document for this XRI.
+ /// </summary>
+ /// <param name="requestHandler">The request handler.</param>
+ /// <returns>The XRDS document.</returns>
private XrdsDocument DownloadXrds(IDirectSslWebRequestHandler requestHandler) {
XrdsDocument doc;
using (var xrdsResponse = Yadis.Request(requestHandler, this.XrdsUrl, this.IsDiscoverySecureEndToEnd)) {
diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs
index 5ee7302..00ba56f 100644
--- a/src/DotNetOpenAuth/Util.cs
+++ b/src/DotNetOpenAuth/Util.cs
@@ -54,8 +54,12 @@ namespace DotNetOpenAuth {
/// <summary>
/// Prepares a dictionary for printing as a string.
/// </summary>
+ /// <typeparam name="K">The type of the key.</typeparam>
+ /// <typeparam name="V">The type of the value.</typeparam>
+ /// <param name="pairs">The dictionary or sequence of name-value pairs.</param>
+ /// <returns>An object whose ToString method will perform the actual work of generating the string.</returns>
/// <remarks>
- /// The work isn't done until (and if) the
+ /// The work isn't done until (and if) the
/// <see cref="Object.ToString"/> method is actually called, which makes it great
/// for logging complex objects without being in a conditional block.
/// </remarks>
@@ -72,10 +76,24 @@ namespace DotNetOpenAuth {
});
}
+ /// <summary>
+ /// Offers deferred ToString processing for a list of elements, that are assumed
+ /// to generate just a single-line string.
+ /// </summary>
+ /// <typeparam name="T">The type of elements contained in the list.</typeparam>
+ /// <param name="list">The list of elements.</param>
+ /// <returns>An object whose ToString method will perform the actual work of generating the string.</returns>
internal static object ToStringDeferred<T>(this IEnumerable<T> list) {
return ToStringDeferred<T>(list, false);
}
+ /// <summary>
+ /// Offers deferred ToString processing for a list of elements.
+ /// </summary>
+ /// <typeparam name="T">The type of elements contained in the list.</typeparam>
+ /// <param name="list">The list of elements.</param>
+ /// <param name="multiLineElements">if set to <c>true</c>, special formatting will be applied to the output to make it clear where one element ends and the next begins.</param>
+ /// <returns>An object whose ToString method will perform the actual work of generating the string.</returns>
internal static object ToStringDeferred<T>(this IEnumerable<T> list, bool multiLineElements) {
return new DelayedToString<IEnumerable<T>>(
list,
@@ -119,24 +137,37 @@ namespace DotNetOpenAuth {
});
}
- internal static HttpWebRequest CreatePostRequest(Uri requestUri, string body) {
- HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
- request.ContentType = "application/x-www-form-urlencoded";
- request.ContentLength = body.Length;
- request.Method = "POST";
- return request;
- }
-
+ /// <summary>
+ /// Manages an individual deferred ToString call.
+ /// </summary>
+ /// <typeparam name="T">The type of object to be serialized as a string.</typeparam>
private class DelayedToString<T> {
+ /// <summary>
+ /// The object that will be serialized if called upon.
+ /// </summary>
private T obj;
+ /// <summary>
+ /// The method used to serialize <see cref="obj"/> to string form.
+ /// </summary>
private Func<T, string> toString;
+ /// <summary>
+ /// Initializes a new instance of the DelayedToString class.
+ /// </summary>
+ /// <param name="obj">The object that may be serialized to string form.</param>
+ /// <param name="toString">The method that will serialize the object if called upon.</param>
public DelayedToString(T obj, Func<T, string> toString) {
this.obj = obj;
this.toString = toString;
}
+ /// <summary>
+ /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
+ /// </returns>
public override string ToString() {
return this.toString(this.obj);
}
diff --git a/src/DotNetOpenAuth/Xrds/ServiceElement.cs b/src/DotNetOpenAuth/Xrds/ServiceElement.cs
index ce9cd49..69b77ba 100644
--- a/src/DotNetOpenAuth/Xrds/ServiceElement.cs
+++ b/src/DotNetOpenAuth/Xrds/ServiceElement.cs
@@ -7,18 +7,33 @@
namespace DotNetOpenAuth.Xrds {
using System;
using System.Collections.Generic;
+ using System.Linq;
using System.Xml.XPath;
using DotNetOpenAuth.OpenId;
+ /// <summary>
+ /// The Service element in an XRDS document.
+ /// </summary>
internal class ServiceElement : XrdsNode, IComparable<ServiceElement> {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ServiceElement"/> class.
+ /// </summary>
+ /// <param name="serviceElement">The service element.</param>
+ /// <param name="parent">The parent.</param>
public ServiceElement(XPathNavigator serviceElement, XrdElement parent) :
base(serviceElement, parent) {
}
+ /// <summary>
+ /// Gets the XRD parent element.
+ /// </summary>
public XrdElement Xrd {
get { return (XrdElement)ParentNode; }
}
+ /// <summary>
+ /// Gets the priority.
+ /// </summary>
public int? Priority {
get {
XPathNavigator n = Node.SelectSingleNode("@priority", XmlNamespaceResolver);
@@ -26,6 +41,9 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets the URI child elements.
+ /// </summary>
public IEnumerable<UriElement> UriElements {
get {
List<UriElement> uris = new List<UriElement>();
@@ -37,6 +55,10 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets the type child elements.
+ /// </summary>
+ /// <value>The type elements.</value>
public IEnumerable<TypeElement> TypeElements {
get {
foreach (XPathNavigator node in Node.Select("xrd:Type", XmlNamespaceResolver)) {
@@ -45,18 +67,18 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets the type child element's URIs.
+ /// </summary>
public string[] TypeElementUris {
get {
- XPathNodeIterator types = Node.Select("xrd:Type", XmlNamespaceResolver);
- string[] typeUris = new string[types.Count];
- int i = 0;
- foreach (XPathNavigator type in types) {
- typeUris[i++] = type.Value;
- }
- return typeUris;
+ return this.TypeElements.Select(type => type.Uri).ToArray();
}
}
+ /// <summary>
+ /// Gets the OP Local Identifier.
+ /// </summary>
public Identifier ProviderLocalIdentifier {
get {
var n = Node.SelectSingleNode("xrd:LocalID", XmlNamespaceResolver)
@@ -67,6 +89,21 @@ namespace DotNetOpenAuth.Xrds {
#region IComparable<ServiceElement> Members
+ /// <summary>
+ /// Compares the current object with another object of the same type.
+ /// </summary>
+ /// <param name="other">An object to compare with this object.</param>
+ /// <returns>
+ /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings:
+ /// Value
+ /// Meaning
+ /// Less than zero
+ /// This object is less than the <paramref name="other"/> parameter.
+ /// Zero
+ /// This object is equal to <paramref name="other"/>.
+ /// Greater than zero
+ /// This object is greater than <paramref name="other"/>.
+ /// </returns>
public int CompareTo(ServiceElement other) {
if (other == null) {
return -1;
diff --git a/src/DotNetOpenAuth/Xrds/TypeElement.cs b/src/DotNetOpenAuth/Xrds/TypeElement.cs
index 2770108..f6c2217 100644
--- a/src/DotNetOpenAuth/Xrds/TypeElement.cs
+++ b/src/DotNetOpenAuth/Xrds/TypeElement.cs
@@ -7,11 +7,22 @@
namespace DotNetOpenAuth.Xrds {
using System.Xml.XPath;
+ /// <summary>
+ /// The Type element in an XRDS document.
+ /// </summary>
internal class TypeElement : XrdsNode {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TypeElement"/> class.
+ /// </summary>
+ /// <param name="typeElement">The type element.</param>
+ /// <param name="parent">The parent.</param>
public TypeElement(XPathNavigator typeElement, ServiceElement parent) :
base(typeElement, parent) {
}
+ /// <summary>
+ /// Gets the URI.
+ /// </summary>
public string Uri {
get { return Node.Value; }
}
diff --git a/src/DotNetOpenAuth/Xrds/UriElement.cs b/src/DotNetOpenAuth/Xrds/UriElement.cs
index 8dbfad1..19f1be3 100644
--- a/src/DotNetOpenAuth/Xrds/UriElement.cs
+++ b/src/DotNetOpenAuth/Xrds/UriElement.cs
@@ -8,11 +8,22 @@ namespace DotNetOpenAuth.Xrds {
using System;
using System.Xml.XPath;
+ /// <summary>
+ /// The Uri element in an XRDS document.
+ /// </summary>
internal class UriElement : XrdsNode, IComparable<UriElement> {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UriElement"/> class.
+ /// </summary>
+ /// <param name="uriElement">The URI element.</param>
+ /// <param name="service">The service.</param>
public UriElement(XPathNavigator uriElement, ServiceElement service) :
base(uriElement, service) {
}
+ /// <summary>
+ /// Gets the priority.
+ /// </summary>
public int? Priority {
get {
XPathNavigator n = Node.SelectSingleNode("@priority", XmlNamespaceResolver);
@@ -20,16 +31,37 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets the URI.
+ /// </summary>
public Uri Uri {
get { return new Uri(Node.Value); }
}
+ /// <summary>
+ /// Gets the parent service.
+ /// </summary>
public ServiceElement Service {
get { return (ServiceElement)ParentNode; }
}
#region IComparable<UriElement> Members
+ /// <summary>
+ /// Compares the current object with another object of the same type.
+ /// </summary>
+ /// <param name="other">An object to compare with this object.</param>
+ /// <returns>
+ /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings:
+ /// Value
+ /// Meaning
+ /// Less than zero
+ /// This object is less than the <paramref name="other"/> parameter.
+ /// Zero
+ /// This object is equal to <paramref name="other"/>.
+ /// Greater than zero
+ /// This object is greater than <paramref name="other"/>.
+ /// </returns>
public int CompareTo(UriElement other) {
if (other == null) {
return -1;
diff --git a/src/DotNetOpenAuth/Xrds/XrdElement.cs b/src/DotNetOpenAuth/Xrds/XrdElement.cs
index e52eb77..72c5078 100644
--- a/src/DotNetOpenAuth/Xrds/XrdElement.cs
+++ b/src/DotNetOpenAuth/Xrds/XrdElement.cs
@@ -13,11 +13,23 @@ namespace DotNetOpenAuth.Xrds {
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
+ /// <summary>
+ /// The Xrd element in an XRDS document.
+ /// </summary>
internal class XrdElement : XrdsNode {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="XrdElement"/> class.
+ /// </summary>
+ /// <param name="xrdElement">The XRD element.</param>
+ /// <param name="parent">The parent.</param>
public XrdElement(XPathNavigator xrdElement, XrdsDocument parent) :
base(xrdElement, parent) {
}
+ /// <summary>
+ /// Gets the child service elements.
+ /// </summary>
+ /// <value>The services.</value>
public IEnumerable<ServiceElement> Services {
get {
// We should enumerate them in priority order
@@ -30,12 +42,21 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets a value indicating whether this XRD element's resolution at the XRI resolver was successful.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if this XRD's resolution was successful; otherwise, <c>false</c>.
+ /// </value>
public bool IsXriResolutionSuccessful {
get {
return this.XriResolutionStatusCode == 100;
}
}
+ /// <summary>
+ /// Gets the canonical ID (i-number) for this element.
+ /// </summary>
public string CanonicalID {
get {
var n = Node.SelectSingleNode("xrd:CanonicalID", XmlNamespaceResolver);
@@ -43,6 +64,9 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets a value indicating whether the <see cref="CanonicalID"/> was verified.
+ /// </summary>
public bool IsCanonicalIdVerified {
get {
var n = Node.SelectSingleNode("xrd:Status", XmlNamespaceResolver);
@@ -64,6 +88,9 @@ namespace DotNetOpenAuth.Xrds {
get { return this.SearchForServiceTypeUris(p => p.ClaimedIdentifierServiceTypeURI); }
}
+ /// <summary>
+ /// Gets the services that would be discoverable at an RP for return_to verification.
+ /// </summary>
public IEnumerable<ServiceElement> OpenIdRelyingPartyReturnToServices {
get { return this.SearchForServiceTypeUris(p => p.RPReturnToTypeURI); }
}
@@ -79,6 +106,9 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets the XRI resolution status code.
+ /// </summary>
private int XriResolutionStatusCode {
get {
var n = Node.SelectSingleNode("xrd:Status", XmlNamespaceResolver);
@@ -90,6 +120,12 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Searches for service sub-elements that have Type URI sub-elements that match
+ /// one that we have for a known OpenID protocol version.
+ /// </summary>
+ /// <param name="p">A function that selects what element of the OpenID Protocol we're interested in finding.</param>
+ /// <returns>A sequence of service elements that match the search criteria, sorted in XRDS @priority attribute order.</returns>
private IEnumerable<ServiceElement> SearchForServiceTypeUris(Func<Protocol, string> p) {
var xpath = new StringBuilder();
xpath.Append("xrd:Service[");
diff --git a/src/DotNetOpenAuth/Xrds/XrdsDocument.cs b/src/DotNetOpenAuth/Xrds/XrdsDocument.cs
index bc66f6e..016b58c 100644
--- a/src/DotNetOpenAuth/Xrds/XrdsDocument.cs
+++ b/src/DotNetOpenAuth/Xrds/XrdsDocument.cs
@@ -14,7 +14,14 @@ namespace DotNetOpenAuth.Xrds {
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
+ /// <summary>
+ /// An XRDS document.
+ /// </summary>
internal class XrdsDocument : XrdsNode {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="XrdsDocument"/> class.
+ /// </summary>
+ /// <param name="xrdsNavigator">The root node of the XRDS document.</param>
public XrdsDocument(XPathNavigator xrdsNavigator)
: base(xrdsNavigator) {
XmlNamespaceResolver.AddNamespace("xrd", XrdsNode.XrdNamespace);
@@ -22,12 +29,23 @@ namespace DotNetOpenAuth.Xrds {
XmlNamespaceResolver.AddNamespace("openid10", Protocol.V10.XmlNamespace);
}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="XrdsDocument"/> class.
+ /// </summary>
+ /// <param name="reader">The Xml reader positioned at the root node of the XRDS document.</param>
public XrdsDocument(XmlReader reader)
: this(new XPathDocument(reader).CreateNavigator()) { }
+ /// <summary>
+ /// Initializes a new instance of the <see cref="XrdsDocument"/> class.
+ /// </summary>
+ /// <param name="xml">The text that is the XRDS document.</param>
public XrdsDocument(string xml)
: this(new XPathDocument(new StringReader(xml)).CreateNavigator()) { }
+ /// <summary>
+ /// Gets the XRD child elements of the document.
+ /// </summary>
public IEnumerable<XrdElement> XrdElements {
get {
// We may be looking at a full XRDS document (in the case of YADIS discovery)
@@ -44,10 +62,19 @@ namespace DotNetOpenAuth.Xrds {
}
}
+ /// <summary>
+ /// Gets a value indicating whether all child XRD elements were resolved successfully.
+ /// </summary>
internal bool IsXrdResolutionSuccessful {
get { return this.XrdElements.All(xrd => xrd.IsXriResolutionSuccessful); }
}
+ /// <summary>
+ /// Creates the service endpoints described in this document, useful for requesting
+ /// authentication of one of the OpenID Providers that result from it.
+ /// </summary>
+ /// <param name="claimedIdentifier">The claimed identifier that was used to discover this XRDS document.</param>
+ /// <returns>A sequence of OpenID Providers that can assert ownership of the <paramref name="claimedIdentifier"/>.</returns>
internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(UriIdentifier claimedIdentifier) {
var endpoints = new List<ServiceEndpoint>();
endpoints.AddRange(this.GenerateOPIdentifierServiceEndpoints(claimedIdentifier));
@@ -62,6 +89,12 @@ namespace DotNetOpenAuth.Xrds {
return endpoints;
}
+ /// <summary>
+ /// Creates the service endpoints described in this document, useful for requesting
+ /// authentication of one of the OpenID Providers that result from it.
+ /// </summary>
+ /// <param name="userSuppliedIdentifier">The user-supplied i-name that was used to discover this XRDS document.</param>
+ /// <returns>A sequence of OpenID Providers that can assert ownership of the canonical ID given in this document.</returns>
internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(XriIdentifier userSuppliedIdentifier) {
var endpoints = new List<ServiceEndpoint>();
endpoints.AddRange(this.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier));
@@ -76,25 +109,52 @@ namespace DotNetOpenAuth.Xrds {
return endpoints;
}
+ /// <summary>
+ /// Finds the Relying Party return_to receiving endpoints.
+ /// </summary>
+ /// <returns>A sequence of Relying Party descriptors for the return_to endpoints.</returns>
+ /// <remarks>
+ /// This is useful for Providers to send unsolicited assertions to Relying Parties,
+ /// or for Provider's to perform RP discovery/verification as part of authentication.
+ /// </remarks>
internal IEnumerable<RelyingPartyEndpointDescription> FindRelyingPartyReceivingEndpoints() {
return from service in this.FindReturnToServices()
from uri in service.UriElements
select new RelyingPartyEndpointDescription(uri.Uri, service.TypeElementUris);
}
+ /// <summary>
+ /// Generates OpenID Providers that can authenticate using directed identity.
+ /// </summary>
+ /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user.</param>
+ /// <returns>A sequence of the providers that can offer directed identity services.</returns>
private IEnumerable<ServiceEndpoint> GenerateOPIdentifierServiceEndpoints(Identifier opIdentifier) {
return from service in this.FindOPIdentifierServices()
from uri in service.UriElements
let protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris)
- select ServiceEndpoint.CreateForProviderIdentifier(opIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority);
+ let providerDescription = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris)
+ select ServiceEndpoint.CreateForProviderIdentifier(opIdentifier, providerDescription, service.Priority, uri.Priority);
}
+ /// <summary>
+ /// Generates the OpenID Providers that are capable of asserting ownership
+ /// of a particular URI claimed identifier.
+ /// </summary>
+ /// <param name="claimedIdentifier">The claimed identifier.</param>
+ /// <returns>A sequence of the providers that can assert ownership of the given identifier.</returns>
private IEnumerable<ServiceEndpoint> GenerateClaimedIdentifierServiceEndpoints(UriIdentifier claimedIdentifier) {
return from service in this.FindClaimedIdentifierServices()
from uri in service.UriElements
- select ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, service.ProviderLocalIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority);
+ let providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris)
+ select ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority);
}
+ /// <summary>
+ /// Generates the OpenID Providers that are capable of asserting ownership
+ /// of a particular XRI claimed identifier.
+ /// </summary>
+ /// <param name="userSuppliedIdentifier">The i-name supplied by the user.</param>
+ /// <returns>A sequence of the providers that can assert ownership of the given identifier.</returns>
private IEnumerable<ServiceEndpoint> GenerateClaimedIdentifierServiceEndpoints(XriIdentifier userSuppliedIdentifier) {
foreach (var service in this.FindClaimedIdentifierServices()) {
foreach (var uri in service.UriElements) {
@@ -107,11 +167,16 @@ namespace DotNetOpenAuth.Xrds {
// In the case of XRI names, the ClaimedId is actually the CanonicalID.
var claimedIdentifier = new XriIdentifier(service.Xrd.CanonicalID);
- yield return ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority);
+ var providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris);
+ yield return ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority);
}
}
}
+ /// <summary>
+ /// Enumerates the XRDS service elements that describe OpenID Providers offering directed identity assertions.
+ /// </summary>
+ /// <returns>A sequence of service elements.</returns>
private IEnumerable<ServiceElement> FindOPIdentifierServices() {
return from xrd in this.XrdElements
from service in xrd.OpenIdProviderIdentifierServices
@@ -129,6 +194,11 @@ namespace DotNetOpenAuth.Xrds {
select service;
}
+ /// <summary>
+ /// Enumerates the XRDS service elements that describe OpenID Relying Party return_to URLs
+ /// that can receive authentication assertions.
+ /// </summary>
+ /// <returns>A sequence of service elements.</returns>
private IEnumerable<ServiceElement> FindReturnToServices() {
return from xrd in this.XrdElements
from service in xrd.OpenIdRelyingPartyReturnToServices
diff --git a/src/DotNetOpenAuth/Xrds/XrdsNode.cs b/src/DotNetOpenAuth/Xrds/XrdsNode.cs
index d015dcb..5eda0e6 100644
--- a/src/DotNetOpenAuth/Xrds/XrdsNode.cs
+++ b/src/DotNetOpenAuth/Xrds/XrdsNode.cs
@@ -8,6 +8,9 @@ namespace DotNetOpenAuth.Xrds {
using System.Xml;
using System.Xml.XPath;
+ /// <summary>
+ /// A node in an XRDS document.
+ /// </summary>
internal class XrdsNode {
/// <summary>
/// The XRD namespace xri://$xrd*($v*2.0)
@@ -19,21 +22,39 @@ namespace DotNetOpenAuth.Xrds {
/// </summary>
internal const string XrdsNamespace = "xri://$xrds";
+ /// <summary>
+ /// Initializes a new instance of the <see cref="XrdsNode"/> class.
+ /// </summary>
+ /// <param name="node">The node represented by this instance.</param>
+ /// <param name="parentNode">The parent node.</param>
protected XrdsNode(XPathNavigator node, XrdsNode parentNode) {
this.Node = node;
this.ParentNode = parentNode;
this.XmlNamespaceResolver = this.ParentNode.XmlNamespaceResolver;
}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="XrdsNode"/> class.
+ /// </summary>
+ /// <param name="document">The document's root node, which this instance represents.</param>
protected XrdsNode(XPathNavigator document) {
this.Node = document;
this.XmlNamespaceResolver = new XmlNamespaceManager(document.NameTable);
}
+ /// <summary>
+ /// Gets the node.
+ /// </summary>
protected XPathNavigator Node { get; private set; }
+ /// <summary>
+ /// Gets the parent node, or null if this is the root node.
+ /// </summary>
protected XrdsNode ParentNode { get; private set; }
+ /// <summary>
+ /// Gets the XML namespace resolver to use in XPath expressions.
+ /// </summary>
protected XmlNamespaceManager XmlNamespaceResolver { get; private set; }
}
}
diff --git a/src/DotNetOpenAuth/Yadis/HtmlParser.cs b/src/DotNetOpenAuth/Yadis/HtmlParser.cs
index 3338b9b..5a00da8 100644
--- a/src/DotNetOpenAuth/Yadis/HtmlParser.cs
+++ b/src/DotNetOpenAuth/Yadis/HtmlParser.cs
@@ -12,16 +12,51 @@ namespace DotNetOpenAuth.Yadis {
using System.Web;
using System.Web.UI.HtmlControls;
+ /// <summary>
+ /// An HTML HEAD tag parser.
+ /// </summary>
internal static class HtmlParser {
- private static readonly Regex attrRe = new Regex("\n# Must start with a sequence of word-characters, followed by an equals sign\n(?<attrname>(\\w|-)+)=\n\n# Then either a quoted or unquoted attribute\n(?:\n\n # Match everything that's between matching quote marks\n (?<qopen>[\"\\'])(?<attrval>.*?)\\k<qopen>\n|\n\n # If the value is not quoted, match up to whitespace\n (?<attrval>(?:[^\\s<>/]|/(?!>))+)\n)\n\n|\n\n(?<endtag>[<>])\n ", Flags);
- private const RegexOptions Flags = (RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ /// <summary>
+ /// Common flags to use on regex tests.
+ /// </summary>
+ private const RegexOptions Flags = RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase;
+
+ /// <summary>
+ /// A regular expression designed to select tags (?)
+ /// </summary>
private const string TagExpr = "\n# Starts with the tag name at a word boundary, where the tag name is\n# not a namespace\n<{0}\\b(?!:)\n \n# All of the stuff up to a \">\", hopefully attributes.\n(?<attrs>[^>]*?)\n \n(?: # Match a short tag\n />\n \n| # Match a full tag\n >\n \n (?<contents>.*?)\n \n # Closed by\n (?: # One of the specified close tags\n </?{1}\\s*>\n \n # End of the string\n | \\Z\n \n )\n \n)\n ";
+
+ /// <summary>
+ /// A regular expression designed to select start tags (?)
+ /// </summary>
private const string StartTagExpr = "\n# Starts with the tag name at a word boundary, where the tag name is\n# not a namespace\n<{0}\\b(?!:)\n \n# All of the stuff up to a \">\", hopefully attributes.\n(?<attrs>[^>]*?)\n \n(?: # Match a short tag\n />\n \n| # Match a full tag\n >\n )\n ";
+ /// <summary>
+ /// A regular expression designed to select attributes within a tag.
+ /// </summary>
+ private static readonly Regex attrRe = new Regex("\n# Must start with a sequence of word-characters, followed by an equals sign\n(?<attrname>(\\w|-)+)=\n\n# Then either a quoted or unquoted attribute\n(?:\n\n # Match everything that's between matching quote marks\n (?<qopen>[\"\\'])(?<attrval>.*?)\\k<qopen>\n|\n\n # If the value is not quoted, match up to whitespace\n (?<attrval>(?:[^\\s<>/]|/(?!>))+)\n)\n\n|\n\n(?<endtag>[<>])\n ", Flags);
+
+ /// <summary>
+ /// A regular expression designed to select the HEAD tag.
+ /// </summary>
private static readonly Regex headRe = TagMatcher("head", new[] { "body" });
+
+ /// <summary>
+ /// A regular expression designed to select the HTML tag.
+ /// </summary>
private static readonly Regex htmlRe = TagMatcher("html", new string[0]);
+
+ /// <summary>
+ /// A regular expression designed to remove all comments and scripts from a string.
+ /// </summary>
private static readonly Regex removedRe = new Regex(@"<!--.*?-->|<!\[CDATA\[.*?\]\]>|<script\b[^>]*>.*?</script>", Flags);
+ /// <summary>
+ /// Finds all the HTML HEAD tag child elements that match the tag name of a given type.
+ /// </summary>
+ /// <typeparam name="T">The HTML tag of interest.</typeparam>
+ /// <param name="html">The HTML to scan.</param>
+ /// <returns>A sequence of the matching elements.</returns>
public static IEnumerable<T> HeadTags<T>(string html) where T : HtmlControl, new() {
html = removedRe.Replace(html, string.Empty);
Match match = htmlRe.Match(html);
@@ -52,6 +87,12 @@ namespace DotNetOpenAuth.Yadis {
}
}
+ /// <summary>
+ /// Generates a regular expression that will find a given HTML tag.
+ /// </summary>
+ /// <param name="tagName">Name of the tag.</param>
+ /// <param name="closeTags">The close tags (?).</param>
+ /// <returns>The created regular expression.</returns>
private static Regex TagMatcher(string tagName, params string[] closeTags) {
string text2;
if (closeTags.Length > 0) {
@@ -73,8 +114,13 @@ namespace DotNetOpenAuth.Yadis {
return new Regex(string.Format(CultureInfo.InvariantCulture, TagExpr, tagName, text2), Flags);
}
- private static Regex StartTagMatcher(string tag_name) {
- return new Regex(string.Format(CultureInfo.InvariantCulture, StartTagExpr, tag_name), Flags);
+ /// <summary>
+ /// Generates a regular expression designed to find a given tag.
+ /// </summary>
+ /// <param name="tagName">The tag to find.</param>
+ /// <returns>The created regular expression.</returns>
+ private static Regex StartTagMatcher(string tagName) {
+ return new Regex(string.Format(CultureInfo.InvariantCulture, StartTagExpr, tagName), Flags);
}
}
}
diff --git a/src/DotNetOpenAuth/Yadis/Yadis.cs b/src/DotNetOpenAuth/Yadis/Yadis.cs
index 3a7ffef..455c653 100644
--- a/src/DotNetOpenAuth/Yadis/Yadis.cs
+++ b/src/DotNetOpenAuth/Yadis/Yadis.cs
@@ -15,7 +15,13 @@ namespace DotNetOpenAuth.Yadis {
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.Xrds;
+ /// <summary>
+ /// YADIS discovery manager.
+ /// </summary>
internal class Yadis {
+ /// <summary>
+ /// The HTTP header to look for in responses to declare where the XRDS document should be found.
+ /// </summary>
internal const string HeaderName = "X-XRDS-Location";
/// <summary>
@@ -86,10 +92,12 @@ namespace DotNetOpenAuth.Yadis {
}
/// <summary>
- /// Searches an HTML document for a
+ /// Searches an HTML document for a
/// &lt;meta http-equiv="X-XRDS-Location" content="{YadisURL}"&gt;
/// tag and returns the content of YadisURL.
/// </summary>
+ /// <param name="html">The HTML to search.</param>
+ /// <returns>The URI of the XRDS document if found; otherwise <c>null</c>.</returns>
public static Uri FindYadisDocumentLocationInHtmlMetaTags(string html) {
foreach (var metaTag in HtmlParser.HeadTags<HtmlMeta>(html)) {
if (HeaderName.Equals(metaTag.HttpEquiv, StringComparison.OrdinalIgnoreCase)) {
@@ -104,6 +112,14 @@ namespace DotNetOpenAuth.Yadis {
return null;
}
+ /// <summary>
+ /// Sends a YADIS HTTP request as part of identifier discovery.
+ /// </summary>
+ /// <param name="requestHandler">The request handler to use to actually submit the request.</param>
+ /// <param name="uri">The URI to GET.</param>
+ /// <param name="requireSsl">Whether only HTTPS URLs should ever be retrieved.</param>
+ /// <param name="acceptTypes">The value of the Accept HTTP header to include in the request.</param>
+ /// <returns>The HTTP response retrieved from the request.</returns>
internal static DirectWebResponse Request(IDirectSslWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) {
ErrorUtilities.VerifyArgumentNotNull(uri, "uri");
@@ -116,6 +132,13 @@ namespace DotNetOpenAuth.Yadis {
return requestHandler.GetResponse(request, requireSsl);
}
+ /// <summary>
+ /// Determines whether a given HTTP response constitutes an XRDS document.
+ /// </summary>
+ /// <param name="response">The response to test.</param>
+ /// <returns>
+ /// <c>true</c> if the response constains an XRDS document; otherwise, <c>false</c>.
+ /// </returns>
private static bool IsXrdsDocument(DirectWebResponse response) {
if (response.ContentType.MediaType == ContentTypes.Xrds) {
return true;