summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-08-04 17:20:46 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2008-08-04 17:20:46 -0700
commit947ca3aca15cd23a7d8b1496ebda219a79487b6f (patch)
tree38dffc73cc8ece6c248a0d2d1b9daa276e7c3ae7
parent7aed732e3451af0e2722303668e1f37a511dcc13 (diff)
downloadDotNetOpenAuth-947ca3aca15cd23a7d8b1496ebda219a79487b6f.zip
DotNetOpenAuth-947ca3aca15cd23a7d8b1496ebda219a79487b6f.tar.gz
DotNetOpenAuth-947ca3aca15cd23a7d8b1496ebda219a79487b6f.tar.bz2
Simplifying end-to-end testing class to better utilize enhanced TestSupport class.
-rw-r--r--src/DotNetOpenId.Test/EndToEndTesting.cs159
-rw-r--r--src/DotNetOpenId.Test/TestSupport.cs59
2 files changed, 91 insertions, 127 deletions
diff --git a/src/DotNetOpenId.Test/EndToEndTesting.cs b/src/DotNetOpenId.Test/EndToEndTesting.cs
index 145a447..abe77eb 100644
--- a/src/DotNetOpenId.Test/EndToEndTesting.cs
+++ b/src/DotNetOpenId.Test/EndToEndTesting.cs
@@ -4,13 +4,8 @@ using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
-using System.Web;
-using DotNetOpenId.Provider;
using DotNetOpenId.RelyingParty;
using NUnit.Framework;
-using IProviderAssociationStore = DotNetOpenId.IAssociationStore<DotNetOpenId.AssociationRelyingPartyType>;
-using ProviderMemoryStore = DotNetOpenId.AssociationMemoryStore<DotNetOpenId.AssociationRelyingPartyType>;
-using DotNetOpenId.Test.Mocks;
namespace DotNetOpenId.Test {
[TestFixture]
@@ -22,73 +17,28 @@ namespace DotNetOpenId.Test {
UntrustedWebRequest.WhitelistHosts.Add("localhost");
}
- void parameterizedTest(Identifier identityUrl,
- AuthenticationRequestMode requestMode, AuthenticationStatus expectedResult,
- bool tryReplayAttack, bool provideStore) {
- parameterizedProgrammaticTest(identityUrl, identityUrl, requestMode, expectedResult, tryReplayAttack, provideStore);
- parameterizedWebClientTest(identityUrl, requestMode, expectedResult, tryReplayAttack, provideStore);
+ void parameterizedTest(TestSupport.Scenarios scenario, ProtocolVersion version,
+ AuthenticationRequestMode requestMode, AuthenticationStatus expectedResult) {
+ Identifier userSuppliedIdentifier = TestSupport.GetMockIdentifier(scenario, version);
+ Identifier claimedId = userSuppliedIdentifier;
+ parameterizedProgrammaticTest(scenario, version, claimedId, requestMode, expectedResult, true);
+ parameterizedProgrammaticTest(scenario, version, claimedId, requestMode, expectedResult, false);
+ parameterizedWebClientTest(userSuppliedIdentifier, requestMode, expectedResult);
}
- void parameterizedProgrammaticTest(Identifier userSuppliedIdentifier, Identifier claimedUrl,
- AuthenticationRequestMode requestMode, AuthenticationStatus expectedResult,
- bool tryReplayAttack, bool provideStore) {
-
- Uri redirectToProviderUrl;
- var returnTo = TestSupport.GetFullUrl(TestSupport.ConsumerPage);
- var realm = new Realm(TestSupport.GetFullUrl(TestSupport.ConsumerPage).AbsoluteUri);
- var consumer = TestSupport.CreateRelyingParty(provideStore ? TestSupport.RelyingPartyStore : null, null);
- Assert.IsNull(consumer.Response);
- var request = consumer.CreateRequest(userSuppliedIdentifier, realm, returnTo);
- Protocol protocol = Protocol.Lookup(request.Provider.Version);
- var store = provideStore ? TestSupport.RelyingPartyStore : null;
-
- // Test properties and defaults
- Assert.AreEqual(AuthenticationRequestMode.Setup, request.Mode);
- Assert.AreEqual(returnTo, request.ReturnToUrl);
- Assert.AreEqual(realm, request.Realm);
+ void parameterizedProgrammaticTest(TestSupport.Scenarios scenario, ProtocolVersion version,
+ Identifier claimedUrl, AuthenticationRequestMode requestMode,
+ AuthenticationStatus expectedResult, bool provideStore) {
+ var request = TestSupport.CreateRelyingPartyRequest(!provideStore, scenario, version);
request.Mode = requestMode;
- Assert.IsNotNull(request.RedirectingResponse);
- var rpWebMessageToOP = request.RedirectingResponse as Response;
- Assert.IsNotNull(rpWebMessageToOP);
- var rpMessageToOP = rpWebMessageToOP.EncodableMessage as IndirectMessageRequest;
- Assert.IsNotNull(rpMessageToOP);
-
- // Verify the redirect URL
- var consumerToProviderQuery = HttpUtility.ParseQueryString(request.RedirectingResponse.ExtractUrl().Query);
- Assert.IsTrue(consumerToProviderQuery[protocol.openid.return_to].StartsWith(returnTo.AbsoluteUri, StringComparison.Ordinal));
- Assert.AreEqual(realm.ToString(), consumerToProviderQuery[protocol.openid.Realm]);
- redirectToProviderUrl = request.RedirectingResponse.ExtractUrl();
-
- OpenIdProvider provider = TestSupport.CreateProviderForRequest(request);
- var opAuthRequest = provider.Request as DotNetOpenId.Provider.IAuthenticationRequest;
- Assert.IsNotNull(opAuthRequest);
- opAuthRequest.IsAuthenticated = expectedResult == AuthenticationStatus.Authenticated;
- Assert.IsTrue(opAuthRequest.IsResponseReady);
-
- consumer = TestSupport.CreateRelyingPartyForResponse(store, opAuthRequest.Response);
- Assert.IsNotNull(consumer.Response);
- Assert.AreEqual(expectedResult, consumer.Response.Status);
- Assert.AreEqual(claimedUrl, consumer.Response.ClaimedIdentifier);
-
- // Try replay attack
- if (tryReplayAttack) {
- // This simulates a network sniffing user who caught the
- // authenticating query en route to either the user agent or
- // the consumer, and tries the same query to the consumer in an
- // attempt to spoof the identity of the authenticating user.
- try {
- var replayAttackConsumer = TestSupport.CreateRelyingPartyForResponse(store, opAuthRequest.Response);
- Assert.AreNotEqual(AuthenticationStatus.Authenticated, replayAttackConsumer.Response.Status, "Replay attack");
- } catch (OpenIdException) { // nonce already used
- // another way to pass
- }
- }
+ var rpResponse = TestSupport.CreateRelyingPartyResponseThroughProvider(request,
+ opReq => opReq.IsAuthenticated = expectedResult == AuthenticationStatus.Authenticated);
+ Assert.AreEqual(expectedResult, rpResponse.Status);
+ Assert.AreEqual(claimedUrl, rpResponse.ClaimedIdentifier);
}
void parameterizedWebClientTest(Identifier identityUrl,
- AuthenticationRequestMode requestMode, AuthenticationStatus expectedResult,
- bool tryReplayAttack, bool provideStore) {
- var store = provideStore ? TestSupport.RelyingPartyStore : null;
+ AuthenticationRequestMode requestMode, AuthenticationStatus expectedResult) {
Uri redirectToProviderUrl;
HttpWebRequest rpRequest = (HttpWebRequest)WebRequest.Create(TestSupport.GetFullUrl(TestSupport.ConsumerPage));
@@ -147,7 +97,7 @@ namespace DotNetOpenId.Test {
}
// Try replay attack
- if (tryReplayAttack) {
+ if (expectedResult == AuthenticationStatus.Authenticated) {
// This simulates a network sniffing user who caught the
// authenticating query en route to either the user agent or
// the consumer, and tries the same query to the consumer in an
@@ -162,107 +112,71 @@ namespace DotNetOpenId.Test {
[Test]
public void Pass_Setup_AutoApproval_11() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V11),
+ TestSupport.Scenarios.AutoApproval, ProtocolVersion.V11,
AuthenticationRequestMode.Setup,
- AuthenticationStatus.Authenticated,
- true,
- true
+ AuthenticationStatus.Authenticated
);
}
[Test]
public void Pass_Setup_AutoApproval_20() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20),
+ TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20,
AuthenticationRequestMode.Setup,
- AuthenticationStatus.Authenticated,
- true,
- true
+ AuthenticationStatus.Authenticated
);
}
[Test]
public void Pass_Immediate_AutoApproval_11() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V11),
+ TestSupport.Scenarios.AutoApproval, ProtocolVersion.V11,
AuthenticationRequestMode.Immediate,
- AuthenticationStatus.Authenticated,
- true,
- true
+ AuthenticationStatus.Authenticated
);
}
[Test]
public void Pass_Immediate_AutoApproval_20() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20),
+ TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20,
AuthenticationRequestMode.Immediate,
- AuthenticationStatus.Authenticated,
- true,
- true
+ AuthenticationStatus.Authenticated
);
}
[Test]
public void Fail_Immediate_ApproveOnSetup_11() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V11),
+ TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V11,
AuthenticationRequestMode.Immediate,
- AuthenticationStatus.SetupRequired,
- false,
- true
+ AuthenticationStatus.SetupRequired
);
}
[Test]
public void Fail_Immediate_ApproveOnSetup_20() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V20),
+ TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V20,
AuthenticationRequestMode.Immediate,
- AuthenticationStatus.SetupRequired,
- false,
- true
+ AuthenticationStatus.SetupRequired
);
}
[Test]
public void Pass_Setup_ApproveOnSetup_11() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V11),
+ TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V11,
AuthenticationRequestMode.Setup,
- AuthenticationStatus.Authenticated,
- true,
- true
+ AuthenticationStatus.Authenticated
);
}
[Test]
public void Pass_Setup_ApproveOnSetup_20() {
parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V20),
+ TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V20,
AuthenticationRequestMode.Setup,
- AuthenticationStatus.Authenticated,
- true,
- true
+ AuthenticationStatus.Authenticated
);
}
- [Test]
- public void Pass_NoStore_AutoApproval_11() {
- parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V11),
- AuthenticationRequestMode.Setup,
- AuthenticationStatus.Authenticated,
- true,
- false
- );
- }
- [Test]
- public void Pass_NoStore_AutoApproval_20() {
- parameterizedTest(
- TestSupport.GetMockIdentifier(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V20),
- AuthenticationRequestMode.Setup,
- AuthenticationStatus.Authenticated,
- true,
- false
- );
- }
[Test]
public void ProviderAddedFragmentRemainsInClaimedIdentifier() {
@@ -270,11 +184,10 @@ namespace DotNetOpenId.Test {
UriBuilder claimedIdentifier = new UriBuilder(userSuppliedIdentifier);
claimedIdentifier.Fragment = "frag";
parameterizedProgrammaticTest(
- userSuppliedIdentifier,
+ TestSupport.Scenarios.AutoApprovalAddFragment, ProtocolVersion.V20,
claimedIdentifier.Uri,
AuthenticationRequestMode.Setup,
AuthenticationStatus.Authenticated,
- false,
true
);
}
@@ -282,8 +195,8 @@ namespace DotNetOpenId.Test {
[Test]
public void SampleScriptedTest() {
var rpReq = TestSupport.CreateRelyingPartyRequest(false, TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20);
- var rp = TestSupport.CreateRelyingPartyFromRoundtrippedProviderRequest(rpReq, opReq => opReq.IsAuthenticated = true);
- Assert.AreEqual(AuthenticationStatus.Authenticated, rp.Response.Status);
+ var rpResp = TestSupport.CreateRelyingPartyResponseThroughProvider(rpReq, opReq => opReq.IsAuthenticated = true);
+ Assert.AreEqual(AuthenticationStatus.Authenticated, rpResp.Status);
}
}
}
diff --git a/src/DotNetOpenId.Test/TestSupport.cs b/src/DotNetOpenId.Test/TestSupport.cs
index 3ddb673..899cdd9 100644
--- a/src/DotNetOpenId.Test/TestSupport.cs
+++ b/src/DotNetOpenId.Test/TestSupport.cs
@@ -4,6 +4,7 @@ using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Reflection;
+using System.Web;
using DotNetOpenId;
using DotNetOpenId.Provider;
using DotNetOpenId.RelyingParty;
@@ -105,6 +106,9 @@ public class TestSupport {
/// </summary>
internal static OpenIdRelyingParty CreateRelyingParty(IRelyingPartyApplicationStore store, Uri requestUrl, NameValueCollection fields) {
var rp = new OpenIdRelyingParty(store, requestUrl ?? GetFullUrl(ConsumerPage), fields ?? new NameValueCollection());
+ if (fields == null || fields.Count == 0) {
+ Assert.IsNull(rp.Response);
+ }
rp.DirectMessageChannel = new DirectMessageTestRedirector(ProviderStore);
return rp;
}
@@ -114,19 +118,48 @@ public class TestSupport {
var rp = TestSupport.CreateRelyingParty(stateless ? null : RelyingPartyStore, null);
var rpReq = rp.CreateRequest(TestSupport.GetMockIdentifier(scenario, version), realm, returnTo);
+
+ {
+ // Sidetrack: verify URLs and other default properties
+ Assert.AreEqual(AuthenticationRequestMode.Setup, rpReq.Mode);
+ Assert.AreEqual(realm, rpReq.Realm);
+ Assert.AreEqual(returnTo, rpReq.ReturnToUrl);
+ }
+
return rpReq;
}
/// <summary>
/// Generates a new <see cref="OpenIdRelyingParty"/> ready to process a
/// response from an <see cref="OpenIdProvider"/>.
/// </summary>
- internal static OpenIdRelyingParty CreateRelyingPartyForResponse(IRelyingPartyApplicationStore store, IResponse providerResponse) {
+ internal static IAuthenticationResponse CreateRelyingPartyResponse(IRelyingPartyApplicationStore store, IResponse providerResponse) {
if (providerResponse == null) throw new ArgumentNullException("providerResponse");
var opAuthWebResponse = (Response)providerResponse;
var opAuthResponse = (EncodableResponse)opAuthWebResponse.EncodableMessage;
- return CreateRelyingParty(store, opAuthResponse.RedirectUrl,
+ var rp = CreateRelyingParty(store, opAuthResponse.RedirectUrl,
opAuthResponse.EncodedFields.ToNameValueCollection());
+
+ // TODO: Remove this conditional, which really should not be required.
+ // When it's removed, some tests hang while signature verification
+ // is supposedly being performed.
+ if (rp.Response.Status == AuthenticationStatus.Authenticated) {
+ // Side-track to test for replay attack while we're at it.
+ // This simulates a network sniffing user who caught the
+ // authenticating query en route to either the user agent or
+ // the consumer, and tries the same query to the consumer in an
+ // attempt to spoof the identity of the authenticating user.
+ try {
+ var replayRP = CreateRelyingParty(store, opAuthResponse.RedirectUrl,
+ opAuthResponse.EncodedFields.ToNameValueCollection());
+ Assert.AreNotEqual(AuthenticationStatus.Authenticated, replayRP.Response.Status, "Replay attack succeeded!");
+ } catch (OpenIdException) { // nonce already used
+ // another way to pass
+ }
+ }
+
+ // Return the result of the initial response (not the replay attack one).
+ return rp.Response;
}
/// <summary>
/// Generates a new <see cref="OpenIdProvider"/> that uses the shared
@@ -147,19 +180,30 @@ public class TestSupport {
internal static IResponse CreateProviderResponseToRequest(
DotNetOpenId.RelyingParty.IAuthenticationRequest request,
Action<DotNetOpenId.Provider.IAuthenticationRequest> prepareProviderResponse) {
+
+ {
+ // Sidetrack: Verify the return_to and realm URLs
+ var consumerToProviderQuery = HttpUtility.ParseQueryString(request.RedirectingResponse.ExtractUrl().Query);
+ Protocol protocol = Protocol.Detect(consumerToProviderQuery.ToDictionary());
+ Assert.IsTrue(consumerToProviderQuery[protocol.openid.return_to].StartsWith(request.ReturnToUrl.AbsoluteUri, StringComparison.Ordinal));
+ Assert.AreEqual(request.Realm.ToString(), consumerToProviderQuery[protocol.openid.Realm]);
+ }
+
var op = TestSupport.CreateProviderForRequest(request);
var opReq = (DotNetOpenId.Provider.IAuthenticationRequest)op.Request;
prepareProviderResponse(opReq);
+ Assert.IsTrue(opReq.IsResponseReady);
return opReq.Response;
}
- internal static OpenIdRelyingParty CreateRelyingPartyFromRoundtrippedProviderRequest(
+ internal static IAuthenticationResponse CreateRelyingPartyResponseThroughProvider(
DotNetOpenId.RelyingParty.IAuthenticationRequest request,
Action<DotNetOpenId.Provider.IAuthenticationRequest> providerAction) {
var rpReq = (AuthenticationRequest)request;
var opResponse = CreateProviderResponseToRequest(rpReq, providerAction);
// Be careful to use whatever store the original RP was using.
- var rp = CreateRelyingPartyForResponse(rpReq.RelyingParty.Store, opResponse);
+ var rp = CreateRelyingPartyResponse(rpReq.RelyingParty.Store, opResponse);
+ Assert.IsNotNull(rp);
return rp;
}
@@ -224,4 +268,11 @@ static class TestExtensions {
}
return nvc;
}
+ public static IDictionary<string, string> ToDictionary(this NameValueCollection nvc) {
+ Dictionary<string, string> dict = new Dictionary<string, string>(nvc.Count);
+ foreach (string key in nvc) {
+ dict[key] = nvc[key];
+ }
+ return dict;
+ }
}