diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-08-30 21:53:43 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-08-30 21:53:43 -0700 |
commit | 029b1923f396e5aed9449c812b55b752edbb968b (patch) | |
tree | 7e4e7dcfa3af2cc548059787f114e859a6e80d89 | |
parent | 3e359429a671c1725f88f12c705c1e88ad9ff9c7 (diff) | |
download | DotNetOpenAuth-029b1923f396e5aed9449c812b55b752edbb968b.zip DotNetOpenAuth-029b1923f396e5aed9449c812b55b752edbb968b.tar.gz DotNetOpenAuth-029b1923f396e5aed9449c812b55b752edbb968b.tar.bz2 |
Added tests for unsolicited assertion sending and receiving, including against the RP's whitelist.
-rw-r--r-- | src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj | 1 | ||||
-rw-r--r-- | src/DotNetOpenAuth.Test/Mocks/MockRealm.cs | 42 | ||||
-rw-r--r-- | src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs | 22 | ||||
-rw-r--r-- | src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs | 13 | ||||
-rw-r--r-- | src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs | 41 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/Identifier.cs | 10 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/Realm.cs | 4 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/UriIdentifier.cs | 5 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/XriIdentifier.cs | 5 |
9 files changed, 141 insertions, 2 deletions
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index 231d92d..b531c8a 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -148,6 +148,7 @@ <Compile Include="Mocks\MockHttpRequest.cs" /> <Compile Include="Mocks\MockIdentifier.cs" /> <Compile Include="Mocks\MockOpenIdExtension.cs" /> + <Compile Include="Mocks\MockRealm.cs" /> <Compile Include="Mocks\MockTransformationBindingElement.cs" /> <Compile Include="Mocks\MockReplayProtectionBindingElement.cs" /> <Compile Include="Mocks\TestBaseMessage.cs" /> diff --git a/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs new file mode 100644 index 0000000..4e29bba --- /dev/null +++ b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------- +// <copyright file="MockRealm.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.Mocks { + using System.Collections.Generic; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; + + internal class MockRealm : Realm { + private RelyingPartyEndpointDescription[] relyingPartyDescriptions; + + /// <summary> + /// Initializes a new instance of the <see cref="MockRealm"/> class. + /// </summary> + /// <param name="wrappedRealm">The wrapped realm.</param> + /// <param name="relyingPartyDescriptions">The relying party descriptions.</param> + internal MockRealm(Realm wrappedRealm, params RelyingPartyEndpointDescription[] relyingPartyDescriptions) + : base(wrappedRealm) { + ErrorUtilities.VerifyArgumentNotNull(relyingPartyDescriptions, "relyingPartyDescriptions"); + + this.relyingPartyDescriptions = relyingPartyDescriptions; + } + + /// <summary> + /// Searches for an XRDS document at the realm URL, and if found, searches + /// for a description of a relying party endpoints (OpenId login pages). + /// </summary> + /// <param name="requestHandler">The mechanism to use for sending HTTP requests.</param> + /// <param name="allowRedirects">Whether redirects may be followed when discovering the Realm. + /// This may be true when creating an unsolicited assertion, but must be + /// false when performing return URL verification per 2.0 spec section 9.2.1.</param> + /// <returns> + /// The details of the endpoints if found, otherwise null. + /// </returns> + internal override IEnumerable<RelyingPartyEndpointDescription> Discover(IDirectWebRequestHandler requestHandler, bool allowRedirects) { + return this.relyingPartyDescriptions; + } + } +} diff --git a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs index d825f4b..807beae 100644 --- a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs @@ -58,6 +58,28 @@ namespace DotNetOpenAuth.Test.OpenId { this.ParameterizedAuthenticationTest(false, false, false); } + /// <summary> + /// Verifies that unsolicited assertions can be sent and received. + /// </summary> + [TestMethod] + public void UnsolicitedAssertion() { + var coordinator = new OpenIdCoordinator( + rp => { + // register with RP so that id discovery passes + rp.Channel.WebRequestHandler = this.MockResponder.MockWebRequestHandler; + + // Receive the unsolicited assertion + var response = rp.GetResponse(); + Assert.AreEqual(AuthenticationStatus.Authenticated, response.Status); + }, + op => { + Identifier id = GetMockIdentifier(ProtocolVersion.V20); + op.SendUnsolicitedAssertion(OPUri, GetMockRealm(false), id, id); + AutoProvider(op); + }); + coordinator.Run(); + } + private void ParameterizedAuthenticationTest(bool sharedAssociation, bool positive, bool tamper) { foreach (Protocol protocol in Protocol.AllPracticalVersions) { foreach (bool statelessRP in new[] { false, true }) { diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs index dddae27..6099b86 100644 --- a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs +++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs @@ -71,6 +71,14 @@ namespace DotNetOpenAuth.Test.OpenId { this.MockResponder = MockHttpRequest.CreateUntrustedMockHttpHandler(); this.RequestHandler = this.MockResponder.MockWebRequestHandler; this.AutoProviderScenario = Scenarios.AutoApproval; + Identifier.EqualityOnStrings = true; + } + + [TestCleanup] + public override void Cleanup() { + base.Cleanup(); + + Identifier.EqualityOnStrings = false; } /// <summary> @@ -162,6 +170,11 @@ namespace DotNetOpenAuth.Test.OpenId { } } + protected Realm GetMockRealm(bool useSsl) { + var rpDescription = new RelyingPartyEndpointDescription(useSsl ? RPUriSsl : RPUri, new string[] { Protocol.V20.RPReturnToTypeURI }); + return new MockRealm(useSsl ? RPRealmUriSsl : RPRealmUri, rpDescription); + } + protected Identifier GetMockIdentifier(ProtocolVersion providerVersion) { return this.GetMockIdentifier(providerVersion, false); } diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs index 68bbff3..f6a57e7 100644 --- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs @@ -63,6 +63,21 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { Assert.AreEqual(1, requests.Count()); } + [TestMethod] + public void CreateRequestsWithEndpointFilter() { + var rp = this.CreateRelyingParty(); + StoreAssociation(rp, OPUri, HmacShaAssociation.Create("somehandle", new byte[20], TimeSpan.FromDays(1))); + Identifier id = Identifier.Parse(GetMockIdentifier(ProtocolVersion.V20)); + + rp.EndpointFilter = opendpoint => true; + var requests = rp.CreateRequests(id, RPRealmUri, RPUri); + Assert.AreEqual(1, requests.Count()); + + rp.EndpointFilter = opendpoint => false; + requests = rp.CreateRequests(id, RPRealmUri, RPUri); + Assert.AreEqual(0, requests.Count()); + } + [TestMethod, ExpectedException(typeof(ProtocolException))] public void CreateRequestOnNonOpenID() { Uri nonOpenId = new Uri("http://www.microsoft.com/"); @@ -79,5 +94,31 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty { var requests = rp.CreateRequests(nonOpenId, RPRealmUri, RPUri); Assert.AreEqual(0, requests.Count()); } + + /// <summary> + /// Verifies that incoming positive assertions throw errors if they come from + /// OPs that are not approved by <see cref="OpenIdRelyingParty.EndpointFilter"/>. + /// </summary> + [TestMethod] + public void AssertionWithEndpointFilter() { + var coordinator = new OpenIdCoordinator( + rp => { + // register with RP so that id discovery passes + rp.Channel.WebRequestHandler = this.MockResponder.MockWebRequestHandler; + + // Rig it to always deny the incoming OP + rp.EndpointFilter = op => false; + + // Receive the unsolicited assertion + var response = rp.GetResponse(); + Assert.AreEqual(AuthenticationStatus.Failed, response.Status); + }, + op => { + Identifier id = GetMockIdentifier(ProtocolVersion.V20); + op.SendUnsolicitedAssertion(OPUri, GetMockRealm(false), id, id); + AutoProvider(op); + }); + coordinator.Run(); + } } } diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs index 1b9570e..6e71b0a 100644 --- a/src/DotNetOpenAuth/OpenId/Identifier.cs +++ b/src/DotNetOpenAuth/OpenId/Identifier.cs @@ -33,6 +33,16 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Gets or sets a value indicating whether <see cref="Identifier"/> instances are considered equal + /// based solely on their string reprsentations. + /// </summary> + /// <remarks> + /// This property serves as a test hook, so that MockIdentifier instances can be considered "equal" + /// to UriIdentifier instances. + /// </remarks> + protected internal static bool EqualityOnStrings { get; set; } + + /// <summary> /// Gets a value indicating whether this Identifier will ensure SSL is /// used throughout the discovery phase and initial redirect of authentication. /// </summary> diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs index 9136f49..f6d157c 100644 --- a/src/DotNetOpenAuth/OpenId/Realm.cs +++ b/src/DotNetOpenAuth/OpenId/Realm.cs @@ -27,7 +27,7 @@ namespace DotNetOpenAuth.OpenId { /// </remarks> [Serializable] [Pure] - public sealed class Realm { + public class Realm { /// <summary> /// A regex used to detect a wildcard that is being used in the realm. /// </summary> @@ -381,7 +381,7 @@ namespace DotNetOpenAuth.OpenId { /// <returns> /// The details of the endpoints if found, otherwise null. /// </returns> - internal IEnumerable<RelyingPartyEndpointDescription> Discover(IDirectWebRequestHandler requestHandler, bool allowRedirects) { + internal virtual IEnumerable<RelyingPartyEndpointDescription> Discover(IDirectWebRequestHandler requestHandler, bool allowRedirects) { // Attempt YADIS discovery DiscoveryResult yadisResult = Yadis.Discover(requestHandler, this.UriWithWildcardChangedToWww, false); if (yadisResult != null) { diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs index 4152666..608c3ff 100644 --- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs @@ -129,6 +129,11 @@ namespace DotNetOpenAuth.OpenId { /// The <paramref name="obj"/> parameter is null. /// </exception> public override bool Equals(object obj) { + // This first check is for a test hook + if (Identifier.EqualityOnStrings && obj != null) { + return string.Equals(this.ToString(), obj.ToString(), StringComparison.Ordinal); + } + UriIdentifier other = obj as UriIdentifier; if (other == null) { return false; diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs index 1bb03ee..a7107be 100644 --- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs @@ -120,6 +120,11 @@ namespace DotNetOpenAuth.OpenId { /// The <paramref name="obj"/> parameter is null. /// </exception> public override bool Equals(object obj) { + // This first check is for a test hook + if (Identifier.EqualityOnStrings && obj != null) { + return string.Equals(this.ToString(), obj.ToString(), StringComparison.Ordinal); + } + XriIdentifier other = obj as XriIdentifier; if (other == null) { return false; |