diff options
Diffstat (limited to 'src')
38 files changed, 842 insertions, 871 deletions
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs index b10da88..c18ea33 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs @@ -15,7 +15,6 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Test.OpenId; using DotNetOpenAuth.Yadis; @@ -84,19 +83,19 @@ namespace DotNetOpenAuth.Test.Mocks { } } - internal void RegisterMockXrdsResponse(IIdentifierDiscoveryResult endpoint) { + internal void RegisterMockXrdsResponse(IdentifierDiscoveryResult endpoint) { Contract.Requires<ArgumentNullException>(endpoint != null); string identityUri; - if (endpoint.ClaimedIdentifier == endpoint.ProviderEndpoint.GetProtocol().ClaimedIdentifierForOPIdentifier) { + if (endpoint.ClaimedIdentifier == endpoint.Protocol.ClaimedIdentifierForOPIdentifier) { identityUri = endpoint.UserSuppliedIdentifier; } else { identityUri = endpoint.UserSuppliedIdentifier ?? endpoint.ClaimedIdentifier; } - this.RegisterMockXrdsResponse(new Uri(identityUri), new IIdentifierDiscoveryResult[] { endpoint }); + this.RegisterMockXrdsResponse(new Uri(identityUri), new IdentifierDiscoveryResult[] { endpoint }); } - internal void RegisterMockXrdsResponse(Uri respondingUri, IEnumerable<IIdentifierDiscoveryResult> endpoints) { + internal void RegisterMockXrdsResponse(Uri respondingUri, IEnumerable<IdentifierDiscoveryResult> endpoints) { Contract.Requires<ArgumentNullException>(endpoints != null); StringBuilder xrds = new StringBuilder(); @@ -111,16 +110,16 @@ namespace DotNetOpenAuth.Test.Mocks { <openid:Delegate xmlns:openid='http://openid.net/xmlns/1.0'>{2}</openid:Delegate> </Service>"; string serviceTypeUri; - if (endpoint.ClaimedIdentifier == endpoint.ProviderEndpoint.GetProtocol().ClaimedIdentifierForOPIdentifier) { - serviceTypeUri = endpoint.ProviderEndpoint.GetProtocol().OPIdentifierServiceTypeURI; + if (endpoint.ClaimedIdentifier == endpoint.Protocol.ClaimedIdentifierForOPIdentifier) { + serviceTypeUri = endpoint.Protocol.OPIdentifierServiceTypeURI; } else { - serviceTypeUri = endpoint.ProviderEndpoint.GetProtocol().ClaimedIdentifierServiceTypeURI; + serviceTypeUri = endpoint.Protocol.ClaimedIdentifierServiceTypeURI; } string xrd = string.Format( CultureInfo.InvariantCulture, template, HttpUtility.HtmlEncode(serviceTypeUri), - HttpUtility.HtmlEncode(endpoint.ProviderEndpoint.Uri.AbsoluteUri), + HttpUtility.HtmlEncode(endpoint.ProviderEndpoint.AbsoluteUri), HttpUtility.HtmlEncode(endpoint.ProviderLocalIdentifier)); xrds.Append(xrd); } @@ -131,12 +130,12 @@ namespace DotNetOpenAuth.Test.Mocks { this.RegisterMockResponse(respondingUri, ContentTypes.Xrds, xrds.ToString()); } - internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, IIdentifierDiscoveryResult providerEndpoint) { - IIdentifierDiscoveryResult identityEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier( + internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, IdentifierDiscoveryResult providerEndpoint) { + IdentifierDiscoveryResult identityEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier( directedIdentityAssignedIdentifier, directedIdentityAssignedIdentifier, providerEndpoint.ProviderLocalIdentifier, - providerEndpoint.ProviderEndpoint, + new ProviderEndpointDescription(providerEndpoint.ProviderEndpoint, providerEndpoint.Capabilities), 10, 10); this.RegisterMockXrdsResponse(identityEndpoint); diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs index 862a05e..9f032b8 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs @@ -10,7 +10,6 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Diagnostics.Contracts; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> @@ -19,13 +18,13 @@ namespace DotNetOpenAuth.Test.Mocks { /// having a dependency on a hosted web site to actually perform discovery on. /// </summary> internal class MockIdentifier : Identifier { - private IEnumerable<IIdentifierDiscoveryResult> endpoints; + private IEnumerable<IdentifierDiscoveryResult> endpoints; private MockHttpRequest mockHttpRequest; private Identifier wrappedIdentifier; - public MockIdentifier(Identifier wrappedIdentifier, MockHttpRequest mockHttpRequest, IEnumerable<IIdentifierDiscoveryResult> endpoints) + public MockIdentifier(Identifier wrappedIdentifier, MockHttpRequest mockHttpRequest, IEnumerable<IdentifierDiscoveryResult> endpoints) : base(wrappedIdentifier.OriginalString, false) { Contract.Requires<ArgumentNullException>(wrappedIdentifier != null); Contract.Requires<ArgumentNullException>(mockHttpRequest != null); @@ -40,7 +39,7 @@ namespace DotNetOpenAuth.Test.Mocks { mockHttpRequest.RegisterMockXrdsResponse(new Uri(wrappedIdentifier.ToString()), endpoints); } - internal IEnumerable<IIdentifierDiscoveryResult> DiscoveryEndpoints { + internal IEnumerable<IdentifierDiscoveryResult> DiscoveryEndpoints { get { return this.endpoints; } } diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs index 8aea7e5..d74258d 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs @@ -11,7 +11,6 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.RelyingParty; internal class MockIdentifierDiscoveryService : IIdentifierDiscoveryService { @@ -32,11 +31,11 @@ namespace DotNetOpenAuth.Test.Mocks { /// <returns> /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. /// </returns> - public IEnumerable<IIdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { + public IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { var mockIdentifier = identifier as MockIdentifier; if (mockIdentifier == null) { abortDiscoveryChain = false; - return Enumerable.Empty<IIdentifierDiscoveryResult>(); + return Enumerable.Empty<IdentifierDiscoveryResult>(); } abortDiscoveryChain = true; diff --git a/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs b/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs index 0f6dd7e..4432c0d 100644 --- a/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/AssociationHandshakeTests.cs @@ -318,7 +318,7 @@ namespace DotNetOpenAuth.Test.OpenId { private void ParameterizedAssociationTest( ProviderEndpointDescription opDescription, string expectedAssociationType) { - Protocol protocol = Protocol.Lookup(opDescription.GetProtocol().ProtocolVersion); + Protocol protocol = Protocol.Lookup(Protocol.Lookup(opDescription.Version).ProtocolVersion); bool expectSuccess = expectedAssociationType != null; bool expectDiffieHellman = !opDescription.Uri.IsTransportSecure(); Association rpAssociation = null, opAssociation; @@ -337,7 +337,7 @@ namespace DotNetOpenAuth.Test.OpenId { op.SendResponse(req); }); coordinator.IncomingMessageFilter = message => { - Assert.AreSame(opDescription.GetProtocol().ProtocolVersion, message.Version, "The message was recognized as version {0} but was expected to be {1}.", message.Version, opDescription.GetProtocol().ProtocolVersion); + Assert.AreSame(Protocol.Lookup(opDescription.Version).ProtocolVersion, message.Version, "The message was recognized as version {0} but was expected to be {1}.", message.Version, Protocol.Lookup(opDescription.Version).ProtocolVersion); var associateSuccess = message as AssociateSuccessfulResponse; var associateFailed = message as AssociateUnsuccessfulResponse; if (associateSuccess != null) { @@ -348,7 +348,7 @@ namespace DotNetOpenAuth.Test.OpenId { } }; coordinator.OutgoingMessageFilter = message => { - Assert.AreSame(opDescription.GetProtocol().ProtocolVersion, message.Version, "The message was for version {0} but was expected to be for {1}.", message.Version, opDescription.GetProtocol().Version); + Assert.AreSame(Protocol.Lookup(opDescription.Version).ProtocolVersion, message.Version, "The message was for version {0} but was expected to be for {1}.", message.Version, Protocol.Lookup(opDescription.Version).Version); }; coordinator.Run(); diff --git a/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs b/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs index 9c68daa..0655ff5 100644 --- a/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs @@ -13,7 +13,6 @@ namespace DotNetOpenAuth.Test.OpenId.DiscoveryServices { using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; using DotNetOpenAuth.OpenId.RelyingParty; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -119,7 +118,7 @@ namespace DotNetOpenAuth.Test.OpenId.DiscoveryServices { var insecureEndpoint = GetServiceEndpoint(0, ProtocolVersion.V20, 10, false); var secureEndpoint = GetServiceEndpoint(1, ProtocolVersion.V20, 20, true); UriIdentifier secureClaimedId = new UriIdentifier(VanityUriSsl, true); - this.MockResponder.RegisterMockXrdsResponse(secureClaimedId, new IIdentifierDiscoveryResult[] { insecureEndpoint, secureEndpoint }); + this.MockResponder.RegisterMockXrdsResponse(secureClaimedId, new IdentifierDiscoveryResult[] { insecureEndpoint, secureEndpoint }); Assert.AreEqual(secureEndpoint.ProviderLocalIdentifier, this.Discover(secureClaimedId).Single().ProviderLocalIdentifier); } @@ -203,21 +202,21 @@ namespace DotNetOpenAuth.Test.OpenId.DiscoveryServices { } this.MockResponder.RegisterMockResponse(new Uri(idToDiscover), claimedId, contentType, headers ?? new WebHeaderCollection(), LoadEmbeddedFile(url)); - IIdentifierDiscoveryResult expected = IdentifierDiscoveryResult.CreateForClaimedIdentifier( + IdentifierDiscoveryResult expected = IdentifierDiscoveryResult.CreateForClaimedIdentifier( claimedId, expectedLocalId, new ProviderEndpointDescription(new Uri(providerEndpoint), new string[] { protocol.ClaimedIdentifierServiceTypeURI }), // services aren't checked by Equals null, null); - IIdentifierDiscoveryResult se = this.Discover(idToDiscover).FirstOrDefault(ep => ep.Equals(expected)); + IdentifierDiscoveryResult se = this.Discover(idToDiscover).FirstOrDefault(ep => ep.Equals(expected)); Assert.IsNotNull(se, url + " failed to be discovered."); // Do extra checking of service type URIs, which aren't included in // the ServiceEndpoint.Equals method. - Assert.AreEqual(expectSreg ? 2 : 1, se.ProviderEndpoint.Capabilities.Count); - Assert.IsTrue(se.ProviderEndpoint.Capabilities.Contains(protocol.ClaimedIdentifierServiceTypeURI)); - Assert.AreEqual(expectSreg, se.ProviderEndpoint.IsExtensionSupported<ClaimsRequest>()); + Assert.AreEqual(expectSreg ? 2 : 1, se.Capabilities.Count); + Assert.IsTrue(se.Capabilities.Contains(protocol.ClaimedIdentifierServiceTypeURI)); + Assert.AreEqual(expectSreg, se.IsExtensionSupported<ClaimsRequest>()); } private void DiscoverXrds(string page, ProtocolVersion version, Identifier expectedLocalId, string providerEndpoint) { diff --git a/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/XriDiscoveryProxyServiceTests.cs b/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/XriDiscoveryProxyServiceTests.cs index b3383a4..404f37d 100644 --- a/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/XriDiscoveryProxyServiceTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/XriDiscoveryProxyServiceTests.cs @@ -10,7 +10,6 @@ namespace DotNetOpenAuth.Test.OpenId.DiscoveryServices { using System.Linq; using System.Text; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.RelyingParty; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -56,11 +55,11 @@ namespace DotNetOpenAuth.Test.OpenId.DiscoveryServices { this.MockResponder.RegisterMockXrdsResponses(mocks); string expectedCanonicalId = "=!9B72.7DD1.50A9.5CCD"; - IIdentifierDiscoveryResult se = this.VerifyCanonicalId("=Arnott", expectedCanonicalId); - Assert.AreEqual(Protocol.V10, Protocol.Lookup(se.ProviderEndpoint.Version).ProtocolVersion); + IdentifierDiscoveryResult se = this.VerifyCanonicalId("=Arnott", expectedCanonicalId); + Assert.AreEqual(Protocol.V10, Protocol.Lookup(se.Version).ProtocolVersion); Assert.AreEqual("http://1id.com/sso", se.ProviderEndpoint.ToString()); Assert.AreEqual(se.ClaimedIdentifier, se.ProviderLocalIdentifier); - Assert.AreEqual("=Arnott", se.GetFriendlyIdentifierForDisplay()); + Assert.AreEqual("=Arnott", se.FriendlyIdentifierForDisplay); } [TestMethod] @@ -380,12 +379,12 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy this.VerifyCanonicalId("@id*andrewarnott", null); } - private IIdentifierDiscoveryResult VerifyCanonicalId(Identifier iname, string expectedClaimedIdentifier) { + private IdentifierDiscoveryResult VerifyCanonicalId(Identifier iname, string expectedClaimedIdentifier) { var se = this.Discover(iname).FirstOrDefault(); if (expectedClaimedIdentifier != null) { Assert.IsNotNull(se); Assert.AreEqual(expectedClaimedIdentifier, se.ClaimedIdentifier.ToString(), "i-name {0} discovery resulted in unexpected CanonicalId", iname); - Assert.IsTrue(se.ProviderEndpoint.Capabilities.Count > 0); + Assert.IsTrue(se.Capabilities.Count > 0); } else { Assert.IsNull(se); } diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionsInteropHelperRPRequestTests.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionsInteropHelperRPRequestTests.cs index 73dc2b3..447d49e 100644 --- a/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionsInteropHelperRPRequestTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionsInteropHelperRPRequestTests.cs @@ -119,7 +119,7 @@ namespace DotNetOpenAuth.Test.OpenId { /// </summary> /// <param name="typeUri">The type URI.</param> private void InjectAdvertisedTypeUri(string typeUri) { - var serviceEndpoint = ProviderEndpointDescription_Accessor.AttachShadow(((ProviderEndpointDescription)this.authReq.Provider)); + var serviceEndpoint = ProviderEndpointDescription_Accessor.AttachShadow(this.authReq.Provider); serviceEndpoint.Capabilities = new ReadOnlyCollection<string>( serviceEndpoint.Capabilities.Concat(new[] { typeUri }).ToList()); } diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs index 9889fac..5492bcc 100644 --- a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs +++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs @@ -13,7 +13,6 @@ namespace DotNetOpenAuth.Test.OpenId { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Provider; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Test.Mocks; @@ -118,11 +117,11 @@ namespace DotNetOpenAuth.Test.OpenId { } } - internal static IIdentifierDiscoveryResult GetServiceEndpoint(int user, ProtocolVersion providerVersion, int servicePriority, bool useSsl) { + internal static IdentifierDiscoveryResult GetServiceEndpoint(int user, ProtocolVersion providerVersion, int servicePriority, bool useSsl) { return GetServiceEndpoint(user, providerVersion, servicePriority, useSsl, false); } - internal static IIdentifierDiscoveryResult GetServiceEndpoint(int user, ProtocolVersion providerVersion, int servicePriority, bool useSsl, bool delegating) { + internal static IdentifierDiscoveryResult GetServiceEndpoint(int user, ProtocolVersion providerVersion, int servicePriority, bool useSsl, bool delegating) { var providerEndpoint = new ProviderEndpointDescription( useSsl ? OpenIdTestBase.OPUriSsl : OpenIdTestBase.OPUri, new string[] { Protocol.Lookup(providerVersion).ClaimedIdentifierServiceTypeURI }); @@ -178,7 +177,7 @@ namespace DotNetOpenAuth.Test.OpenId { } } - internal IEnumerable<IIdentifierDiscoveryResult> Discover(Identifier identifier) { + internal IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier) { var rp = this.CreateRelyingParty(true); rp.Channel.WebRequestHandler = this.RequestHandler; return rp.Discover(identifier); @@ -200,7 +199,7 @@ namespace DotNetOpenAuth.Test.OpenId { protected Identifier GetMockIdentifier(ProtocolVersion providerVersion, bool useSsl, bool delegating) { var se = GetServiceEndpoint(0, providerVersion, 10, useSsl, delegating); UriIdentifier identityUri = (UriIdentifier)se.ClaimedIdentifier; - return new MockIdentifier(identityUri, this.MockResponder, new IIdentifierDiscoveryResult[] { se }); + return new MockIdentifier(identityUri, this.MockResponder, new IdentifierDiscoveryResult[] { se }); } /// <summary> diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdUtilitiesTests.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdUtilitiesTests.cs index 1a68d0a..389ef81 100644 --- a/src/DotNetOpenAuth.Test/OpenId/OpenIdUtilitiesTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdUtilitiesTests.cs @@ -16,50 +16,5 @@ namespace DotNetOpenAuth.Test.OpenId { [TestClass] public class OpenIdUtilitiesTests : OpenIdTestBase { - private ProviderEndpointDescription se; - - private string[] v20TypeUris = { Protocol.V20.ClaimedIdentifierServiceTypeURI }; - - [TestInitialize] - public override void SetUp() { - base.SetUp(); - - this.se = new ProviderEndpointDescription(OPUri, Protocol.V20.Version); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void IsExtensionSupportedNullType() { - this.se.IsExtensionSupported((Type)null); - } - - [TestMethod, ExpectedException(typeof(ArgumentException))] - public void IsTypeUriPresentNullString() { - this.se.IsTypeUriPresent((string)null); - } - - [TestMethod, ExpectedException(typeof(ArgumentException))] - public void IsTypeUriPresentEmptyString() { - this.se.IsTypeUriPresent(string.Empty); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void IsExtensionSupportedNullExtension() { - this.se.IsExtensionSupported((IOpenIdMessageExtension)null); - } - - [TestMethod] - public void IsExtensionSupported() { - this.se = new ProviderEndpointDescription(OPUri, this.v20TypeUris); - Assert.IsFalse(this.se.IsExtensionSupported<ClaimsRequest>()); - Assert.IsFalse(this.se.IsExtensionSupported(new ClaimsRequest())); - Assert.IsFalse(this.se.IsTypeUriPresent("http://someextension/typeuri")); - - this.se = new ProviderEndpointDescription( - OPUri, - new[] { Protocol.V20.ClaimedIdentifierServiceTypeURI, "http://someextension", Constants.sreg_ns }); - Assert.IsTrue(this.se.IsExtensionSupported<ClaimsRequest>()); - Assert.IsTrue(this.se.IsExtensionSupported(new ClaimsRequest())); - Assert.IsTrue(this.se.IsTypeUriPresent("http://someextension")); - } } } diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/AuthenticationRequestTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/AuthenticationRequestTests.cs index fea672d..1445e1d 100644 --- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/AuthenticationRequestTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/AuthenticationRequestTests.cs @@ -13,7 +13,6 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; using DotNetOpenAuth.OpenId.Messages; using DotNetOpenAuth.OpenId.RelyingParty; @@ -63,7 +62,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { [TestMethod] public void ProviderVersion() { var authRequest = this.CreateAuthenticationRequest(this.claimedId, this.claimedId); - Assert.AreEqual(this.protocol.Version, authRequest.DiscoveryResult.ProviderEndpoint.GetProtocol().Version); + Assert.AreEqual(this.protocol.Version, authRequest.DiscoveryResult.Version); } /// <summary> @@ -184,7 +183,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { private AuthenticationRequest CreateAuthenticationRequest(Identifier claimedIdentifier, Identifier providerLocalIdentifier) { ProviderEndpointDescription providerEndpoint = new ProviderEndpointDescription(OPUri, this.protocol.Version); - IIdentifierDiscoveryResult endpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, providerLocalIdentifier, providerEndpoint, 10, 5); + IdentifierDiscoveryResult endpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, providerLocalIdentifier, providerEndpoint, 10, 5); OpenIdRelyingParty rp = this.CreateRelyingParty(); return AuthenticationRequest.CreateForTest(endpoint, this.realm, this.returnTo, rp); } diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs index 87969b1..701bcae 100644 --- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs @@ -38,7 +38,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { Assert.AreEqual(AuthenticationStatus.Authenticated, authResponse.Status); Assert.IsNull(authResponse.Exception); Assert.AreEqual<string>(assertion.ClaimedIdentifier, authResponse.ClaimedIdentifier); - Assert.AreEqual<string>(authResponse.Endpoint.GetFriendlyIdentifierForDisplay(), authResponse.FriendlyIdentifierForDisplay); + Assert.AreEqual<string>(authResponse.Endpoint.FriendlyIdentifierForDisplay, authResponse.FriendlyIdentifierForDisplay); Assert.AreSame(extension, authResponse.GetUntrustedExtension(typeof(ClaimsResponse))); Assert.AreSame(extension, authResponse.GetUntrustedExtension<ClaimsResponse>()); Assert.IsNull(authResponse.GetCallbackArgument("a")); diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs index 6718213..a7d9752 100644 --- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs @@ -12,7 +12,6 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; using DotNetOpenAuth.OpenId.Messages; using DotNetOpenAuth.OpenId.RelyingParty; @@ -31,43 +30,48 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { private int servicePriority = 10; private int uriPriority = 10; + [TestInitialize] + public override void SetUp() { + base.SetUp(); + } + [TestMethod] public void Ctor() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); Assert.AreEqual(this.claimedId, se.ClaimedIdentifier); Assert.AreSame(this.providerEndpoint, se.ProviderEndpoint); Assert.AreSame(this.localId, se.ProviderLocalIdentifier); - CollectionAssert<string>.AreEquivalent(this.v20TypeUris, se.ProviderEndpoint.Capabilities); - Assert.AreEqual(this.servicePriority, ((IXrdsProviderEndpoint)se).ServicePriority); + CollectionAssert<string>.AreEquivalent(this.v20TypeUris, se.Capabilities); + Assert.AreEqual(this.servicePriority, se.ServicePriority); } [TestMethod] public void CtorImpliedLocalIdentifier() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, null, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, null, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); Assert.AreEqual(this.claimedId, se.ClaimedIdentifier); Assert.AreSame(this.providerEndpoint, se.ProviderEndpoint); Assert.AreSame(this.claimedId, se.ProviderLocalIdentifier); - CollectionAssert<string>.AreEquivalent(this.v20TypeUris, se.ProviderEndpoint.Capabilities); + CollectionAssert<string>.AreEquivalent(this.v20TypeUris, se.Capabilities); } [TestMethod] public void ProtocolDetection() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); - Assert.AreSame(Protocol.V20, se.ProviderEndpoint.GetProtocol()); + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + Assert.AreSame(Protocol.V20, se.Protocol); se = IdentifierDiscoveryResult.CreateForClaimedIdentifier( this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, new[] { Protocol.V20.OPIdentifierServiceTypeURI }), this.servicePriority, this.uriPriority); - Assert.AreSame(Protocol.V20, se.ProviderEndpoint.GetProtocol()); + Assert.AreSame(Protocol.V20, se.Protocol); se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v11TypeUris), this.servicePriority, this.uriPriority); - Assert.AreSame(Protocol.V11, se.ProviderEndpoint.GetProtocol()); + Assert.AreSame(Protocol.V11, se.Protocol); } [TestMethod, ExpectedException(typeof(ProtocolException))] public void ProtocolDetectionWithoutClues() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier( + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier( this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, new[] { Protocol.V20.HtmlDiscoveryLocalIdKey }), // random type URI irrelevant to detection @@ -77,13 +81,13 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { [TestMethod] public void EqualsTests() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); - IIdentifierDiscoveryResult se2 = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), (int?)null, (int?)null); + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + IdentifierDiscoveryResult se2 = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), (int?)null, (int?)null); Assert.AreEqual(se2, se); Assert.AreNotEqual(se, null); Assert.AreNotEqual(null, se); - IIdentifierDiscoveryResult se3 = IdentifierDiscoveryResult.CreateForClaimedIdentifier(new UriIdentifier(this.claimedId + "a"), this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + IdentifierDiscoveryResult se3 = IdentifierDiscoveryResult.CreateForClaimedIdentifier(new UriIdentifier(this.claimedId + "a"), this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); Assert.AreNotEqual(se, se3); se3 = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedId, this.localId, new ProviderEndpointDescription(new Uri(this.providerEndpoint.AbsoluteUri + "a"), this.v20TypeUris), this.servicePriority, this.uriPriority); Assert.AreNotEqual(se, se3); @@ -93,7 +97,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { Assert.AreNotEqual(se, se3); // make sure that Collection<T>.Contains works as desired. - var list = new List<IIdentifierDiscoveryResult>(); + var list = new List<IdentifierDiscoveryResult>(); list.Add(se); Assert.IsTrue(list.Contains(se2)); } @@ -105,7 +109,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { string[] serviceTypeUris = new string[] { Protocol.V20.ClaimedIdentifierServiceTypeURI, }; - IIdentifierDiscoveryResult se; + IdentifierDiscoveryResult se; // strip of protocol, port, query and fragment se = IdentifierDiscoveryResult.CreateForClaimedIdentifier( @@ -114,12 +118,12 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { new ProviderEndpointDescription(providerEndpoint, serviceTypeUris), null, null); - Assert.AreEqual("someprovider.somedomain.com/someuser", se.GetFriendlyIdentifierForDisplay()); + Assert.AreEqual("someprovider.somedomain.com/someuser", se.FriendlyIdentifierForDisplay); // unescape characters Uri foreignUri = new Uri("http://server崎/村"); se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(foreignUri, localId, new ProviderEndpointDescription(providerEndpoint, serviceTypeUris), null, null); - Assert.AreEqual("server崎/村", se.GetFriendlyIdentifierForDisplay()); + Assert.AreEqual("server崎/村", se.FriendlyIdentifierForDisplay); // restore user supplied identifier to XRIs se = IdentifierDiscoveryResult.CreateForClaimedIdentifier( @@ -129,7 +133,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { new ProviderEndpointDescription(providerEndpoint, serviceTypeUris), null, null); - Assert.AreEqual("=Arnott崎村", se.GetFriendlyIdentifierForDisplay()); + Assert.AreEqual("=Arnott崎村", se.FriendlyIdentifierForDisplay); // If UserSuppliedIdentifier is the same as the ClaimedIdentifier, don't display it twice... se = IdentifierDiscoveryResult.CreateForClaimedIdentifier( @@ -139,26 +143,67 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { new ProviderEndpointDescription(providerEndpoint, serviceTypeUris), null, null); - Assert.AreEqual("=!9B72.7DD1.50A9.5CCD", se.GetFriendlyIdentifierForDisplay()); + Assert.AreEqual("=!9B72.7DD1.50A9.5CCD", se.FriendlyIdentifierForDisplay); } [TestMethod] public void IsTypeUriPresent() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedXri, this.userSuppliedXri, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); - Assert.IsTrue(se.ProviderEndpoint.IsTypeUriPresent(Protocol.Default.ClaimedIdentifierServiceTypeURI)); - Assert.IsFalse(se.ProviderEndpoint.IsTypeUriPresent("http://someother")); + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedXri, this.userSuppliedXri, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + Assert.IsTrue(se.IsTypeUriPresent(Protocol.Default.ClaimedIdentifierServiceTypeURI)); + Assert.IsFalse(se.IsTypeUriPresent("http://someother")); } [TestMethod, ExpectedException(typeof(ArgumentException))] public void IsTypeUriPresentNull() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedXri, this.userSuppliedXri, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); - se.ProviderEndpoint.IsTypeUriPresent(null); + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedXri, this.userSuppliedXri, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + se.IsTypeUriPresent(null); } [TestMethod, ExpectedException(typeof(ArgumentException))] public void IsTypeUriPresentEmpty() { - IIdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedXri, this.userSuppliedXri, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); - se.ProviderEndpoint.IsTypeUriPresent(string.Empty); + IdentifierDiscoveryResult se = IdentifierDiscoveryResult.CreateForClaimedIdentifier(this.claimedXri, this.userSuppliedXri, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority); + se.IsTypeUriPresent(string.Empty); + } + + [TestMethod, ExpectedException(typeof(ArgumentNullException))] + public void IsExtensionSupportedNullType() { + var se = IdentifierDiscoveryResult.CreateForProviderIdentifier(OPUri, new ProviderEndpointDescription(OPUri, this.v20TypeUris), null, null); + se.IsExtensionSupported((Type)null); + } + + [TestMethod, ExpectedException(typeof(ArgumentException))] + public void IsTypeUriPresentNullString() { + var se = IdentifierDiscoveryResult.CreateForProviderIdentifier(OPUri, new ProviderEndpointDescription(OPUri, this.v20TypeUris), null, null); + se.IsTypeUriPresent((string)null); + } + + [TestMethod, ExpectedException(typeof(ArgumentException))] + public void IsTypeUriPresentEmptyString() { + var se = IdentifierDiscoveryResult.CreateForProviderIdentifier(OPUri, new ProviderEndpointDescription(OPUri, this.v20TypeUris), null, null); + se.IsTypeUriPresent(string.Empty); + } + + [TestMethod, ExpectedException(typeof(ArgumentNullException))] + public void IsExtensionSupportedNullExtension() { + var se = IdentifierDiscoveryResult.CreateForProviderIdentifier(OPUri, new ProviderEndpointDescription(OPUri, this.v20TypeUris), null, null); + se.IsExtensionSupported((IOpenIdMessageExtension)null); + } + + [TestMethod] + public void IsExtensionSupported() { + var se = IdentifierDiscoveryResult.CreateForProviderIdentifier(OPUri, new ProviderEndpointDescription(OPUri, this.v20TypeUris), null, null); + Assert.IsFalse(se.IsExtensionSupported<ClaimsRequest>()); + Assert.IsFalse(se.IsExtensionSupported(new ClaimsRequest())); + Assert.IsFalse(se.IsTypeUriPresent("http://someextension/typeuri")); + + se = IdentifierDiscoveryResult.CreateForProviderIdentifier( + OPUri, + new ProviderEndpointDescription(OPUri, new[] { Protocol.V20.ClaimedIdentifierServiceTypeURI, "http://someextension", Constants.sreg_ns }), + null, + null); + Assert.IsTrue(se.IsExtensionSupported<ClaimsRequest>()); + Assert.IsTrue(se.IsExtensionSupported(new ClaimsRequest())); + Assert.IsTrue(se.IsTypeUriPresent("http://someextension")); } } } diff --git a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs index de41ff0..2ee2e91 100644 --- a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs +++ b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs @@ -9,7 +9,6 @@ namespace DotNetOpenAuth.Configuration { using System.Configuration; using System.Diagnostics.Contracts; using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 1a20bd6..95a7150 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -437,7 +437,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OpenId\Interop\AuthenticationResponseShim.cs" /> <Compile Include="OpenId\Interop\ClaimsResponseShim.cs" /> <Compile Include="OpenId\Interop\OpenIdRelyingPartyShim.cs" /> - <Compile Include="OpenId\DiscoveryServices\IIdentifierDiscoveryService.cs" /> + <Compile Include="OpenId\IIdentifierDiscoveryService.cs" /> <Compile Include="OpenId\Messages\CheckAuthenticationRequest.cs" /> <Compile Include="OpenId\Messages\CheckAuthenticationResponse.cs" /> <Compile Include="OpenId\Messages\CheckIdRequest.cs" /> @@ -504,7 +504,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OpenId\RelyingParty\AssociationPreference.cs" /> <Compile Include="OpenId\RelyingParty\AuthenticationRequest.cs" /> <Compile Include="OpenId\RelyingParty\AuthenticationRequestMode.cs" /> - <Compile Include="OpenId\DiscoveryServices\IIdentifierDiscoveryResult.cs" /> + <Compile Include="OpenId\RelyingParty\IProviderEndpoint.cs" /> <Compile Include="OpenId\RelyingParty\SelectorButtonContract.cs" /> <Compile Include="OpenId\RelyingParty\SelectorProviderButton.cs" /> <Compile Include="OpenId\RelyingParty\SelectorOpenIdButton.cs" /> @@ -512,7 +512,6 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OpenId\RelyingParty\IRelyingPartyBehavior.cs" /> <Compile Include="OpenId\RelyingParty\OpenIdSelector.cs" /> <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.cs" /> - <Compile Include="OpenId\RelyingParty\IXrdsProviderEndpointContract.cs" /> <Compile Include="OpenId\RelyingParty\IAuthenticationRequestContract.cs" /> <Compile Include="OpenId\RelyingParty\NegativeAuthenticationResponse.cs" /> <Compile Include="OpenId\RelyingParty\OpenIdAjaxTextBox.cs" /> @@ -529,9 +528,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OpenId\RelyingParty\FailedAuthenticationResponse.cs" /> <Compile Include="OpenId\RelyingParty\IAuthenticationRequest.cs" /> <Compile Include="OpenId\RelyingParty\IAuthenticationResponse.cs" /> - <Compile Include="OpenId\RelyingParty\IProviderEndpoint.cs" /> <Compile Include="OpenId\RelyingParty\ISetupRequiredAuthenticationResponse.cs" /> - <Compile Include="OpenId\RelyingParty\IXrdsProviderEndpoint.cs" /> <Compile Include="OpenId\RelyingParty\OpenIdRelyingParty.cs" /> <Compile Include="OpenId\OpenIdStrings.Designer.cs"> <DependentUpon>OpenIdStrings.resx</DependentUpon> @@ -546,7 +543,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OpenId\RelyingParty\PrivateSecretManager.cs" /> <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" /> <Compile Include="OpenId\RelyingParty\SelectorButton.cs" /> - <Compile Include="OpenId\DiscoveryServices\IdentifierDiscoveryResult.cs" /> + <Compile Include="OpenId\IdentifierDiscoveryResult.cs" /> <Compile Include="OpenId\OpenIdXrdsHelper.cs" /> <Compile Include="OpenId\RelyingParty\SimpleXrdsProviderEndpoint.cs" /> <Compile Include="OpenId\RelyingParty\StandardRelyingPartyApplicationStore.cs" /> @@ -554,9 +551,9 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OpenId\RelyingParty\WellKnownProviders.cs" /> <Compile Include="OpenId\SecuritySettings.cs" /> <Compile Include="Messaging\UntrustedWebRequestHandler.cs" /> - <Compile Include="OpenId\DiscoveryServices\UriDiscoveryService.cs" /> + <Compile Include="OpenId\UriDiscoveryService.cs" /> <Compile Include="OpenId\UriIdentifier.cs" /> - <Compile Include="OpenId\DiscoveryServices\XriDiscoveryProxyService.cs" /> + <Compile Include="OpenId\XriDiscoveryProxyService.cs" /> <Compile Include="OpenId\XriIdentifier.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="OAuth\Messages\UnauthorizedTokenRequest.cs" /> diff --git a/src/DotNetOpenAuth/OpenId/DiscoveryServices/IIdentifierDiscoveryResult.cs b/src/DotNetOpenAuth/OpenId/DiscoveryServices/IIdentifierDiscoveryResult.cs deleted file mode 100644 index 4ac6dab..0000000 --- a/src/DotNetOpenAuth/OpenId/DiscoveryServices/IIdentifierDiscoveryResult.cs +++ /dev/null @@ -1,108 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="IIdentifierDiscoveryResult.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OpenId.DiscoveryServices { - using System; - using System.Collections.Generic; - using System.Diagnostics.Contracts; - using System.Linq; - using System.Text; - using DotNetOpenAuth.OpenId.RelyingParty; - - /// <summary> - /// An self-describing result of discovery on some identifier; perhaps one of many. - /// </summary> - [ContractClass(typeof(IIdentifierDiscoveryResultContract))] - internal interface IIdentifierDiscoveryResult { - /// <summary> - /// Gets the provider endpoint. - /// </summary> - /// <value>The discovered provider endpoint. May optionally implement <see cref="IXrdsProviderEndpoint"/>.</value> - IProviderEndpoint ProviderEndpoint { get; } - - /// <summary> - /// Gets the Identifier that the end user claims to control. - /// </summary> - Identifier ClaimedIdentifier { get; } - - /// <summary> - /// Gets an alternate Identifier for an end user that is local to a - /// particular OP and thus not necessarily under the end user's - /// control. - /// </summary> - Identifier ProviderLocalIdentifier { get; } - - /// <summary> - /// Gets the Identifier that was presented by the end user to the Relying Party, - /// or selected by the user at the OpenID Provider. - /// During the initiation phase of the protocol, an end user may enter - /// either their own Identifier or an OP Identifier. If an OP Identifier - /// is used, the OP may then assist the end user in selecting an Identifier - /// to share with the Relying Party. - /// </summary> - Identifier UserSuppliedIdentifier { get; } - } - - /// <summary> - /// Code contract class for the <see cref="IIdentifierDiscoveryResult"/> interface. - /// </summary> - [ContractClassFor(typeof(IIdentifierDiscoveryResult))] - internal class IIdentifierDiscoveryResultContract : IIdentifierDiscoveryResult { - #region IIdentifierDiscoveryResult Members - - /// <summary> - /// Gets the provider endpoint. - /// </summary> - /// <value> - /// The discovered provider endpoint. May optionally implement <see cref="IXrdsProviderEndpoint"/>. - /// </value> - IProviderEndpoint IIdentifierDiscoveryResult.ProviderEndpoint { - get { - Contract.Ensures(Contract.Result<IProviderEndpoint>() != null); - throw new NotImplementedException(); - } - } - - /// <summary> - /// Gets the Identifier that the end user claims to control. - /// </summary> - Identifier IIdentifierDiscoveryResult.ClaimedIdentifier { - get { - Contract.Ensures(Contract.Result<Identifier>() != null); - throw new NotImplementedException(); - } - } - - /// <summary> - /// Gets the Identifier that was presented by the end user to the Relying Party, - /// or selected by the user at the OpenID Provider. - /// During the initiation phase of the protocol, an end user may enter - /// either their own Identifier or an OP Identifier. If an OP Identifier - /// is used, the OP may then assist the end user in selecting an Identifier - /// to share with the Relying Party. - /// </summary> - Identifier IIdentifierDiscoveryResult.UserSuppliedIdentifier { - get { - Contract.Ensures(Contract.Result<Identifier>() != null); - throw new NotImplementedException(); - } - } - - /// <summary> - /// Gets an alternate Identifier for an end user that is local to a - /// particular OP and thus not necessarily under the end user's - /// control. - /// </summary> - Identifier IIdentifierDiscoveryResult.ProviderLocalIdentifier { - get { - Contract.Ensures(Contract.Result<Identifier>() != null); - throw new NotImplementedException(); - } - } - - #endregion - } -} diff --git a/src/DotNetOpenAuth/OpenId/DiscoveryServices/IdentifierDiscoveryResult.cs b/src/DotNetOpenAuth/OpenId/DiscoveryServices/IdentifierDiscoveryResult.cs deleted file mode 100644 index ad77c17..0000000 --- a/src/DotNetOpenAuth/OpenId/DiscoveryServices/IdentifierDiscoveryResult.cs +++ /dev/null @@ -1,307 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="IdentifierDiscoveryResult.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OpenId.DiscoveryServices { - using System; - using System.Collections.ObjectModel; - using System.Diagnostics; - using System.Diagnostics.Contracts; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.DiscoveryServices; - using DotNetOpenAuth.OpenId.Messages; - using DotNetOpenAuth.OpenId.RelyingParty; - - /// <summary> - /// Represents a single OP endpoint from discovery on some OpenID Identifier. - /// </summary> - [DebuggerDisplay("ClaimedIdentifier: {ClaimedIdentifier}, ProviderEndpoint: {ProviderEndpoint}, OpenId: {Protocol.Version}")] - internal class IdentifierDiscoveryResult : IIdentifierDiscoveryResult { - /// <summary> - /// Backing field for the <see cref="ClaimedIdentifier"/> property. - /// </summary> - private Identifier claimedIdentifier; - - /// <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; - - /// <summary> - /// Initializes a new instance of the <see cref="IdentifierDiscoveryResult"/> class. - /// </summary> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <param name="claimedIdentifier">The Claimed Identifier.</param> - /// <param name="userSuppliedIdentifier">The User-supplied Identifier.</param> - /// <param name="providerLocalIdentifier">The Provider Local Identifier.</param> - /// <param name="servicePriority">The service priority.</param> - /// <param name="uriPriority">The URI priority.</param> - private IdentifierDiscoveryResult(IProviderEndpoint providerEndpoint, Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, int? servicePriority, int? uriPriority) { - Contract.Requires<ArgumentNullException>(claimedIdentifier != null); - Contract.Requires<ArgumentNullException>(providerEndpoint != null); - this.ProviderEndpoint = providerEndpoint; - this.ClaimedIdentifier = claimedIdentifier; - this.UserSuppliedIdentifier = userSuppliedIdentifier; - this.ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier; - this.servicePriority = servicePriority; - this.uriPriority = uriPriority; - } - - /// <summary> - /// Gets the Identifier that was presented by the end user to the Relying Party, - /// or selected by the user at the OpenID Provider. - /// During the initiation phase of the protocol, an end user may enter - /// either their own Identifier or an OP Identifier. If an OP Identifier - /// is used, the OP may then assist the end user in selecting an Identifier - /// to share with the Relying Party. - /// </summary> - public Identifier UserSuppliedIdentifier { get; private set; } - - /// <summary> - /// Gets or sets the Identifier that the end user claims to control. - /// </summary> - public Identifier ClaimedIdentifier { - get { - return this.claimedIdentifier; - } - - set { - // Take care to reparse the incoming identifier to make sure it's - // not a derived type that will override expected behavior. - // Elsewhere in this class, we count on the fact that this property - // is either UriIdentifier or XriIdentifier. MockIdentifier messes it up. - this.claimedIdentifier = value != null ? Identifier.Parse(value) : null; - } - } - - /// <summary> - /// Gets an alternate Identifier for an end user that is local to a - /// particular OP and thus not necessarily under the end user's - /// control. - /// </summary> - public Identifier ProviderLocalIdentifier { get; private set; } - - /// <summary> - /// Gets the provider endpoint. - /// </summary> - /// <value> - /// The discovered provider endpoint. May optionally implement <see cref="IXrdsProviderEndpoint"/>. - /// </value> - public IProviderEndpoint ProviderEndpoint { get; private set; } - - /// <summary> - /// Gets an XRDS sorting routine that uses the XRDS Service/@Priority - /// attribute to determine order. - /// </summary> - /// <remarks> - /// Endpoints lacking any priority value are sorted to the end of the list. - /// </remarks> - internal static Comparison<IXrdsProviderEndpoint> EndpointOrder { - get { - // Sort first by service type (OpenID 2.0, 1.1, 1.0), - // then by Service/@priority, then by Service/Uri/@priority - return (se1, se2) => { - int result = GetEndpointPrecedenceOrderByServiceType(se1).CompareTo(GetEndpointPrecedenceOrderByServiceType(se2)); - if (result != 0) { - return result; - } - if (se1.ServicePriority.HasValue && se2.ServicePriority.HasValue) { - result = se1.ServicePriority.Value.CompareTo(se2.ServicePriority.Value); - if (result != 0) { - return result; - } - if (se1.UriPriority.HasValue && se2.UriPriority.HasValue) { - return se1.UriPriority.Value.CompareTo(se2.UriPriority.Value); - } else if (se1.UriPriority.HasValue) { - return -1; - } else if (se2.UriPriority.HasValue) { - return 1; - } else { - return 0; - } - } else { - if (se1.ServicePriority.HasValue) { - return -1; - } else if (se2.ServicePriority.HasValue) { - return 1; - } else { - // neither service defines a priority, so base ordering by uri priority. - if (se1.UriPriority.HasValue && se2.UriPriority.HasValue) { - return se1.UriPriority.Value.CompareTo(se2.UriPriority.Value); - } else if (se1.UriPriority.HasValue) { - return -1; - } else if (se2.UriPriority.HasValue) { - return 1; - } else { - return 0; - } - } - } - }; - } - } - - /// <summary> - /// Implements the operator ==. - /// </summary> - /// <param name="se1">The first service endpoint.</param> - /// <param name="se2">The second service endpoint.</param> - /// <returns>The result of the operator.</returns> - public static bool operator ==(IdentifierDiscoveryResult se1, IdentifierDiscoveryResult se2) { - return se1.EqualsNullSafe(se2); - } - - /// <summary> - /// Implements the operator !=. - /// </summary> - /// <param name="se1">The first service endpoint.</param> - /// <param name="se2">The second service endpoint.</param> - /// <returns>The result of the operator.</returns> - public static bool operator !=(IdentifierDiscoveryResult se1, IdentifierDiscoveryResult se2) { - return !(se1 == se2); - } - - /// <summary> - /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>. - /// </summary> - /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param> - /// <returns> - /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false. - /// </returns> - /// <exception cref="T:System.NullReferenceException"> - /// The <paramref name="obj"/> parameter is null. - /// </exception> - public override bool Equals(object obj) { - var other = obj as IIdentifierDiscoveryResult; - if (other == null) { - return false; - } - - // We specifically do not check our ProviderSupportedServiceTypeUris array - // or the priority field - // as that is not persisted in our tokens, and it is not part of the - // important assertion validation that is part of the spec. - return - this.ClaimedIdentifier == other.ClaimedIdentifier && - this.ProviderEndpoint == other.ProviderEndpoint && - this.ProviderLocalIdentifier == other.ProviderLocalIdentifier && - this.ProviderEndpoint.GetProtocol().EqualsPractically(other.ProviderEndpoint.GetProtocol()); - } - - /// <summary> - /// Serves as a hash function for a particular type. - /// </summary> - /// <returns> - /// A hash code for the current <see cref="T:System.Object"/>. - /// </returns> - public override int GetHashCode() { - return this.ClaimedIdentifier.GetHashCode(); - } - - /// <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() { - StringBuilder builder = new StringBuilder(); - builder.AppendLine("ClaimedIdentifier: " + this.ClaimedIdentifier); - builder.AppendLine("ProviderLocalIdentifier: " + this.ProviderLocalIdentifier); - builder.AppendLine("ProviderEndpoint: " + this.ProviderEndpoint.Uri.AbsoluteUri); - builder.AppendLine("OpenID version: " + this.ProviderEndpoint.Version); - builder.AppendLine("Service Type URIs:"); - foreach (string serviceTypeUri in this.ProviderEndpoint.Capabilities) { - builder.Append("\t"); - builder.AppendLine(serviceTypeUri); - } - builder.Length -= Environment.NewLine.Length; // trim last newline - return builder.ToString(); - } - - /// <summary> - /// Creates a <see cref="IIdentifierDiscoveryResult"/> instance to represent some OP Identifier. - /// </summary> - /// <param name="providerIdentifier">The provider identifier (actually the user-supplied identifier).</param> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <param name="servicePriority">The service priority.</param> - /// <param name="uriPriority">The URI priority.</param> - /// <returns>The created <see cref="IIdentifierDiscoveryResult"/> instance</returns> - internal static IIdentifierDiscoveryResult CreateForProviderIdentifier(Identifier providerIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) { - Contract.Requires<ArgumentNullException>(providerEndpoint != null); - - Protocol protocol = Protocol.Detect(providerEndpoint.Capabilities); - - return new IdentifierDiscoveryResult( - providerEndpoint, - protocol.ClaimedIdentifierForOPIdentifier, - providerIdentifier, - protocol.ClaimedIdentifierForOPIdentifier, - servicePriority, - uriPriority); - } - - /// <summary> - /// Creates a <see cref="IIdentifierDiscoveryResult"/> instance to represent some Claimed Identifier. - /// </summary> - /// <param name="claimedIdentifier">The claimed identifier.</param> - /// <param name="providerLocalIdentifier">The provider local identifier.</param> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <param name="servicePriority">The service priority.</param> - /// <param name="uriPriority">The URI priority.</param> - /// <returns>The created <see cref="IIdentifierDiscoveryResult"/> instance</returns> - internal static IIdentifierDiscoveryResult CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier providerLocalIdentifier, IProviderEndpoint providerEndpoint, int? servicePriority, int? uriPriority) { - return CreateForClaimedIdentifier(claimedIdentifier, null, providerLocalIdentifier, providerEndpoint, servicePriority, uriPriority); - } - - /// <summary> - /// Creates a <see cref="IIdentifierDiscoveryResult"/> instance to represent some Claimed Identifier. - /// </summary> - /// <param name="claimedIdentifier">The claimed identifier.</param> - /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> - /// <param name="providerLocalIdentifier">The provider local identifier.</param> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <param name="servicePriority">The service priority.</param> - /// <param name="uriPriority">The URI priority.</param> - /// <returns>The created <see cref="IdentifierDiscoveryResult"/> instance</returns> - internal static IIdentifierDiscoveryResult CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, IProviderEndpoint providerEndpoint, int? servicePriority, int? uriPriority) { - return new IdentifierDiscoveryResult(providerEndpoint, claimedIdentifier, userSuppliedIdentifier, providerLocalIdentifier, servicePriority, uriPriority); - } - - /// <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(IXrdsProviderEndpoint 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.IsTypeUriPresent(Protocol.V20.OPIdentifierServiceTypeURI)) { - return 0; - } - if (endpoint.IsTypeUriPresent(Protocol.V20.ClaimedIdentifierServiceTypeURI)) { - return 1; - } - if (endpoint.IsTypeUriPresent(Protocol.V11.ClaimedIdentifierServiceTypeURI)) { - return 2; - } - if (endpoint.IsTypeUriPresent(Protocol.V10.ClaimedIdentifierServiceTypeURI)) { - return 3; - } - return 10; - } - } -} diff --git a/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs b/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs index f8d2d17..fd9bb7b 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs @@ -51,7 +51,7 @@ namespace DotNetOpenAuth.OpenId.Extensions { return; } - if (req.Provider.IsExtensionSupported<ClaimsRequest>()) { + if (req.DiscoveryResult.IsExtensionSupported<ClaimsRequest>()) { Logger.OpenId.Info("Skipping generation of AX request because the Identifier advertises the Provider supports the Sreg extension."); return; } @@ -276,7 +276,7 @@ namespace DotNetOpenAuth.OpenId.Extensions { /// <returns>The AX format(s) to use based on the Provider's advertised AX support.</returns> private static bool TryDetectOPAttributeFormat(RelyingParty.IAuthenticationRequest request, out AXAttributeFormats attributeFormat) { Contract.Requires<ArgumentNullException>(request != null); - attributeFormat = DetectAXFormat(request.Provider.Capabilities); + attributeFormat = DetectAXFormat(request.DiscoveryResult.Capabilities); return attributeFormat != AXAttributeFormats.None; } diff --git a/src/DotNetOpenAuth/OpenId/Extensions/UI/UIRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/UI/UIRequest.cs index dddb1a6..67efe8e 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/UI/UIRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/UI/UIRequest.cs @@ -28,7 +28,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.UI { /// <see cref="UIModes.Popup"/>. </para> /// <para>An RP may determine whether an arbitrary OP supports this extension (and thereby determine /// whether to use a standard full window redirect or a popup) via the - /// <see cref="OpenIdUtilities.IsExtensionSupported<T>(IProviderEndpoint)"/> method.</para> + /// <see cref="IdentifierDiscoveryResult.IsExtensionSupported<T>()"/> method.</para> /// </remarks> public sealed class UIRequest : IOpenIdMessageExtension, IMessageWithEvents { /// <summary> diff --git a/src/DotNetOpenAuth/OpenId/DiscoveryServices/IIdentifierDiscoveryService.cs b/src/DotNetOpenAuth/OpenId/IIdentifierDiscoveryService.cs index 3a8950e..e98218d 100644 --- a/src/DotNetOpenAuth/OpenId/DiscoveryServices/IIdentifierDiscoveryService.cs +++ b/src/DotNetOpenAuth/OpenId/IIdentifierDiscoveryService.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.OpenId.DiscoveryServices { +namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -28,7 +28,7 @@ namespace DotNetOpenAuth.OpenId.DiscoveryServices { /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. /// </returns> [Pure] - IEnumerable<IIdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain); + IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain); } /// <summary> @@ -47,10 +47,10 @@ namespace DotNetOpenAuth.OpenId.DiscoveryServices { /// <returns> /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. /// </returns> - IEnumerable<IIdentifierDiscoveryResult> IIdentifierDiscoveryService.Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { + IEnumerable<IdentifierDiscoveryResult> IIdentifierDiscoveryService.Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { Contract.Requires<ArgumentNullException>(identifier != null); Contract.Requires<ArgumentNullException>(requestHandler != null); - Contract.Ensures(Contract.Result<IEnumerable<IIdentifierDiscoveryResult>>() != null); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth/OpenId/IdentifierDiscoveryResult.cs b/src/DotNetOpenAuth/OpenId/IdentifierDiscoveryResult.cs new file mode 100644 index 0000000..45e97a1 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/IdentifierDiscoveryResult.cs @@ -0,0 +1,482 @@ +//----------------------------------------------------------------------- +// <copyright file="IdentifierDiscoveryResult.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId { + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Messages; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// <summary> + /// Represents a single OP endpoint from discovery on some OpenID Identifier. + /// </summary> + [DebuggerDisplay("ClaimedIdentifier: {ClaimedIdentifier}, ProviderEndpoint: {ProviderEndpoint}, OpenId: {Protocol.Version}")] + public sealed class IdentifierDiscoveryResult : IProviderEndpoint { + /// <summary> + /// Backing field for the <see cref="Protocol"/> property. + /// </summary> + private Protocol protocol; + + /// <summary> + /// Backing field for the <see cref="ClaimedIdentifier"/> property. + /// </summary> + private Identifier claimedIdentifier; + + /// <summary> + /// Backing field for the <see cref="FriendlyIdentifierForDisplay"/> property. + /// </summary> + private Identifier friendlyIdentifierForDisplay; + + /// <summary> + /// Initializes a new instance of the <see cref="IdentifierDiscoveryResult"/> class. + /// </summary> + /// <param name="providerEndpoint">The provider endpoint.</param> + /// <param name="claimedIdentifier">The Claimed Identifier.</param> + /// <param name="userSuppliedIdentifier">The User-supplied Identifier.</param> + /// <param name="providerLocalIdentifier">The Provider Local Identifier.</param> + /// <param name="servicePriority">The service priority.</param> + /// <param name="uriPriority">The URI priority.</param> + private IdentifierDiscoveryResult(ProviderEndpointDescription providerEndpoint, Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, int? servicePriority, int? uriPriority) { + Contract.Requires<ArgumentNullException>(providerEndpoint != null); + Contract.Requires<ArgumentNullException>(claimedIdentifier != null); + Contract.Requires<ArgumentNullException>(providerLocalIdentifier != null); + this.ProviderEndpoint = providerEndpoint.Uri; + this.Capabilities = new ReadOnlyCollection<string>(providerEndpoint.Capabilities); + this.Version = providerEndpoint.Version; + this.ClaimedIdentifier = claimedIdentifier; + this.ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier; + this.UserSuppliedIdentifier = userSuppliedIdentifier; + this.ServicePriority = servicePriority; + this.ProviderEndpointPriority = uriPriority; + } + + /// <summary> + /// Gets the detected version of OpenID implemented by the Provider. + /// </summary> + public Version Version { get; private set; } + + /// <summary> + /// Gets the Identifier that was presented by the end user to the Relying Party, + /// or selected by the user at the OpenID Provider. + /// During the initiation phase of the protocol, an end user may enter + /// either their own Identifier or an OP Identifier. If an OP Identifier + /// is used, the OP may then assist the end user in selecting an Identifier + /// to share with the Relying Party. + /// </summary> + public Identifier UserSuppliedIdentifier { get; private set; } + + /// <summary> + /// Gets the Identifier that the end user claims to control. + /// </summary> + public Identifier ClaimedIdentifier { + get { + return this.claimedIdentifier; + } + + internal set { + // Take care to reparse the incoming identifier to make sure it's + // not a derived type that will override expected behavior. + // Elsewhere in this class, we count on the fact that this property + // is either UriIdentifier or XriIdentifier. MockIdentifier messes it up. + this.claimedIdentifier = value != null ? Identifier.Parse(value) : null; + } + } + + /// <summary> + /// Gets an alternate Identifier for an end user that is local to a + /// particular OP and thus not necessarily under the end user's + /// control. + /// </summary> + public Identifier ProviderLocalIdentifier { get; private set; } + + /// <summary> + /// Gets a more user-friendly (but NON-secure!) string to display to the user as his identifier. + /// </summary> + /// <returns>A human-readable, abbreviated (but not secure) identifier the user MAY recognize as his own.</returns> + public Identifier FriendlyIdentifierForDisplay { + get { + if (this.friendlyIdentifierForDisplay == null) { + XriIdentifier xri = this.ClaimedIdentifier as XriIdentifier; + UriIdentifier uri = this.ClaimedIdentifier as UriIdentifier; + if (xri != null) { + if (this.UserSuppliedIdentifier == null || String.Equals(this.UserSuppliedIdentifier, this.ClaimedIdentifier, StringComparison.OrdinalIgnoreCase)) { + this.friendlyIdentifierForDisplay = this.ClaimedIdentifier; + } else { + this.friendlyIdentifierForDisplay = this.UserSuppliedIdentifier; + } + } else if (uri != null) { + if (uri != this.Protocol.ClaimedIdentifierForOPIdentifier) { + string displayUri = uri.Uri.Host + uri.Uri.AbsolutePath; + displayUri = displayUri.TrimEnd('/'); + + // Multi-byte unicode characters get encoded by the Uri class for transit. + // Since discoveryResult is for display purposes, we want to reverse discoveryResult and display a readable + // representation of these foreign characters. + this.friendlyIdentifierForDisplay = Uri.UnescapeDataString(displayUri); + } + } else { + this.friendlyIdentifierForDisplay = this.ClaimedIdentifier; + } + } + + return this.friendlyIdentifierForDisplay; + } + } + + /// <summary> + /// Gets the provider endpoint. + /// </summary> + public Uri ProviderEndpoint { get; private set; } + + /// <summary> + /// Gets the @priority given in the XRDS document for this specific OP endpoint. + /// </summary> + public int? ProviderEndpointPriority { get; private set; } + + /// <summary> + /// Gets the @priority given in the XRDS document for this service + /// (which may consist of several endpoints). + /// </summary> + public int? ServicePriority { get; private set; } + + /// <summary> + /// Gets the collection of service type URIs found in the XRDS document describing this Provider. + /// </summary> + /// <value>Should never be null, but may be empty.</value> + public ReadOnlyCollection<string> Capabilities { get; private set; } + + #region IProviderEndpoint Members + + /// <summary> + /// Gets the URL that the OpenID Provider receives authentication requests at. + /// </summary> + /// <value>This value MUST be an absolute HTTP or HTTPS URL.</value> + Uri IProviderEndpoint.Uri { + get { return this.ProviderEndpoint; } + } + + #endregion + + /// <summary> + /// Gets an XRDS sorting routine that uses the XRDS Service/@Priority + /// attribute to determine order. + /// </summary> + /// <remarks> + /// Endpoints lacking any priority value are sorted to the end of the list. + /// </remarks> + internal static Comparison<IdentifierDiscoveryResult> EndpointOrder { + get { + // Sort first by service type (OpenID 2.0, 1.1, 1.0), + // then by Service/@priority, then by Service/Uri/@priority + return (se1, se2) => { + int result = GetEndpointPrecedenceOrderByServiceType(se1).CompareTo(GetEndpointPrecedenceOrderByServiceType(se2)); + if (result != 0) { + return result; + } + if (se1.ServicePriority.HasValue && se2.ServicePriority.HasValue) { + result = se1.ServicePriority.Value.CompareTo(se2.ServicePriority.Value); + if (result != 0) { + return result; + } + if (se1.ProviderEndpointPriority.HasValue && se2.ProviderEndpointPriority.HasValue) { + return se1.ProviderEndpointPriority.Value.CompareTo(se2.ProviderEndpointPriority.Value); + } else if (se1.ProviderEndpointPriority.HasValue) { + return -1; + } else if (se2.ProviderEndpointPriority.HasValue) { + return 1; + } else { + return 0; + } + } else { + if (se1.ServicePriority.HasValue) { + return -1; + } else if (se2.ServicePriority.HasValue) { + return 1; + } else { + // neither service defines a priority, so base ordering by uri priority. + if (se1.ProviderEndpointPriority.HasValue && se2.ProviderEndpointPriority.HasValue) { + return se1.ProviderEndpointPriority.Value.CompareTo(se2.ProviderEndpointPriority.Value); + } else if (se1.ProviderEndpointPriority.HasValue) { + return -1; + } else if (se2.ProviderEndpointPriority.HasValue) { + return 1; + } else { + return 0; + } + } + } + }; + } + } + + /// <summary> + /// Gets the protocol used by the OpenID Provider. + /// </summary> + internal Protocol Protocol { + get { + if (this.protocol == null) { + this.protocol = Protocol.Lookup(this.Version); + } + + return this.protocol; + } + } + + /// <summary> + /// Implements the operator ==. + /// </summary> + /// <param name="se1">The first service endpoint.</param> + /// <param name="se2">The second service endpoint.</param> + /// <returns>The result of the operator.</returns> + public static bool operator ==(IdentifierDiscoveryResult se1, IdentifierDiscoveryResult se2) { + return se1.EqualsNullSafe(se2); + } + + /// <summary> + /// Implements the operator !=. + /// </summary> + /// <param name="se1">The first service endpoint.</param> + /// <param name="se2">The second service endpoint.</param> + /// <returns>The result of the operator.</returns> + public static bool operator !=(IdentifierDiscoveryResult se1, IdentifierDiscoveryResult se2) { + return !(se1 == se2); + } + + /// <summary> + /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>. + /// </summary> + /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param> + /// <returns> + /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false. + /// </returns> + /// <exception cref="T:System.NullReferenceException"> + /// The <paramref name="obj"/> parameter is null. + /// </exception> + public override bool Equals(object obj) { + var other = obj as IdentifierDiscoveryResult; + if (other == null) { + return false; + } + + // We specifically do not check our ProviderSupportedServiceTypeUris array + // or the priority field + // as that is not persisted in our tokens, and it is not part of the + // important assertion validation that is part of the spec. + return + this.ClaimedIdentifier == other.ClaimedIdentifier && + this.ProviderEndpoint == other.ProviderEndpoint && + this.ProviderLocalIdentifier == other.ProviderLocalIdentifier && + this.Protocol.EqualsPractically(other.Protocol); + } + + /// <summary> + /// Serves as a hash function for a particular type. + /// </summary> + /// <returns> + /// A hash code for the current <see cref="T:System.Object"/>. + /// </returns> + public override int GetHashCode() { + return this.ClaimedIdentifier.GetHashCode(); + } + + /// <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() { + StringBuilder builder = new StringBuilder(); + builder.AppendLine("ClaimedIdentifier: " + this.ClaimedIdentifier); + builder.AppendLine("ProviderLocalIdentifier: " + this.ProviderLocalIdentifier); + builder.AppendLine("ProviderEndpoint: " + this.ProviderEndpoint); + builder.AppendLine("OpenID version: " + this.Version); + builder.AppendLine("Service Type URIs:"); + foreach (string serviceTypeUri in this.Capabilities) { + builder.Append("\t"); + builder.AppendLine(serviceTypeUri); + } + builder.Length -= Environment.NewLine.Length; // trim last newline + return builder.ToString(); + } + + /// <summary> + /// Checks whether the OpenId Identifier claims support for a given extension. + /// </summary> + /// <typeparam name="T">The extension whose support is being queried.</typeparam> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "No parameter at all.")] + public bool IsExtensionSupported<T>() where T : IOpenIdMessageExtension, new() { + T extension = new T(); + return this.IsExtensionSupported(extension); + } + + /// <summary> + /// Checks whether the OpenId Identifier claims support for a given extension. + /// </summary> + /// <param name="extensionType">The extension whose support is being queried.</param> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + public bool IsExtensionSupported(Type extensionType) { + var extension = (IOpenIdMessageExtension)Activator.CreateInstance(extensionType); + return this.IsExtensionSupported(extension); + } + + /// <summary> + /// Determines whether a given extension is supported by this endpoint. + /// </summary> + /// <param name="extension">An instance of the extension to check support for.</param> + /// <returns> + /// <c>true</c> if the extension is supported by this endpoint; otherwise, <c>false</c>. + /// </returns> + public bool IsExtensionSupported(IOpenIdMessageExtension extension) { + Contract.Requires<ArgumentNullException>(extension != null); + + // Consider the primary case. + if (this.IsTypeUriPresent(extension.TypeUri)) { + return true; + } + + // Consider the secondary cases. + if (extension.AdditionalSupportedTypeUris != null) { + if (extension.AdditionalSupportedTypeUris.Any(typeUri => this.IsTypeUriPresent(typeUri))) { + return true; + } + } + + return false; + } + + /// <summary> + /// Creates a <see cref="IdentifierDiscoveryResult"/> instance to represent some OP Identifier. + /// </summary> + /// <param name="providerIdentifier">The provider identifier (actually the user-supplied identifier).</param> + /// <param name="providerEndpoint">The provider endpoint.</param> + /// <param name="servicePriority">The service priority.</param> + /// <param name="uriPriority">The URI priority.</param> + /// <returns>The created <see cref="IdentifierDiscoveryResult"/> instance</returns> + internal static IdentifierDiscoveryResult CreateForProviderIdentifier(Identifier providerIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) { + Contract.Requires<ArgumentNullException>(providerEndpoint != null); + + Protocol protocol = Protocol.Detect(providerEndpoint.Capabilities); + + return new IdentifierDiscoveryResult( + providerEndpoint, + protocol.ClaimedIdentifierForOPIdentifier, + providerIdentifier, + protocol.ClaimedIdentifierForOPIdentifier, + servicePriority, + uriPriority); + } + + /// <summary> + /// Creates a <see cref="IdentifierDiscoveryResult"/> instance to represent some Claimed Identifier. + /// </summary> + /// <param name="claimedIdentifier">The claimed identifier.</param> + /// <param name="providerLocalIdentifier">The provider local identifier.</param> + /// <param name="providerEndpoint">The provider endpoint.</param> + /// <param name="servicePriority">The service priority.</param> + /// <param name="uriPriority">The URI priority.</param> + /// <returns>The created <see cref="IdentifierDiscoveryResult"/> instance</returns> + internal static IdentifierDiscoveryResult CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier providerLocalIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) { + return CreateForClaimedIdentifier(claimedIdentifier, null, providerLocalIdentifier, providerEndpoint, servicePriority, uriPriority); + } + + /// <summary> + /// Creates a <see cref="IdentifierDiscoveryResult"/> instance to represent some Claimed Identifier. + /// </summary> + /// <param name="claimedIdentifier">The claimed identifier.</param> + /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> + /// <param name="providerLocalIdentifier">The provider local identifier.</param> + /// <param name="providerEndpoint">The provider endpoint.</param> + /// <param name="servicePriority">The service priority.</param> + /// <param name="uriPriority">The URI priority.</param> + /// <returns>The created <see cref="IdentifierDiscoveryResult"/> instance</returns> + internal static IdentifierDiscoveryResult CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) { + return new IdentifierDiscoveryResult(providerEndpoint, claimedIdentifier, userSuppliedIdentifier, providerLocalIdentifier, servicePriority, uriPriority); + } + + /// <summary> + /// Determines whether a given type URI is present on the specified provider endpoint. + /// </summary> + /// <param name="typeUri">The type URI.</param> + /// <returns> + /// <c>true</c> if the type URI is present on the specified provider endpoint; otherwise, <c>false</c>. + /// </returns> + internal bool IsTypeUriPresent(string typeUri) { + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri)); + return this.Capabilities.Contains(typeUri); + } + + /// <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; + } + +#if CONTRACTS_FULL + /// <summary> + /// Verifies conditions that should be true for any valid state of this object. + /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")] + [ContractInvariantMethod] + private void ObjectInvariant() { + Contract.Invariant(this.ProviderEndpoint != null); + Contract.Invariant(this.ClaimedIdentifier != null); + Contract.Invariant(this.UserSuppliedIdentifier != null); + Contract.Invariant(this.ProviderLocalIdentifier != null); + Contract.Invariant(this.Capabilities != null); + Contract.Invariant(this.Version != null); + Contract.Invariant(this.Protocol != null); + } +#endif + } +} diff --git a/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs b/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs index 4845c17..04eb23c 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs @@ -15,7 +15,6 @@ namespace DotNetOpenAuth.OpenId { using System.Web.UI; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.ChannelElements; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Extensions; using DotNetOpenAuth.OpenId.Messages; using DotNetOpenAuth.OpenId.Provider; @@ -31,78 +30,6 @@ namespace DotNetOpenAuth.OpenId { internal const string CustomParameterPrefix = "dnoa."; /// <summary> - /// Checks whether the OpenId Identifier claims support for a given extension. - /// </summary> - /// <typeparam name="T">The extension whose support is being queried.</typeparam> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <returns> - /// True if support for the extension is advertised. False otherwise. - /// </returns> - /// <remarks> - /// Note that a true or false return value is no guarantee of a Provider's - /// support for or lack of support for an extension. The return value is - /// determined by how the authenticating user filled out his/her XRDS document only. - /// The only way to be sure of support for a given extension is to include - /// the extension in the request and see if a response comes back for that extension. - /// </remarks> - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "No parameter at all.")] - public static bool IsExtensionSupported<T>(this IProviderEndpoint providerEndpoint) where T : IOpenIdMessageExtension, new() { - Contract.Requires(providerEndpoint != null); - T extension = new T(); - return IsExtensionSupported(providerEndpoint, extension); - } - - /// <summary> - /// Checks whether the OpenId Identifier claims support for a given extension. - /// </summary> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <param name="extensionType">The extension whose support is being queried.</param> - /// <returns> - /// True if support for the extension is advertised. False otherwise. - /// </returns> - /// <remarks> - /// Note that a true or false return value is no guarantee of a Provider's - /// support for or lack of support for an extension. The return value is - /// determined by how the authenticating user filled out his/her XRDS document only. - /// The only way to be sure of support for a given extension is to include - /// the extension in the request and see if a response comes back for that extension. - /// </remarks> - public static bool IsExtensionSupported(this IProviderEndpoint providerEndpoint, Type extensionType) { - Contract.Requires(providerEndpoint != null); - Contract.Requires(extensionType != null); - Contract.Requires<ArgumentException>(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType)); - var extension = (IOpenIdMessageExtension)Activator.CreateInstance(extensionType); - return IsExtensionSupported(providerEndpoint, extension); - } - - /// <summary> - /// Determines whether a given extension is supported by this endpoint. - /// </summary> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <param name="extension">An instance of the extension to check support for.</param> - /// <returns> - /// <c>true</c> if the extension is supported by this endpoint; otherwise, <c>false</c>. - /// </returns> - public static bool IsExtensionSupported(this IProviderEndpoint providerEndpoint, IOpenIdMessageExtension extension) { - Contract.Requires(providerEndpoint != null); - Contract.Requires<ArgumentNullException>(extension != null); - - // Consider the primary case. - if (providerEndpoint.IsTypeUriPresent(extension.TypeUri)) { - return true; - } - - // Consider the secondary cases. - if (extension.AdditionalSupportedTypeUris != null) { - if (extension.AdditionalSupportedTypeUris.Any(typeUri => providerEndpoint.IsTypeUriPresent(typeUri))) { - return true; - } - } - - return false; - } - - /// <summary> /// Gets the OpenID protocol instance for the version in a message. /// </summary> /// <param name="message">The message.</param> @@ -229,60 +156,5 @@ namespace DotNetOpenAuth.OpenId { ErrorUtilities.VerifyOperation(aggregator != null, OpenIdStrings.UnsupportedChannelConfiguration); return aggregator.Factories; } - - /// <summary> - /// Gets the OpenID protocol used by the Provider. - /// </summary> - /// <param name="providerDescription">The provider description.</param> - /// <returns>The OpenID protocol.</returns> - internal static Protocol GetProtocol(this IProviderEndpoint providerDescription) { - return Protocol.Lookup(providerDescription.Version); - } - - /// <summary> - /// Gets the value for the <see cref="IAuthenticationResponse.FriendlyIdentifierForDisplay"/> property. - /// </summary> - /// <param name="discoveryResult">The discovery result.</param> - /// <returns>A human-readable, abbreviated (but not secure) identifier the user MAY recognize as his own.</returns> - internal static string GetFriendlyIdentifierForDisplay(this IIdentifierDiscoveryResult discoveryResult) { - Contract.Requires(discoveryResult != null); - XriIdentifier xri = discoveryResult.ClaimedIdentifier as XriIdentifier; - UriIdentifier uri = discoveryResult.ClaimedIdentifier as UriIdentifier; - if (xri != null) { - if (discoveryResult.UserSuppliedIdentifier == null || String.Equals(discoveryResult.UserSuppliedIdentifier, discoveryResult.ClaimedIdentifier, StringComparison.OrdinalIgnoreCase)) { - return discoveryResult.ClaimedIdentifier; - } else { - return discoveryResult.UserSuppliedIdentifier; - } - } else if (uri != null) { - if (uri != discoveryResult.ProviderEndpoint.GetProtocol().ClaimedIdentifierForOPIdentifier) { - string displayUri = uri.Uri.Host + uri.Uri.AbsolutePath; - displayUri = displayUri.TrimEnd('/'); - - // Multi-byte unicode characters get encoded by the Uri class for transit. - // Since discoveryResult is for display purposes, we want to reverse discoveryResult and display a readable - // representation of these foreign characters. - return Uri.UnescapeDataString(displayUri); - } - } else { - return discoveryResult.ClaimedIdentifier; - } - - return null; - } - - /// <summary> - /// Determines whether a given type URI is present on the specified provider endpoint. - /// </summary> - /// <param name="providerEndpoint">The provider endpoint.</param> - /// <param name="typeUri">The type URI.</param> - /// <returns> - /// <c>true</c> if the type URI is present on the specified provider endpoint; otherwise, <c>false</c>. - /// </returns> - internal static bool IsTypeUriPresent(this IProviderEndpoint providerEndpoint, string typeUri) { - Contract.Requires(providerEndpoint != null); - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri)); - return providerEndpoint.Capabilities.Contains(typeUri); - } } } diff --git a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs index e84035a..d72b55d 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs @@ -10,7 +10,6 @@ namespace DotNetOpenAuth.OpenId { using System.Diagnostics.Contracts; using System.Linq; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Xrds; @@ -56,8 +55,8 @@ namespace DotNetOpenAuth.OpenId { /// <returns> /// A sequence of OpenID Providers that can assert ownership of the <paramref name="claimedIdentifier"/>. /// </returns> - internal static IEnumerable<IIdentifierDiscoveryResult> CreateServiceEndpoints(this XrdsDocument xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { - var endpoints = new List<IIdentifierDiscoveryResult>(); + internal static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this XrdsDocument xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { + var endpoints = new List<IdentifierDiscoveryResult>(); endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); // If any OP Identifier service elements were found, we must not proceed @@ -77,11 +76,11 @@ namespace DotNetOpenAuth.OpenId { /// <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<IIdentifierDiscoveryResult> CreateServiceEndpoints(this XrdsDocument xrds, XriIdentifier userSuppliedIdentifier) { + internal static IEnumerable<IdentifierDiscoveryResult> CreateServiceEndpoints(this XrdsDocument xrds, XriIdentifier userSuppliedIdentifier) { Contract.Requires<ArgumentNullException>(xrds != null); Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null); - Contract.Ensures(Contract.Result<IEnumerable<IIdentifierDiscoveryResult>>() != null); - var endpoints = new List<IIdentifierDiscoveryResult>(); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); + var endpoints = new List<IdentifierDiscoveryResult>(); endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); // If any OP Identifier service elements were found, we must not proceed @@ -100,10 +99,10 @@ namespace DotNetOpenAuth.OpenId { /// <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<IIdentifierDiscoveryResult> GenerateOPIdentifierServiceEndpoints(this XrdsDocument xrds, Identifier opIdentifier) { + private static IEnumerable<IdentifierDiscoveryResult> GenerateOPIdentifierServiceEndpoints(this XrdsDocument xrds, Identifier opIdentifier) { Contract.Requires<ArgumentNullException>(xrds != null); Contract.Requires<ArgumentNullException>(opIdentifier != null); - Contract.Ensures(Contract.Result<IEnumerable<IIdentifierDiscoveryResult>>() != 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) @@ -121,7 +120,7 @@ namespace DotNetOpenAuth.OpenId { /// <returns> /// A sequence of the providers that can assert ownership of the given identifier. /// </returns> - private static IEnumerable<IIdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this XrdsDocument xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { + private static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this XrdsDocument xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) { return from service in xrds.FindClaimedIdentifierServices() from uri in service.UriElements where uri.Uri != null @@ -136,7 +135,7 @@ namespace DotNetOpenAuth.OpenId { /// <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<IIdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this XrdsDocument xrds, XriIdentifier userSuppliedIdentifier) { + private static IEnumerable<IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this XrdsDocument xrds, XriIdentifier userSuppliedIdentifier) { foreach (var service in xrds.FindClaimedIdentifierServices()) { foreach (var uri in service.UriElements) { // spec section 7.3.2.3 on Claimed Id -> CanonicalID substitution diff --git a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs index e4102ba..d24873b 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs @@ -19,7 +19,6 @@ namespace DotNetOpenAuth.OpenId.Provider { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OpenId.ChannelElements; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Messages; using RP = DotNetOpenAuth.OpenId.RelyingParty; @@ -398,7 +397,7 @@ namespace DotNetOpenAuth.OpenId.Provider { // do due diligence by performing our own discovery on the claimed identifier // and make sure that it is tied to this OP and OP local identifier. if (this.SecuritySettings.UnsolicitedAssertionVerification != ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel.NeverVerify) { - var serviceEndpoint = DotNetOpenAuth.OpenId.DiscoveryServices.IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, localIdentifier, new ProviderEndpointDescription(providerEndpoint, Protocol.Default.Version), null, null); + var serviceEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, localIdentifier, new ProviderEndpointDescription(providerEndpoint, Protocol.Default.Version), null, null); var discoveredEndpoints = this.RelyingParty.Discover(claimedIdentifier); if (!discoveredEndpoints.Contains(serviceEndpoint)) { Logger.OpenId.WarnFormat( diff --git a/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs b/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs index 1c618eb..2870fe5 100644 --- a/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs +++ b/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; using System.Collections.ObjectModel; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Linq; using DotNetOpenAuth.Messaging; @@ -20,8 +21,7 @@ namespace DotNetOpenAuth.OpenId { /// <remarks> /// This is an immutable type. /// </remarks> - [Serializable] - internal class ProviderEndpointDescription : IProviderEndpoint { + internal sealed class ProviderEndpointDescription : IProviderEndpoint { /// <summary> /// Initializes a new instance of the <see cref="ProviderEndpointDescription"/> class. /// </summary> @@ -33,7 +33,7 @@ namespace DotNetOpenAuth.OpenId { this.Uri = providerEndpoint; this.Version = openIdVersion; - this.Capabilities = new ReadOnlyCollection<string>(new List<string>()); + this.Capabilities = new ReadOnlyCollection<string>(EmptyList<string>.Instance); } /// <summary> @@ -76,6 +76,60 @@ namespace DotNetOpenAuth.OpenId { /// <summary> /// Gets the collection of service type URIs found in the XRDS document describing this Provider. /// </summary> - public ReadOnlyCollection<string> Capabilities { get; private set; } + internal ReadOnlyCollection<string> Capabilities { get; private set; } + + #region IProviderEndpoint Members + + /// <summary> + /// Checks whether the OpenId Identifier claims support for a given extension. + /// </summary> + /// <typeparam name="T">The extension whose support is being queried.</typeparam> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + bool IProviderEndpoint.IsExtensionSupported<T>() { + throw new NotImplementedException(); + } + + /// <summary> + /// Checks whether the OpenId Identifier claims support for a given extension. + /// </summary> + /// <param name="extensionType">The extension whose support is being queried.</param> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + bool IProviderEndpoint.IsExtensionSupported(Type extensionType) { + throw new NotImplementedException(); + } + + #endregion + +#if CONTRACTS_FULL + /// <summary> + /// Verifies conditions that should be true for any valid state of this object. + /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")] + [ContractInvariantMethod] + private void ObjectInvariant() { + Contract.Invariant(this.Uri != null); + Contract.Invariant(this.Version != null); + Contract.Invariant(this.Capabilities != null); + } +#endif } } diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs index 467bed1..7f0a360 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs @@ -14,7 +14,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.ChannelElements; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Messages; /// <summary> @@ -66,7 +65,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <param name="realm">The realm, or root URL, of the host web site.</param> /// <param name="returnToUrl">The base return_to URL that the Provider should return the user to to complete authentication. This should not include callback parameters as these should be added using the <see cref="AddCallbackArguments(string, string)"/> method.</param> /// <param name="relyingParty">The relying party that created this instance.</param> - private AuthenticationRequest(IIdentifierDiscoveryResult discoveryResult, Realm realm, Uri returnToUrl, OpenIdRelyingParty relyingParty) { + private AuthenticationRequest(IdentifierDiscoveryResult discoveryResult, Realm realm, Uri returnToUrl, OpenIdRelyingParty relyingParty) { Contract.Requires<ArgumentNullException>(discoveryResult != null); Contract.Requires<ArgumentNullException>(realm != null); Contract.Requires<ArgumentNullException>(returnToUrl != null); @@ -140,7 +139,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// determine and send the ClaimedIdentifier after authentication. /// </summary> public bool IsDirectedIdentity { - get { return this.DiscoveryResult.ClaimedIdentifier == this.DiscoveryResult.ProviderEndpoint.GetProtocol().ClaimedIdentifierForOPIdentifier; } + get { return this.DiscoveryResult.ClaimedIdentifier == this.DiscoveryResult.Protocol.ClaimedIdentifierForOPIdentifier; } } /// <summary> @@ -159,9 +158,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// location. /// </summary> public IProviderEndpoint Provider { - get { return this.DiscoveryResult.ProviderEndpoint; } + get { return this.DiscoveryResult; } } + /// <summary> + /// Gets the discovery result leading to the formulation of this request. + /// </summary> + /// <value>The discovery result.</value> + public IdentifierDiscoveryResult DiscoveryResult { get; private set; } + #endregion /// <summary> @@ -187,12 +192,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { get { return this.extensions; } } - /// <summary> - /// Gets the endpoint that describes the particular OpenID Identifier and Provider that - /// will be used to create the authentication request. - /// </summary> - internal IIdentifierDiscoveryResult DiscoveryResult { get; private set; } - #region IAuthenticationRequest methods /// <summary> @@ -358,12 +357,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { ErrorUtilities.VerifyProtocol(realm.Contains(returnToUrl), OpenIdStrings.ReturnToNotUnderRealm, returnToUrl, realm); // Perform discovery right now (not deferred). - IEnumerable<IIdentifierDiscoveryResult> serviceEndpoints; + IEnumerable<IdentifierDiscoveryResult> serviceEndpoints; try { serviceEndpoints = relyingParty.Discover(userSuppliedIdentifier); } catch (ProtocolException ex) { Logger.Yadis.ErrorFormat("Error while performing discovery on: \"{0}\": {1}", userSuppliedIdentifier, ex); - serviceEndpoints = Enumerable.Empty<IIdentifierDiscoveryResult>(); + serviceEndpoints = Enumerable.Empty<IdentifierDiscoveryResult>(); } // Filter disallowed endpoints. @@ -381,7 +380,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <param name="returnTo">The return to.</param> /// <param name="rp">The relying party.</param> /// <returns>The instantiated <see cref="AuthenticationRequest"/>.</returns> - internal static AuthenticationRequest CreateForTest(IIdentifierDiscoveryResult discoveryResult, Realm realm, Uri returnTo, OpenIdRelyingParty rp) { + internal static AuthenticationRequest CreateForTest(IdentifierDiscoveryResult discoveryResult, Realm realm, Uri returnTo, OpenIdRelyingParty rp) { return new AuthenticationRequest(discoveryResult, realm, returnTo, rp); } @@ -402,7 +401,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// All data validation and cleansing steps must have ALREADY taken place /// before calling this method. /// </remarks> - private static IEnumerable<AuthenticationRequest> CreateInternal(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, IEnumerable<IIdentifierDiscoveryResult> serviceEndpoints, bool createNewAssociationsAsNeeded) { + private static IEnumerable<AuthenticationRequest> CreateInternal(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, IEnumerable<IdentifierDiscoveryResult> serviceEndpoints, bool createNewAssociationsAsNeeded) { // DO NOT USE CODE CONTRACTS IN THIS METHOD, since it uses yield return ErrorUtilities.VerifyArgumentNotNull(userSuppliedIdentifier, "userSuppliedIdentifier"); ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty"); @@ -414,12 +413,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { ErrorUtilities.VerifyOperation(!relyingParty.SecuritySettings.RequireAssociation || relyingParty.AssociationManager.HasAssociationStore, OpenIdStrings.AssociationStoreRequired); Logger.Yadis.InfoFormat("Performing discovery on user-supplied identifier: {0}", userSuppliedIdentifier); - IEnumerable<IIdentifierDiscoveryResult> endpoints = FilterAndSortEndpoints(serviceEndpoints, relyingParty); + IEnumerable<IdentifierDiscoveryResult> endpoints = FilterAndSortEndpoints(serviceEndpoints, relyingParty); // Maintain a list of endpoints that we could not form an association with. // We'll fallback to generating requests to these if the ones we CAN create // an association with run out. - var failedAssociationEndpoints = new List<IIdentifierDiscoveryResult>(0); + var failedAssociationEndpoints = new List<IdentifierDiscoveryResult>(0); foreach (var endpoint in endpoints) { Logger.OpenId.InfoFormat("Creating authentication request for user supplied Identifier: {0}", userSuppliedIdentifier); @@ -430,7 +429,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { // In some scenarios (like the AJAX control wanting ALL auth requests possible), // we don't want to create associations with every Provider. But we'll use // associations where they are already formed from previous authentications. - association = createNewAssociationsAsNeeded ? relyingParty.AssociationManager.GetOrCreateAssociation(endpoint.ProviderEndpoint) : relyingParty.AssociationManager.GetExistingAssociation(endpoint.ProviderEndpoint); + association = createNewAssociationsAsNeeded ? relyingParty.AssociationManager.GetOrCreateAssociation(endpoint) : relyingParty.AssociationManager.GetExistingAssociation(endpoint); if (association == null && createNewAssociationsAsNeeded) { Logger.OpenId.WarnFormat("Failed to create association with {0}. Skipping to next endpoint.", endpoint.ProviderEndpoint); @@ -473,7 +472,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <param name="endpoints">The endpoints.</param> /// <param name="relyingParty">The relying party.</param> /// <returns>A filtered and sorted list of endpoints; may be empty if the input was empty or the filter removed all endpoints.</returns> - private static List<IIdentifierDiscoveryResult> FilterAndSortEndpoints(IEnumerable<IIdentifierDiscoveryResult> endpoints, OpenIdRelyingParty relyingParty) { + private static List<IdentifierDiscoveryResult> FilterAndSortEndpoints(IEnumerable<IdentifierDiscoveryResult> endpoints, OpenIdRelyingParty relyingParty) { Contract.Requires<ArgumentNullException>(endpoints != null); Contract.Requires<ArgumentNullException>(relyingParty != null); @@ -482,9 +481,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { EndpointSelector hostingSiteFilter = relyingParty.EndpointFilter ?? (ep => true); bool anyFilteredOut = false; - var filteredEndpoints = new List<IIdentifierDiscoveryResult>(); + var filteredEndpoints = new List<IdentifierDiscoveryResult>(); foreach (var endpoint in endpoints) { - if (versionFilter((IXrdsProviderEndpoint)endpoint.ProviderEndpoint) && hostingSiteFilter((IXrdsProviderEndpoint)endpoint.ProviderEndpoint)) { + if (versionFilter(endpoint) && hostingSiteFilter(endpoint)) { filteredEndpoints.Add(endpoint); } else { anyFilteredOut = true; @@ -492,9 +491,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } // Sort endpoints so that the first one in the list is the most preferred one. - filteredEndpoints.OrderBy(ep => (IXrdsProviderEndpoint)ep.ProviderEndpoint, relyingParty.EndpointOrder); + filteredEndpoints.OrderBy(ep => ep, relyingParty.EndpointOrder); - var endpointList = new List<IIdentifierDiscoveryResult>(filteredEndpoints.Count); + var endpointList = new List<IdentifierDiscoveryResult>(filteredEndpoints.Count); foreach (var endpoint in filteredEndpoints) { endpointList.Add(endpoint); } @@ -524,12 +523,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { SignedResponseRequest request; if (!this.IsExtensionOnly) { - CheckIdRequest authRequest = new CheckIdRequest(this.DiscoveryResult.ProviderEndpoint.Version, this.DiscoveryResult.ProviderEndpoint.Uri, this.Mode); + CheckIdRequest authRequest = new CheckIdRequest(this.DiscoveryResult.Version, this.DiscoveryResult.ProviderEndpoint, this.Mode); authRequest.ClaimedIdentifier = this.DiscoveryResult.ClaimedIdentifier; authRequest.LocalIdentifier = this.DiscoveryResult.ProviderLocalIdentifier; request = authRequest; } else { - request = new SignedResponseRequest(this.DiscoveryResult.ProviderEndpoint.Version, this.DiscoveryResult.ProviderEndpoint.Uri, this.Mode); + request = new SignedResponseRequest(this.DiscoveryResult.Version, this.DiscoveryResult.ProviderEndpoint, this.Mode); } request.Realm = this.Realm; request.ReturnTo = this.ReturnToUrl; @@ -554,7 +553,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { Association association = null; switch (this.associationPreference) { case AssociationPreference.IfPossible: - association = this.RelyingParty.AssociationManager.GetOrCreateAssociation(this.DiscoveryResult.ProviderEndpoint); + association = this.RelyingParty.AssociationManager.GetOrCreateAssociation(this.DiscoveryResult); if (association == null) { // Avoid trying to create the association again if the redirecting response // is generated again. @@ -562,7 +561,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } break; case AssociationPreference.IfAlreadyEstablished: - association = this.RelyingParty.AssociationManager.GetExistingAssociation(this.DiscoveryResult.ProviderEndpoint); + association = this.RelyingParty.AssociationManager.GetExistingAssociation(this.DiscoveryResult); break; case AssociationPreference.Never: break; diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs index 3808c85..65db0bd 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs @@ -97,6 +97,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { IProviderEndpoint Provider { get; } /// <summary> + /// Gets the discovery result leading to the formulation of this request. + /// </summary> + /// <value>The discovery result.</value> + IdentifierDiscoveryResult DiscoveryResult { get; } + + /// <summary> /// Makes a dictionary of key/value pairs available when the authentication is completed. /// </summary> /// <param name="arguments">The arguments to add to the request's return_to URI. Values must not be null.</param> diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs index 41cc4e9..cd36cc7 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs @@ -32,11 +32,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } Realm IAuthenticationRequest.Realm { - get { throw new NotImplementedException(); } + get { + Contract.Ensures(Contract.Result<Realm>() != null); + throw new NotImplementedException(); + } } Identifier IAuthenticationRequest.ClaimedIdentifier { - get { throw new NotImplementedException(); } + get { + throw new NotImplementedException(); + } } bool IAuthenticationRequest.IsDirectedIdentity { @@ -54,7 +59,17 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } IProviderEndpoint IAuthenticationRequest.Provider { - get { throw new NotImplementedException(); } + get { + Contract.Ensures(Contract.Result<IProviderEndpoint>() != null); + throw new NotImplementedException(); + } + } + + IdentifierDiscoveryResult IAuthenticationRequest.DiscoveryResult { + get { + Contract.Ensures(Contract.Result<IdentifierDiscoveryResult>() != null); + throw new NotImplementedException(); + } } void IAuthenticationRequest.AddCallbackArguments(IDictionary<string, string> arguments) { diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs index 79b5055..5d8918d 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs @@ -37,10 +37,35 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { Uri Uri { get; } /// <summary> - /// Gets the collection of service type URIs found in the XRDS document describing this Provider. + /// Checks whether the OpenId Identifier claims support for a given extension. /// </summary> - /// <value>Should never be null, but may be empty.</value> - ReadOnlyCollection<string> Capabilities { get; } + /// <typeparam name="T">The extension whose support is being queried.</typeparam> + /// <returns>True if support for the extension is advertised. False otherwise.</returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "No parameter at all.")] + [Obsolete("Use IAuthenticationRequest.DiscoveryResult.IsExtensionSupported instead.")] + bool IsExtensionSupported<T>() where T : IOpenIdMessageExtension, new(); + + /// <summary> + /// Checks whether the OpenId Identifier claims support for a given extension. + /// </summary> + /// <param name="extensionType">The extension whose support is being queried.</param> + /// <returns>True if support for the extension is advertised. False otherwise.</returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + [Obsolete("Use IAuthenticationRequest.DiscoveryResult.IsExtensionSupported instead.")] + bool IsExtensionSupported(Type extensionType); } /// <summary> @@ -77,14 +102,41 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } /// <summary> - /// Gets the collection of service type URIs found in the XRDS document describing this Provider. + /// Checks whether the OpenId Identifier claims support for a given extension. /// </summary> - /// <value>Should never be null, but may be empty.</value> - ReadOnlyCollection<string> IProviderEndpoint.Capabilities { - get { - Contract.Ensures(Contract.Result<ReadOnlyCollection<string>>() != null); - throw new NotImplementedException(); - } + /// <typeparam name="T">The extension whose support is being queried.</typeparam> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + bool IProviderEndpoint.IsExtensionSupported<T>() { + throw new NotImplementedException(); + } + + /// <summary> + /// Checks whether the OpenId Identifier claims support for a given extension. + /// </summary> + /// <param name="extensionType">The extension whose support is being queried.</param> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + bool IProviderEndpoint.IsExtensionSupported(Type extensionType) { + Contract.Requires<ArgumentNullException>(extensionType != null); + Contract.Requires<ArgumentException>(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType)); + throw new NotImplementedException(); } #endregion diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs deleted file mode 100644 index 6dd25c6..0000000 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="IXrdsProviderEndpoint.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OpenId.RelyingParty { - using System; - using System.Diagnostics.CodeAnalysis; - using System.Diagnostics.Contracts; - - /// <summary> - /// An <see cref="IProviderEndpoint"/> interface with additional members for use - /// in sorting for most preferred endpoint. - /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Xrds is an acronym.")] - [ContractClass(typeof(IXrdsProviderEndpointContract))] - public interface IXrdsProviderEndpoint : IProviderEndpoint { - /// <summary> - /// Gets the priority associated with this service that may have been given - /// in the XRDS document. - /// </summary> - int? ServicePriority { get; } - - /// <summary> - /// Gets the priority associated with the service endpoint URL. - /// </summary> - /// <remarks> - /// When sorting by priority, this property should be considered second after - /// <see cref="ServicePriority"/>. - /// </remarks> - int? UriPriority { get; } - } -} diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs deleted file mode 100644 index c7f0cc1..0000000 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs +++ /dev/null @@ -1,50 +0,0 @@ -// <auto-generated /> - -namespace DotNetOpenAuth.OpenId.RelyingParty { - using System; - using System.Diagnostics.CodeAnalysis; - using System.Diagnostics.Contracts; - using System.Globalization; - using DotNetOpenAuth.OpenId.Messages; - using System.Collections.ObjectModel; - - [ContractClassFor(typeof(IXrdsProviderEndpoint))] - internal abstract class IXrdsProviderEndpointContract : IXrdsProviderEndpoint { - #region IXrdsProviderEndpoint Properties - - int? IXrdsProviderEndpoint.ServicePriority { - get { throw new System.NotImplementedException(); } - } - - int? IXrdsProviderEndpoint.UriPriority { - get { throw new System.NotImplementedException(); } - } - - #endregion - - #region IProviderEndpoint Properties - - Version IProviderEndpoint.Version { - get { - Contract.Ensures(Contract.Result<Version>() != null); - throw new System.NotImplementedException(); - } - } - - Uri IProviderEndpoint.Uri { - get { - Contract.Ensures(Contract.Result<Uri>() != null); - throw new System.NotImplementedException(); - } - } - - ReadOnlyCollection<string> IProviderEndpoint.Capabilities { - get { - Contract.Ensures(Contract.Result<ReadOnlyCollection<string>>() != null); - throw new NotImplementedException(); - } - } - - #endregion - } -} diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs index 947e607..8d6b14a 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs @@ -18,7 +18,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OpenId.ChannelElements; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Extensions; using DotNetOpenAuth.OpenId.Messages; @@ -31,7 +30,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <c>True</c> if the endpoint should be considered. /// <c>False</c> to remove it from the pool of acceptable providers. /// </returns> - public delegate bool EndpointSelector(IXrdsProviderEndpoint endpoint); + public delegate bool EndpointSelector(IProviderEndpoint endpoint); /// <summary> /// Provides the programmatic facilities to act as an OpenId consumer. @@ -62,7 +61,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Backing store for the <see cref="EndpointOrder"/> property. /// </summary> - private Comparison<IXrdsProviderEndpoint> endpointOrder = DefaultEndpointOrder; + private Comparison<IdentifierDiscoveryResult> endpointOrder = DefaultEndpointOrder; /// <summary> /// Backing field for the <see cref="Channel"/> property. @@ -125,7 +124,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// Endpoints lacking any priority value are sorted to the end of the list. /// </remarks> [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Comparison<IXrdsProviderEndpoint> DefaultEndpointOrder { + public static Comparison<IdentifierDiscoveryResult> DefaultEndpointOrder { get { return IdentifierDiscoveryResult.EndpointOrder; } } @@ -208,7 +207,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// can be set to the value of <see cref="DefaultEndpointOrder"/>. /// </remarks> [EditorBrowsable(EditorBrowsableState.Advanced)] - public Comparison<IXrdsProviderEndpoint> EndpointOrder { + public Comparison<IdentifierDiscoveryResult> EndpointOrder { get { return this.endpointOrder; } @@ -591,11 +590,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </summary> /// <param name="identifier">The identifier to discover services for.</param> /// <returns>A non-null sequence of services discovered for the identifier.</returns> - internal IEnumerable<IIdentifierDiscoveryResult> Discover(Identifier identifier) { + internal IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier) { Contract.Requires<ArgumentNullException>(identifier != null); - Contract.Ensures(Contract.Result<IEnumerable<IIdentifierDiscoveryResult>>() != null); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); - IEnumerable<IIdentifierDiscoveryResult> results = Enumerable.Empty<IIdentifierDiscoveryResult>(); + IEnumerable<IdentifierDiscoveryResult> results = Enumerable.Empty<IdentifierDiscoveryResult>(); foreach (var discoverer in this.DiscoveryServices) { bool abortDiscoveryChain; var discoveryResults = discoverer.Discover(identifier, this.WebRequestHandler, out abortDiscoveryChain).CacheGeneratedResults(); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs index 4cf2648..578d40d 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs @@ -793,7 +793,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { case PopupBehavior.Always: return true; case PopupBehavior.IfProviderSupported: - return request.Provider.IsExtensionSupported<UIRequest>(); + return request.DiscoveryResult.IsExtensionSupported<UIRequest>(); default: throw ErrorUtilities.ThrowInternal("Unexpected value for Popup property."); } @@ -920,7 +920,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { // Inform ourselves in return_to that we're in a popup. req.SetUntrustedCallbackArgument(UIPopupCallbackKey, "1"); - if (req.Provider.IsExtensionSupported<UIRequest>()) { + if (req.DiscoveryResult.IsExtensionSupported<UIRequest>()) { // Inform the OP that we'll be using a popup window consistent with the UI extension. req.AddExtension(new UIRequest()); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs index 1bc306c..8a62d68 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs @@ -26,7 +26,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Information about the OP endpoint that issued this assertion. /// </summary> - private readonly ProviderEndpointDescription provider; + private readonly IProviderEndpoint provider; /// <summary> /// Initializes a new instance of the <see cref="PositiveAnonymousResponse"/> class. diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs index 657768b..44f01bc 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs @@ -11,7 +11,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System.Linq; using System.Web; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.DiscoveryServices; using DotNetOpenAuth.OpenId.Messages; /// <summary> @@ -92,7 +91,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </para> /// </remarks> public override string FriendlyIdentifierForDisplay { - get { return this.Endpoint.GetFriendlyIdentifierForDisplay(); } + get { return this.Endpoint.FriendlyIdentifierForDisplay; } } /// <summary> @@ -113,7 +112,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// the claimed identifier to avoid a Provider asserting an Identifier /// for which it has no authority. /// </remarks> - internal IIdentifierDiscoveryResult Endpoint { get; private set; } + internal IdentifierDiscoveryResult Endpoint { get; private set; } /// <summary> /// Gets the positive assertion response message. diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs index 4ecef7c..00213d8 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs @@ -10,7 +10,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System.Collections.ObjectModel; using System.Linq; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.DiscoveryServices; /// <summary> /// Security settings that are applicable to relying parties. @@ -116,10 +115,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </summary> /// <param name="endpoints">The endpoints discovered on an Identifier.</param> /// <returns>A sequence of endpoints that satisfy all security requirements.</returns> - internal IEnumerable<IIdentifierDiscoveryResult> FilterEndpoints(IEnumerable<IIdentifierDiscoveryResult> endpoints) { + internal IEnumerable<IdentifierDiscoveryResult> FilterEndpoints(IEnumerable<IdentifierDiscoveryResult> endpoints) { return endpoints .Where(se => !this.RejectDelegatingIdentifiers || se.ClaimedIdentifier == se.ProviderLocalIdentifier) - .Where(se => !this.RequireDirectedIdentity || se.ClaimedIdentifier == se.ProviderEndpoint.GetProtocol().ClaimedIdentifierForOPIdentifier); + .Where(se => !this.RequireDirectedIdentity || se.ClaimedIdentifier == se.Protocol.ClaimedIdentifierForOPIdentifier); } } } diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs index 1b8ce75..678f69a 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/SimpleXrdsProviderEndpoint.cs @@ -15,7 +15,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// assertions (particularly unsolicited ones) are received from OP endpoints that /// are deemed permissible by the host RP. /// </summary> - internal class SimpleXrdsProviderEndpoint : IXrdsProviderEndpoint { + internal class SimpleXrdsProviderEndpoint : IProviderEndpoint { /// <summary> /// Initializes a new instance of the <see cref="SimpleXrdsProviderEndpoint"/> class. /// </summary> @@ -23,32 +23,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { internal SimpleXrdsProviderEndpoint(PositiveAssertionResponse positiveAssertion) { this.Uri = positiveAssertion.ProviderEndpoint; this.Version = positiveAssertion.Version; - this.Capabilities = new ReadOnlyCollection<string>(EmptyList<string>.Instance); } - #region IXrdsProviderEndpoint Properties - - /// <summary> - /// Gets the priority associated with this service that may have been given - /// in the XRDS document. - /// </summary> - public int? ServicePriority { - get { return null; } - } - - /// <summary> - /// Gets the priority associated with the service endpoint URL. - /// </summary> - /// <remarks> - /// When sorting by priority, this property should be considered second after - /// <see cref="ServicePriority"/>. - /// </remarks> - public int? UriPriority { - get { return null; } - } - - #endregion - #region IProviderEndpoint Members /// <summary> @@ -62,10 +38,40 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { public Uri Uri { get; private set; } /// <summary> - /// Gets the collection of service type URIs found in the XRDS document describing this Provider. + /// Checks whether the OpenId Identifier claims support for a given extension. /// </summary> - /// <value>Should never be null, but may be empty.</value> - public ReadOnlyCollection<string> Capabilities { get; private set; } + /// <typeparam name="T">The extension whose support is being queried.</typeparam> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + bool IProviderEndpoint.IsExtensionSupported<T>() { + throw new NotImplementedException(); + } + + /// <summary> + /// Checks whether the OpenId Identifier claims support for a given extension. + /// </summary> + /// <param name="extensionType">The extension whose support is being queried.</param> + /// <returns> + /// True if support for the extension is advertised. False otherwise. + /// </returns> + /// <remarks> + /// Note that a true or false return value is no guarantee of a Provider's + /// support for or lack of support for an extension. The return value is + /// determined by how the authenticating user filled out his/her XRDS document only. + /// The only way to be sure of support for a given extension is to include + /// the extension in the request and see if a response comes back for that extension. + /// </remarks> + bool IProviderEndpoint.IsExtensionSupported(Type extensionType) { + throw new NotImplementedException(); + } #endregion } diff --git a/src/DotNetOpenAuth/OpenId/DiscoveryServices/UriDiscoveryService.cs b/src/DotNetOpenAuth/OpenId/UriDiscoveryService.cs index 30b75a6..14aff34 100644 --- a/src/DotNetOpenAuth/OpenId/DiscoveryServices/UriDiscoveryService.cs +++ b/src/DotNetOpenAuth/OpenId/UriDiscoveryService.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.OpenId.DiscoveryServices { +namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; using System.Linq; @@ -38,14 +38,14 @@ namespace DotNetOpenAuth.OpenId.DiscoveryServices { /// <returns> /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. /// </returns> - public IEnumerable<IIdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { + public IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { abortDiscoveryChain = false; var uriIdentifier = identifier as UriIdentifier; if (uriIdentifier == null) { - return Enumerable.Empty<IIdentifierDiscoveryResult>(); + return Enumerable.Empty<IdentifierDiscoveryResult>(); } - var endpoints = new List<IIdentifierDiscoveryResult>(); + var endpoints = new List<IdentifierDiscoveryResult>(); // Attempt YADIS discovery DiscoveryResult yadisResult = Yadis.Discover(requestHandler, uriIdentifier, identifier.IsDiscoverySecureEndToEnd); @@ -57,7 +57,7 @@ namespace DotNetOpenAuth.OpenId.DiscoveryServices { // Filter out insecure endpoints if high security is required. if (uriIdentifier.IsDiscoverySecureEndToEnd) { - xrdsEndpoints = xrdsEndpoints.Where(se => se.ProviderEndpoint.Uri.IsTransportSecure()); + xrdsEndpoints = xrdsEndpoints.Where(se => se.ProviderEndpoint.IsTransportSecure()); } endpoints.AddRange(xrdsEndpoints); } catch (XmlException ex) { @@ -67,11 +67,11 @@ namespace DotNetOpenAuth.OpenId.DiscoveryServices { // Failing YADIS discovery of an XRDS document, we try HTML discovery. if (endpoints.Count == 0) { - var htmlEndpoints = new List<IIdentifierDiscoveryResult>(DiscoverFromHtml(yadisResult.NormalizedUri, uriIdentifier, yadisResult.ResponseText)); + var htmlEndpoints = new List<IdentifierDiscoveryResult>(DiscoverFromHtml(yadisResult.NormalizedUri, uriIdentifier, yadisResult.ResponseText)); if (htmlEndpoints.Any()) { Logger.Yadis.DebugFormat("Total services discovered in HTML: {0}", htmlEndpoints.Count); Logger.Yadis.Debug(htmlEndpoints.ToStringDeferred(true)); - endpoints.AddRange(htmlEndpoints.Where(ep => !uriIdentifier.IsDiscoverySecureEndToEnd || ep.ProviderEndpoint.Uri.IsTransportSecure())); + endpoints.AddRange(htmlEndpoints.Where(ep => !uriIdentifier.IsDiscoverySecureEndToEnd || ep.ProviderEndpoint.IsTransportSecure())); if (endpoints.Count == 0) { Logger.Yadis.Info("No HTML discovered endpoints met the security requirements."); } @@ -98,7 +98,7 @@ namespace DotNetOpenAuth.OpenId.DiscoveryServices { /// <returns> /// A sequence of any discovered ServiceEndpoints. /// </returns> - private static IEnumerable<IIdentifierDiscoveryResult> DiscoverFromHtml(Uri claimedIdentifier, UriIdentifier userSuppliedIdentifier, string html) { + 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, diff --git a/src/DotNetOpenAuth/OpenId/DiscoveryServices/XriDiscoveryProxyService.cs b/src/DotNetOpenAuth/OpenId/XriDiscoveryProxyService.cs index 7f3a9db..e504730 100644 --- a/src/DotNetOpenAuth/OpenId/DiscoveryServices/XriDiscoveryProxyService.cs +++ b/src/DotNetOpenAuth/OpenId/XriDiscoveryProxyService.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.OpenId.DiscoveryServices { +namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -51,11 +51,11 @@ namespace DotNetOpenAuth.OpenId.DiscoveryServices { /// <returns> /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. /// </returns> - public IEnumerable<IIdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { + public IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { abortDiscoveryChain = false; var xriIdentifier = identifier as XriIdentifier; if (xriIdentifier == null) { - return Enumerable.Empty<IIdentifierDiscoveryResult>(); + return Enumerable.Empty<IdentifierDiscoveryResult>(); } return DownloadXrds(xriIdentifier, requestHandler).CreateServiceEndpoints(xriIdentifier); |