/// <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"); //// 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> /// 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"); 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"); 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 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) { Contract.Requires <ArgumentNullException>(xrds != null); Contract.Requires <ArgumentNullException>(opIdentifier != null); 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) { Contract.Requires <ArgumentNullException>(xrds != null); Contract.Requires <ArgumentNullException>(claimedIdentifier != null); 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> /// Searches HTML for the HEAD META tags that describe OpenID provider services. /// </summary> /// <param name="claimedIdentifier">The final URL that provided this HTML document. /// This may not be the same as (this) userSuppliedIdentifier if the /// userSuppliedIdentifier pointed to a 301 Redirect.</param> /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> /// <param name="html">The HTML that was downloaded and should be searched.</param> /// <returns> /// A sequence of any discovered ServiceEndpoints. /// </returns> private static IEnumerable <IdentifierDiscoveryResult> DiscoverFromHtml(Uri claimedIdentifier, UriIdentifier userSuppliedIdentifier, string html) { var linkTags = new List <HtmlLink>(HtmlParser.HeadTags <HtmlLink>(html)); foreach (var protocol in Protocol.AllPracticalVersions) { // rel attributes are supposed to be interpreted with case INsensitivity, // and is a space-delimited list of values. (http://www.htmlhelp.com/reference/html40/values.html#linktypes) var serverLinkTag = linkTags.WithAttribute("rel").FirstOrDefault(tag => Regex.IsMatch(tag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryProviderKey) + @"\b", RegexOptions.IgnoreCase)); if (serverLinkTag == null) { continue; } Uri providerEndpoint = null; if (Uri.TryCreate(serverLinkTag.Href, UriKind.Absolute, out providerEndpoint)) { // See if a LocalId tag of the discovered version exists Identifier providerLocalIdentifier = null; var delegateLinkTag = linkTags.WithAttribute("rel").FirstOrDefault(tag => Regex.IsMatch(tag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryLocalIdKey) + @"\b", RegexOptions.IgnoreCase)); if (delegateLinkTag != null) { if (Identifier.IsValid(delegateLinkTag.Href)) { providerLocalIdentifier = delegateLinkTag.Href; } else { Logger.Yadis.WarnFormat("Skipping endpoint data because local id is badly formed ({0}).", delegateLinkTag.Href); continue; // skip to next version } } // Choose the TypeURI to match the OpenID version detected. string[] typeURIs = { protocol.ClaimedIdentifierServiceTypeURI }; yield return(IdentifierDiscoveryResult.CreateForClaimedIdentifier( claimedIdentifier, userSuppliedIdentifier, providerLocalIdentifier, new ProviderEndpointDescription(providerEndpoint, typeURIs), (int?)null, (int?)null)); } } }
/// <summary> /// Gets the priority rating for a given type of endpoint, allowing a /// priority sorting of endpoints. /// </summary> /// <param name="endpoint">The endpoint to prioritize.</param> /// <returns>An arbitary integer, which may be used for sorting against other returned values from this method.</returns> private static double GetEndpointPrecedenceOrderByServiceType(IdentifierDiscoveryResult endpoint) { // The numbers returned from this method only need to compare against other numbers // from this method, which makes them arbitrary but relational to only others here. if (endpoint.Capabilities.Contains(Protocol.V20.OPIdentifierServiceTypeURI)) { return(0); } if (endpoint.Capabilities.Contains(Protocol.V20.ClaimedIdentifierServiceTypeURI)) { return(1); } if (endpoint.Capabilities.Contains(Protocol.V11.ClaimedIdentifierServiceTypeURI)) { return(2); } if (endpoint.Capabilities.Contains(Protocol.V10.ClaimedIdentifierServiceTypeURI)) { return(3); } return(10); }