summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OpenId/OpenIdXrdsHelper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OpenId/OpenIdXrdsHelper.cs')
-rw-r--r--src/DotNetOpenAuth.OpenId/OpenIdXrdsHelper.cs163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/DotNetOpenAuth.OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth.OpenId/OpenIdXrdsHelper.cs
new file mode 100644
index 0000000..617c467
--- /dev/null
+++ b/src/DotNetOpenAuth.OpenId/OpenIdXrdsHelper.cs
@@ -0,0 +1,163 @@
+//-----------------------------------------------------------------------
+// <copyright file="OpenIdXrdsHelper.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using DotNetOpenAuth.Xrds;
+
+ /// <summary>
+ /// Adds OpenID-specific extension methods to the XrdsDocument class.
+ /// </summary>
+ internal static class OpenIdXrdsHelperRelyingParty {
+ /// <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="xrds">The XrdsDocument instance to use in this process.</param>
+ /// <param name="claimedIdentifier">The claimed identifier that was used to discover this XRDS document.</param>
+ /// <param name="userSuppliedIdentifier">The user supplied identifier.</param>
+ /// <returns>
+ /// A sequence of OpenID Providers that can assert ownership of the <paramref name="claimedIdentifier"/>.
+ /// </returns>
+ internal static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this IEnumerable<XrdElement> xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) {
+ Requires.NotNull(xrds, "xrds");
+ Requires.NotNull(claimedIdentifier, "claimedIdentifier");
+ Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
+ Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null);
+
+ var endpoints = new List<IdentifierDiscoveryResult>();
+ endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier));
+ endpoints.AddRange(xrds.GenerateClaimedIdentifierServiceEndpoints(claimedIdentifier, userSuppliedIdentifier));
+
+ Logger.Yadis.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count);
+ Logger.Yadis.Debug(endpoints.ToStringDeferred(true));
+ 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="xrds">The XrdsDocument instance to use in this process.</param>
+ /// <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 static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this IEnumerable<XrdElement> xrds, XriIdentifier userSuppliedIdentifier) {
+ Requires.NotNull(xrds, "xrds");
+ Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
+ Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null);
+
+ var endpoints = new List<IdentifierDiscoveryResult>();
+ endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier));
+ endpoints.AddRange(xrds.GenerateClaimedIdentifierServiceEndpoints(userSuppliedIdentifier));
+ Logger.Yadis.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count);
+ Logger.Yadis.Debug(endpoints.ToStringDeferred(true));
+ return endpoints;
+ }
+
+ /// <summary>
+ /// Generates OpenID Providers that can authenticate using directed identity.
+ /// </summary>
+ /// <param name="xrds">The XrdsDocument instance to use in this process.</param>
+ /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user. Essentially the user-supplied identifier.</param>
+ /// <returns>A sequence of the providers that can offer directed identity services.</returns>
+ private static IEnumerable<IdentifierDiscoveryResult> GenerateOPIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, Identifier opIdentifier) {
+ Requires.NotNull(xrds, "xrds");
+ Requires.NotNull(opIdentifier, "opIdentifier");
+ Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null);
+ return from service in xrds.FindOPIdentifierServices()
+ from uri in service.UriElements
+ let protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris)
+ let providerDescription = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris)
+ select IdentifierDiscoveryResult.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="xrds">The XrdsDocument instance to use in this process.</param>
+ /// <param name="claimedIdentifier">The claimed identifier.</param>
+ /// <param name="userSuppliedIdentifier">The user supplied identifier.</param>
+ /// <returns>
+ /// A sequence of the providers that can assert ownership of the given identifier.
+ /// </returns>
+ private static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) {
+ Requires.NotNull(xrds, "xrds");
+ Requires.NotNull(claimedIdentifier, "claimedIdentifier");
+ Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null);
+
+ return from service in xrds.FindClaimedIdentifierServices()
+ from uri in service.UriElements
+ where uri.Uri != null
+ let providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris)
+ select IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, 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="xrds">The XrdsDocument instance to use in this process.</param>
+ /// <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 static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable<XrdElement> xrds, XriIdentifier userSuppliedIdentifier) {
+ // Cannot use code contracts because this method uses yield return.
+ ////Requires.NotNull(xrds, "xrds");
+ ////Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null);
+ ErrorUtilities.VerifyArgumentNotNull(xrds, "xrds");
+
+ foreach (var service in xrds.FindClaimedIdentifierServices()) {
+ foreach (var uri in service.UriElements) {
+ // spec section 7.3.2.3 on Claimed Id -> CanonicalID substitution
+ if (service.Xrd.CanonicalID == null) {
+ Logger.Yadis.WarnFormat(XrdsStrings.MissingCanonicalIDElement, userSuppliedIdentifier);
+ break; // skip on to next service
+ }
+ ErrorUtilities.VerifyProtocol(service.Xrd.IsCanonicalIdVerified, XrdsStrings.CIDVerificationFailed, userSuppliedIdentifier);
+
+ // In the case of XRI names, the ClaimedId is actually the CanonicalID.
+ var claimedIdentifier = new XriIdentifier(service.Xrd.CanonicalID);
+ var providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris);
+ yield return IdentifierDiscoveryResult.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>
+ /// <param name="xrds">The XrdsDocument instance to use in this process.</param>
+ /// <returns>A sequence of service elements.</returns>
+ private static IEnumerable<ServiceElement> FindOPIdentifierServices(this IEnumerable<XrdElement> xrds) {
+ Requires.NotNull(xrds, "xrds");
+ Contract.Ensures(Contract.Result<IEnumerable<ServiceElement>>() != null);
+
+ return from xrd in xrds
+ from service in xrd.OpenIdProviderIdentifierServices
+ select service;
+ }
+
+ /// <summary>
+ /// Returns the OpenID-compatible services described by a given XRDS document,
+ /// in priority order.
+ /// </summary>
+ /// <param name="xrds">The XrdsDocument instance to use in this process.</param>
+ /// <returns>A sequence of the services offered.</returns>
+ private static IEnumerable<ServiceElement> FindClaimedIdentifierServices(this IEnumerable<XrdElement> xrds) {
+ Requires.NotNull(xrds, "xrds");
+ Contract.Ensures(Contract.Result<IEnumerable<ServiceElement>>() != null);
+
+ return from xrd in xrds
+ from service in xrd.OpenIdClaimedIdentifierServices
+ select service;
+ }
+ }
+}