//-----------------------------------------------------------------------
//
// Copyright (c) Outercurve Foundation. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId {
using System;
using System.Collections.Generic;
using System.Linq;
using DotNetOpenAuth.Logging;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.Xrds;
using Validation;
///
/// Adds OpenID-specific extension methods to the XrdsDocument class.
///
internal static class OpenIdXrdsHelperRelyingParty {
///
/// Creates the service endpoints described in this document, useful for requesting
/// authentication of one of the OpenID Providers that result from it.
///
/// The XrdsDocument instance to use in this process.
/// The claimed identifier that was used to discover this XRDS document.
/// The user supplied identifier.
///
/// A sequence of OpenID Providers that can assert ownership of the .
///
internal static IEnumerable CreateServiceEndpoints(this IEnumerable xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) {
Requires.NotNull(xrds, "xrds");
Requires.NotNull(claimedIdentifier, "claimedIdentifier");
Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
var endpoints = new List();
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).ToString());
return endpoints;
}
///
/// Creates the service endpoints described in this document, useful for requesting
/// authentication of one of the OpenID Providers that result from it.
///
/// The XrdsDocument instance to use in this process.
/// The user-supplied i-name that was used to discover this XRDS document.
/// A sequence of OpenID Providers that can assert ownership of the canonical ID given in this document.
internal static IEnumerable CreateServiceEndpoints(this IEnumerable xrds, XriIdentifier userSuppliedIdentifier) {
Requires.NotNull(xrds, "xrds");
Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
var endpoints = new List();
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).ToString());
return endpoints;
}
///
/// Generates OpenID Providers that can authenticate using directed identity.
///
/// The XrdsDocument instance to use in this process.
/// The OP Identifier entered (and resolved) by the user. Essentially the user-supplied identifier.
/// A sequence of the providers that can offer directed identity services.
private static IEnumerable GenerateOPIdentifierServiceEndpoints(this IEnumerable xrds, Identifier opIdentifier) {
Requires.NotNull(xrds, "xrds");
Requires.NotNull(opIdentifier, "opIdentifier");
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);
}
///
/// Generates the OpenID Providers that are capable of asserting ownership
/// of a particular URI claimed identifier.
///
/// The XrdsDocument instance to use in this process.
/// The claimed identifier.
/// The user supplied identifier.
///
/// A sequence of the providers that can assert ownership of the given identifier.
///
private static IEnumerable GenerateClaimedIdentifierServiceEndpoints(this IEnumerable xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) {
Requires.NotNull(xrds, "xrds");
Requires.NotNull(claimedIdentifier, "claimedIdentifier");
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);
}
///
/// Generates the OpenID Providers that are capable of asserting ownership
/// of a particular XRI claimed identifier.
///
/// The XrdsDocument instance to use in this process.
/// The i-name supplied by the user.
/// A sequence of the providers that can assert ownership of the given identifier.
private static IEnumerable GenerateClaimedIdentifierServiceEndpoints(this IEnumerable xrds, XriIdentifier userSuppliedIdentifier) {
// Cannot use code contracts because this method uses yield return.
////Requires.NotNull(xrds, "xrds");
//// 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);
}
}
}
///
/// Enumerates the XRDS service elements that describe OpenID Providers offering directed identity assertions.
///
/// The XrdsDocument instance to use in this process.
/// A sequence of service elements.
private static IEnumerable FindOPIdentifierServices(this IEnumerable xrds) {
Requires.NotNull(xrds, "xrds");
return from xrd in xrds
from service in xrd.OpenIdProviderIdentifierServices
select service;
}
///
/// Returns the OpenID-compatible services described by a given XRDS document,
/// in priority order.
///
/// The XrdsDocument instance to use in this process.
/// A sequence of the services offered.
private static IEnumerable FindClaimedIdentifierServices(this IEnumerable xrds) {
Requires.NotNull(xrds, "xrds");
return from xrd in xrds
from service in xrd.OpenIdClaimedIdentifierServices
select service;
}
}
}