summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/Channel.cs15
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/MessageProtectionTasks.cs6
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs56
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth2.ResourceServer/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs2
-rw-r--r--src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/KeyValueFormEncoding.cs4
-rw-r--r--src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs5
-rw-r--r--src/DotNetOpenAuth.Test/CoordinatorBase.cs92
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj10
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs16
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs54
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs22
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs76
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs108
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs40
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs348
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingHttpRequestInfo.cs109
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2AuthServerChannel.cs33
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs37
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs155
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs163
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs47
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs14
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs12
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockRealm.cs10
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs15
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs19
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs17
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs11
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/AppendixScenarios.cs112
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs71
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs2
35 files changed, 321 insertions, 1368 deletions
diff --git a/src/DotNetOpenAuth.Core/Messaging/Channel.cs b/src/DotNetOpenAuth.Core/Messaging/Channel.cs
index 8564e38..62de162 100644
--- a/src/DotNetOpenAuth.Core/Messaging/Channel.cs
+++ b/src/DotNetOpenAuth.Core/Messaging/Channel.cs
@@ -504,8 +504,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="response">The response that is anticipated to contain an protocol message.</param>
/// <returns>The deserialized message parts, if found. Null otherwise.</returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
- internal Task<IDictionary<string, string>> ReadFromResponseCoreAsyncTestHook(HttpResponseMessage response) {
- return this.ReadFromResponseCoreAsync(response);
+ internal Task<IDictionary<string, string>> ReadFromResponseCoreAsyncTestHook(HttpResponseMessage response, CancellationToken cancellationToken) {
+ return this.ReadFromResponseCoreAsync(response, cancellationToken);
}
/// <summary>
@@ -520,7 +520,7 @@ namespace DotNetOpenAuth.Messaging {
/// This method should NOT be called by derived types
/// except when sending ONE WAY request messages.
/// </remarks>
- internal Task ProcessOutgoingMessageTestHookAsync(IProtocolMessage message, CancellationToken cancellationToken) {
+ internal Task ProcessOutgoingMessageTestHookAsync(IProtocolMessage message, CancellationToken cancellationToken = default(CancellationToken)) {
return this.ProcessOutgoingMessageAsync(message, cancellationToken);
}
@@ -685,7 +685,7 @@ namespace DotNetOpenAuth.Messaging {
return null;
}
- var responseFields = await this.ReadFromResponseCoreAsync(response);
+ var responseFields = await this.ReadFromResponseCoreAsync(response, cancellationToken);
if (responseFields == null) {
return null;
}
@@ -914,9 +914,12 @@ namespace DotNetOpenAuth.Messaging {
/// Gets the protocol message that may be in the given HTTP response.
/// </summary>
/// <param name="response">The response that is anticipated to contain an protocol message.</param>
- /// <returns>The deserialized message parts, if found. Null otherwise.</returns>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The deserialized message parts, if found. Null otherwise.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
- protected abstract Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response);
+ protected abstract Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken);
/// <summary>
/// Prepares an HTTP request that carries a given message.
diff --git a/src/DotNetOpenAuth.Core/Messaging/MessageProtectionTasks.cs b/src/DotNetOpenAuth.Core/Messaging/MessageProtectionTasks.cs
index 29163f7..37c86ca 100644
--- a/src/DotNetOpenAuth.Core/Messaging/MessageProtectionTasks.cs
+++ b/src/DotNetOpenAuth.Core/Messaging/MessageProtectionTasks.cs
@@ -31,5 +31,11 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
internal static readonly Task<MessageProtections?> TamperProtection =
Task.FromResult<MessageProtections?>(MessageProtections.TamperProtection);
+
+ /// <summary>
+ /// A task whose result is <see cref="MessageProtections.ReplayProtection"/>
+ /// </summary>
+ internal static readonly Task<MessageProtections?> ReplayProtection =
+ Task.FromResult<MessageProtections?>(MessageProtections.ReplayProtection);
}
}
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
index 3f677b8..b163d0d 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
@@ -296,7 +296,22 @@ namespace DotNetOpenAuth.OAuth {
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
public Task<UserAuthorizationRequest> ReadAuthorizationRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
request = request ?? this.channel.GetRequestFromContext();
- return this.Channel.TryReadFromRequestAsync<UserAuthorizationRequest>(request.AsHttpRequestMessage(), cancellationToken);
+ return this.ReadAuthorizationRequestAsync(request.AsHttpRequestMessage(), cancellationToken);
+ }
+
+ /// <summary>
+ /// Reads in a Consumer's request for the Service Provider to obtain permission from
+ /// the user to authorize the Consumer's access of some protected resource(s).
+ /// </summary>
+ /// <param name="request">The HTTP request to read from.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
+ /// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
+ public Task<UserAuthorizationRequest> ReadAuthorizationRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
+ Requires.NotNull(request, "request");
+ return this.Channel.TryReadFromRequestAsync<UserAuthorizationRequest>(request, cancellationToken);
}
/// <summary>
@@ -372,7 +387,21 @@ namespace DotNetOpenAuth.OAuth {
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
public Task<AuthorizedTokenRequest> ReadAccessTokenRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
request = request ?? this.Channel.GetRequestFromContext();
- return this.Channel.TryReadFromRequestAsync<AuthorizedTokenRequest>(request.AsHttpRequestMessage(), cancellationToken);
+ return this.ReadAccessTokenRequestAsync(request.AsHttpRequestMessage(), cancellationToken);
+ }
+
+ /// <summary>
+ /// Reads in a Consumer's request to exchange an authorized request token for an access token.
+ /// </summary>
+ /// <param name="request">The HTTP request to read from.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
+ /// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
+ public Task<AuthorizedTokenRequest> ReadAccessTokenRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
+ Requires.NotNull(request, "request");
+ return this.Channel.TryReadFromRequestAsync<AuthorizedTokenRequest>(request, cancellationToken);
}
/// <summary>
@@ -425,9 +454,26 @@ namespace DotNetOpenAuth.OAuth {
/// to access the resources being requested.
/// </remarks>
/// <exception cref="ProtocolException">Thrown if an unexpected message is attached to the request.</exception>
- public async Task<AccessProtectedResourceRequest> ReadProtectedResourceAuthorizationAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
- request = request ?? this.Channel.GetRequestFromContext();
- var accessMessage = await this.Channel.TryReadFromRequestAsync<AccessProtectedResourceRequest>(request.AsHttpRequestMessage(), cancellationToken);
+ public Task<AccessProtectedResourceRequest> ReadProtectedResourceAuthorizationAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ request = request ?? this.channel.GetRequestFromContext();
+ return this.ReadProtectedResourceAuthorizationAsync(request.AsHttpRequestMessage(), cancellationToken);
+ }
+
+ /// <summary>
+ /// Gets the authorization (access token) for accessing some protected resource.
+ /// </summary>
+ /// <param name="request">The incoming HTTP request.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>The authorization message sent by the Consumer, or null if no authorization message is attached.</returns>
+ /// <remarks>
+ /// This method verifies that the access token and token secret are valid.
+ /// It falls on the caller to verify that the access token is actually authorized
+ /// to access the resources being requested.
+ /// </remarks>
+ /// <exception cref="ProtocolException">Thrown if an unexpected message is attached to the request.</exception>
+ public async Task<AccessProtectedResourceRequest> ReadProtectedResourceAuthorizationAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
+ Requires.NotNull(request, "request");
+ var accessMessage = await this.Channel.TryReadFromRequestAsync<AccessProtectedResourceRequest>(request, cancellationToken);
if (accessMessage != null) {
if (this.TokenManager.GetTokenType(accessMessage.AccessToken) != TokenType.AccessToken) {
throw new ProtocolException(
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs
index 0925402..b120344 100644
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs
+++ b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs
@@ -171,7 +171,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <returns>
/// The deserialized message parts, if found. Null otherwise.
/// </returns>
- protected override async Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response) {
+ protected override async Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) {
string body = await response.Content.ReadAsStringAsync();
return HttpUtility.ParseQueryString(body).ToDictionary();
}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs
index 3fcbf67..609cedb 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs
@@ -66,7 +66,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// The deserialized message parts, if found. Null otherwise.
/// </returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
- protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response) {
+ protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) {
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs
index ae1a823..a11b81b 100644
--- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs
+++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs
@@ -92,7 +92,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// The deserialized message parts, if found. Null otherwise.
/// </returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
- protected override async Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response) {
+ protected override async Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) {
// The spec says direct responses should be JSON objects, but Facebook uses HttpFormUrlEncoded instead, calling it text/plain
// Others return text/javascript. Again bad.
string body = await response.Content.ReadAsStringAsync();
diff --git a/src/DotNetOpenAuth.OAuth2.ResourceServer/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs b/src/DotNetOpenAuth.OAuth2.ResourceServer/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs
index c645753..1d90844 100644
--- a/src/DotNetOpenAuth.OAuth2.ResourceServer/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs
+++ b/src/DotNetOpenAuth.OAuth2.ResourceServer/OAuth2/ChannelElements/OAuth2ResourceServerChannel.cs
@@ -90,7 +90,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// The deserialized message parts, if found. Null otherwise.
/// </returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
- protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response) {
+ protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) {
// We never expect resource servers to send out direct requests,
// and therefore won't have direct responses.
throw new NotImplementedException();
diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/KeyValueFormEncoding.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/KeyValueFormEncoding.cs
index c74a636..9c06e6b 100644
--- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/KeyValueFormEncoding.cs
+++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/KeyValueFormEncoding.cs
@@ -11,6 +11,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
using System.Globalization;
using System.IO;
using System.Text;
+ using System.Threading;
using System.Threading.Tasks;
using DotNetOpenAuth.Messaging;
using Validation;
@@ -132,12 +133,13 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="data">The stream of Key-Value Form encoded bytes.</param>
/// <returns>The deserialized dictionary.</returns>
/// <exception cref="FormatException">Thrown when the data is not in the expected format.</exception>
- public async Task<IDictionary<string, string>> GetDictionaryAsync(Stream data) {
+ public async Task<IDictionary<string, string>> GetDictionaryAsync(Stream data, CancellationToken cancellationToken) {
using (StreamReader reader = new StreamReader(data, textEncoding)) {
var dict = new Dictionary<string, string>();
int line_num = 0;
string line;
while ((line = await reader.ReadLineAsync()) != null) {
+ cancellationToken.ThrowIfCancellationRequested();
line_num++;
if (this.ConformanceLevel == KeyValueFormConformanceLevel.Loose) {
line = line.Trim();
diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs
index 6d4df61..dcc4019 100644
--- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs
+++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/OpenIdChannel.cs
@@ -133,14 +133,15 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// Gets the protocol message that may be in the given HTTP response.
/// </summary>
/// <param name="response">The response that is anticipated to contain an protocol message.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// The deserialized message parts, if found. Null otherwise.
/// </returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
- protected override async Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response) {
+ protected override async Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) {
try {
using (var responseStream = await response.Content.ReadAsStreamAsync()) {
- return await this.keyValueForm.GetDictionaryAsync(responseStream);
+ return await this.keyValueForm.GetDictionaryAsync(responseStream, cancellationToken);
}
} catch (FormatException ex) {
throw ErrorUtilities.Wrap(ex, ex.Message);
diff --git a/src/DotNetOpenAuth.Test/CoordinatorBase.cs b/src/DotNetOpenAuth.Test/CoordinatorBase.cs
index 48067af..6a3ad86 100644
--- a/src/DotNetOpenAuth.Test/CoordinatorBase.cs
+++ b/src/DotNetOpenAuth.Test/CoordinatorBase.cs
@@ -7,6 +7,8 @@
namespace DotNetOpenAuth.Test {
using System;
using System.Collections.Generic;
+ using System.Net;
+ using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using DotNetOpenAuth.Messaging;
@@ -15,40 +17,80 @@ namespace DotNetOpenAuth.Test {
using NUnit.Framework;
using Validation;
- internal abstract class CoordinatorBase<T1, T2> {
- private Func<T1, CancellationToken, Task> party1Action;
- private Func<T2, CancellationToken, Task> party2Action;
+ using System.Linq;
- protected CoordinatorBase(Func<T1, CancellationToken, Task> party1Action, Func<T2, CancellationToken, Task> party2Action) {
- Requires.NotNull(party1Action, "party1Action");
- Requires.NotNull(party2Action, "party2Action");
+ internal class CoordinatorBase {
+ private Func<IHostFactories, CancellationToken, Task> driver;
- this.party1Action = party1Action;
- this.party2Action = party2Action;
+ private Handler[] handlers;
+
+ internal CoordinatorBase(Func<IHostFactories, CancellationToken, Task> driver, params Handler[] handlers) {
+ Requires.NotNull(driver, "driver");
+ Requires.NotNull(handlers, "handlers");
+
+ this.driver = driver;
+ this.handlers = handlers;
}
- protected internal Action<IProtocolMessage> IncomingMessageFilter { get; set; }
+ protected internal virtual async Task RunAsync(CancellationToken cancellationToken = default(CancellationToken)) {
+ IHostFactories hostFactories = new MyHostFactories(this.handlers);
+
+ await this.driver(hostFactories, cancellationToken);
+ }
- protected internal Action<IProtocolMessage> OutgoingMessageFilter { get; set; }
+ internal static Handler Handle(Uri uri) {
+ return new Handler(uri);
+ }
- internal abstract Task RunAsync();
+ internal struct Handler {
+ internal Handler(Uri uri)
+ : this() {
+ this.Uri = uri;
+ }
+
+ public Uri Uri { get; private set; }
+
+ public Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> MessageHandler { get; private set; }
+
+ internal Handler By(Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> handler) {
+ return new Handler(this.Uri) { MessageHandler = handler };
+ }
+ }
- protected async Task RunCoreAsync(T1 party1Object, T2 party2Object) {
- var cts = new CancellationTokenSource();
+ private class MyHostFactories : IHostFactories {
+ private readonly Handler[] handlers;
+
+ public MyHostFactories(Handler[] handlers) {
+ this.handlers = handlers;
+ }
+
+ public HttpMessageHandler CreateHttpMessageHandler() {
+ return new ForwardingMessageHandler(this.handlers);
+ }
+
+ public HttpClient CreateHttpClient(HttpMessageHandler handler = null) {
+ return new HttpClient(handler ?? this.CreateHttpMessageHandler());
+ }
+ }
+
+ private class ForwardingMessageHandler : HttpMessageHandler {
+ private readonly Handler[] handlers;
+
+ public ForwardingMessageHandler(Handler[] handlers) {
+ this.handlers = handlers;
+ }
- try {
- var parties = new List<Task> {
- Task.Run(() => this.party1Action(party1Object, cts.Token)),
- Task.Run(() => this.party2Action(party2Object, cts.Token)),
- };
- var completingTask = await Task.WhenAny(parties);
- await completingTask; // rethrow any exception from the first completing task.
+ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
+ foreach (var handler in this.handlers) {
+ if (handler.Uri.AbsolutePath == request.RequestUri.AbsolutePath) {
+ var response = await handler.MessageHandler(request, cancellationToken);
+ if (response != null) {
+ return response;
+ }
+ }
+ }
- // if no exception, then block for the second task now.
- await Task.WhenAll(parties);
- } catch {
- cts.Cancel(); // cause the second party to terminate, if necessary.
- throw;
+ return new HttpResponseMessage(HttpStatusCode.NotFound);
}
}
}
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index ba87c42..a355ab6 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -114,7 +114,6 @@
<Compile Include="Messaging\EnumerableCacheTests.cs" />
<Compile Include="Messaging\ErrorUtilitiesTests.cs" />
<Compile Include="Messaging\MessageSerializerTests.cs" />
- <Compile Include="Messaging\MultipartPostPartTests.cs" />
<Compile Include="Messaging\Reflection\MessageDescriptionTests.cs" />
<Compile Include="Messaging\Reflection\MessageDictionaryTests.cs" />
<Compile Include="Messaging\MessagingTestBase.cs" />
@@ -127,12 +126,6 @@
<Compile Include="Messaging\Reflection\ValueMappingTests.cs" />
<Compile Include="Messaging\StandardMessageFactoryTests.cs" />
<Compile Include="Mocks\AssociateUnencryptedRequestNoSslCheck.cs" />
- <Compile Include="Mocks\CoordinatingChannel.cs" />
- <Compile Include="Mocks\CoordinatingHttpRequestInfo.cs" />
- <Compile Include="Mocks\CoordinatingOAuth2AuthServerChannel.cs" />
- <Compile Include="Mocks\CoordinatingOAuth2ClientChannel.cs" />
- <Compile Include="Mocks\CoordinatingOutgoingWebResponse.cs" />
- <Compile Include="Mocks\CoordinatingOAuthConsumerChannel.cs" />
<Compile Include="Mocks\IBaseMessageExplicitMembers.cs" />
<Compile Include="Mocks\InMemoryTokenManager.cs" />
<Compile Include="Mocks\MockHttpMessageHandler.cs" />
@@ -242,10 +235,7 @@
<Compile Include="Performance\HighPerformance.cs" />
<Compile Include="Performance\PerformanceTestUtilities.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Messaging\ResponseTests.cs" />
<Compile Include="OAuth\AppendixScenarios.cs" />
- <Compile Include="Mocks\CoordinatingOAuthServiceProviderChannel.cs" />
- <Compile Include="OAuth\OAuthCoordinator.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="TestUtilities.cs" />
<Compile Include="UriUtilTests.cs" />
diff --git a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
index d525766..a8eb7c1 100644
--- a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
@@ -27,27 +27,27 @@ namespace DotNetOpenAuth.Test.Messaging.Bindings {
}
[Test]
- public void VerifyGoodTimestampIsAccepted() {
+ public async Task VerifyGoodTimestampIsAccepted() {
this.Channel = CreateChannel(MessageProtections.Expiration);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow, false);
}
[Test]
- public void VerifyFutureTimestampWithinClockSkewIsAccepted() {
+ public async Task VerifyFutureTimestampWithinClockSkewIsAccepted() {
this.Channel = CreateChannel(MessageProtections.Expiration);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow + DotNetOpenAuthSection.Messaging.MaximumClockSkew - TimeSpan.FromSeconds(1), false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow + DotNetOpenAuthSection.Messaging.MaximumClockSkew - TimeSpan.FromSeconds(1), false);
}
[Test, ExpectedException(typeof(ExpiredMessageException))]
- public void VerifyOldTimestampIsRejected() {
+ public async Task VerifyOldTimestampIsRejected() {
this.Channel = CreateChannel(MessageProtections.Expiration);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow - StandardExpirationBindingElement.MaximumMessageAge - TimeSpan.FromSeconds(1), false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow - StandardExpirationBindingElement.MaximumMessageAge - TimeSpan.FromSeconds(1), false);
}
[Test, ExpectedException(typeof(ProtocolException))]
- public void VerifyFutureTimestampIsRejected() {
+ public async Task VerifyFutureTimestampIsRejected() {
this.Channel = CreateChannel(MessageProtections.Expiration);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow + DotNetOpenAuthSection.Messaging.MaximumClockSkew + TimeSpan.FromSeconds(2), false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow + DotNetOpenAuthSection.Messaging.MaximumClockSkew + TimeSpan.FromSeconds(2), false);
}
}
}
diff --git a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
index 4540373..b54c11b 100644
--- a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Test.Messaging {
using System.Collections.Generic;
using System.IO;
using System.Net;
+ using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
@@ -27,13 +28,13 @@ namespace DotNetOpenAuth.Test.Messaging {
}
[Test]
- public void ReadFromRequestQueryString() {
- this.ParameterizedReceiveTest("GET");
+ public async Task ReadFromRequestQueryString() {
+ await this.ParameterizedReceiveTestAsync(HttpMethod.Get);
}
[Test]
- public void ReadFromRequestForm() {
- this.ParameterizedReceiveTest("POST");
+ public async Task ReadFromRequestForm() {
+ await this.ParameterizedReceiveTestAsync(HttpMethod.Post);
}
/// <summary>
@@ -44,7 +45,7 @@ namespace DotNetOpenAuth.Test.Messaging {
public async Task ReadFromRequestDisallowedHttpMethod() {
var fields = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
fields["GetOnly"] = "true";
- await this.Channel.ReadFromRequestAsync(CreateHttpRequestInfo("POST", fields), CancellationToken.None);
+ await this.Channel.ReadFromRequestAsync(CreateHttpRequestInfo(HttpMethod.Post, fields), CancellationToken.None);
}
[Test, ExpectedException(typeof(ArgumentNullException))]
@@ -79,14 +80,14 @@ namespace DotNetOpenAuth.Test.Messaging {
var response = await this.Channel.PrepareResponseAsync(message);
Assert.AreEqual(HttpStatusCode.Redirect, response.StatusCode);
- Assert.AreEqual("text/html; charset=utf-8", response.Headers[HttpResponseHeader.ContentType]);
- Assert.IsTrue(response.Body != null && response.Body.Length > 0); // a non-empty body helps get passed filters like WebSense
- StringAssert.StartsWith("http://provider/path", response.Headers[HttpResponseHeader.Location]);
+ Assert.AreEqual("text/html; charset=utf-8", response.Content.Headers.ContentType.ToString());
+ Assert.IsTrue(response.Content != null && response.Content.Headers.ContentLength > 0); // a non-empty body helps get passed filters like WebSense
+ StringAssert.StartsWith("http://provider/path", response.Headers.Location.AbsoluteUri);
foreach (var pair in expected) {
string key = MessagingUtilities.EscapeUriDataStringRfc3986(pair.Key);
string value = MessagingUtilities.EscapeUriDataStringRfc3986(pair.Value);
string substring = string.Format("{0}={1}", key, value);
- StringAssert.Contains(substring, response.Headers[HttpResponseHeader.Location]);
+ StringAssert.Contains(substring, response.Headers.Location.AbsoluteUri);
}
}
@@ -124,8 +125,8 @@ namespace DotNetOpenAuth.Test.Messaging {
};
var response = await this.Channel.PrepareResponseAsync(message);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "A form redirect should be an HTTP successful response.");
- Assert.IsNull(response.Headers[HttpResponseHeader.Location], "There should not be a redirection header in the response.");
- string body = response.Body;
+ Assert.IsNull(response.Headers.Location, "There should not be a redirection header in the response.");
+ string body = await response.Content.ReadAsStringAsync();
StringAssert.Contains("<form ", body);
StringAssert.Contains("action=\"http://provider/path\"", body);
StringAssert.Contains("method=\"post\"", body);
@@ -197,23 +198,24 @@ namespace DotNetOpenAuth.Test.Messaging {
TestMessage expectedMessage = GetStandardTestMessage(FieldFill.AllRequired);
HttpRequest request = new HttpRequest("somefile", "http://someurl", MessagingUtilities.CreateQueryString(fields));
HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
- IProtocolMessage message = await this.Channel.ReadFromRequestAsync(CancellationToken.None);
+ var requestBase = this.Channel.GetRequestFromContext();
+ IProtocolMessage message = await this.Channel.ReadFromRequestAsync(requestBase.AsHttpRequestMessage(), CancellationToken.None);
Assert.IsNotNull(message);
Assert.IsInstanceOf<TestMessage>(message);
Assert.AreEqual(expectedMessage.Age, ((TestMessage)message).Age);
}
[Test, ExpectedException(typeof(InvalidOperationException))]
- public void ReadFromRequestNoContext() {
+ public void GetRequestFromContextNoContext() {
HttpContext.Current = null;
TestBadChannel badChannel = new TestBadChannel(false);
- badChannel.ReadFromRequest();
+ badChannel.GetRequestFromContext();
}
[Test, ExpectedException(typeof(ArgumentNullException))]
- public void ReadFromRequestNull() {
+ public async Task ReadFromRequestNull() {
TestBadChannel badChannel = new TestBadChannel(false);
- badChannel.ReadFromRequest(null);
+ await badChannel.ReadFromRequestAsync(null, CancellationToken.None);
}
[Test]
@@ -227,22 +229,22 @@ namespace DotNetOpenAuth.Test.Messaging {
}
[Test, ExpectedException(typeof(InvalidSignatureException))]
- public void ReceivedInvalidSignature() {
+ public async Task ReceivedInvalidSignature() {
this.Channel = CreateChannel(MessageProtections.TamperProtection);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, true);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow, true);
}
[Test]
- public void ReceivedReplayProtectedMessageJustOnce() {
+ public async Task ReceivedReplayProtectedMessageJustOnce() {
this.Channel = CreateChannel(MessageProtections.ReplayProtection);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow, false);
}
[Test, ExpectedException(typeof(ReplayedMessageException))]
- public void ReceivedReplayProtectedMessageTwice() {
+ public async Task ReceivedReplayProtectedMessageTwice() {
this.Channel = CreateChannel(MessageProtections.ReplayProtection);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow, false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.UtcNow, false);
}
[Test, ExpectedException(typeof(ProtocolException))]
@@ -293,15 +295,15 @@ namespace DotNetOpenAuth.Test.Messaging {
}
[Test, ExpectedException(typeof(UnprotectedMessageException))]
- public void InsufficientlyProtectedMessageReceived() {
+ public async Task InsufficientlyProtectedMessageReceived() {
this.Channel = CreateChannel(MessageProtections.None, MessageProtections.TamperProtection);
- this.ParameterizedReceiveProtectedTest(DateTime.Now, false);
+ await this.ParameterizedReceiveProtectedTestAsync(DateTime.Now, false);
}
[Test, ExpectedException(typeof(ProtocolException))]
public async Task IncomingMessageMissingRequiredParameters() {
var fields = GetStandardTestFields(FieldFill.IdentifiableButNotAllRequired);
- await this.Channel.ReadFromRequestAsync(CreateHttpRequestInfo("GET", fields), CancellationToken.None);
+ await this.Channel.ReadFromRequestAsync(CreateHttpRequestInfo(HttpMethod.Get, fields), CancellationToken.None);
}
}
}
diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs
index 092b89c..9e0cc99 100644
--- a/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs
@@ -10,6 +10,7 @@ namespace DotNetOpenAuth.Test {
using System.Collections.Specialized;
using System.IO;
using System.Net;
+ using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
@@ -57,20 +58,19 @@ namespace DotNetOpenAuth.Test {
this.Channel = new TestChannel();
}
- internal static HttpRequestInfo CreateHttpRequestInfo(string method, IDictionary<string, string> fields) {
+ internal static HttpRequestMessage CreateHttpRequestInfo(HttpMethod method, IDictionary<string, string> fields) {
+ var result = new HttpRequestMessage() { Method = method };
var requestUri = new UriBuilder(DefaultUrlForHttpRequestInfo);
- var headers = new NameValueCollection();
- NameValueCollection form = null;
- if (method == "POST") {
- form = fields.ToNameValueCollection();
- headers.Add(HttpRequestHeaders.ContentType, Channel.HttpFormUrlEncoded);
- } else if (method == "GET") {
- requestUri.Query = MessagingUtilities.CreateQueryString(fields);
+ if (method == HttpMethod.Post) {
+ result.Content = new FormUrlEncodedContent(fields);
+ } else if (method == HttpMethod.Get) {
+ requestUri.AppendQueryArgs(fields);
} else {
throw new ArgumentOutOfRangeException("method", method, "Expected POST or GET");
}
- return new HttpRequestInfo(method, requestUri.Uri, form: form, headers: headers);
+ result.RequestUri = requestUri.Uri;
+ return result;
}
internal static Channel CreateChannel(MessageProtections capabilityAndRecognition) {
@@ -145,7 +145,7 @@ namespace DotNetOpenAuth.Test {
}
}
- internal async Task ParameterizedReceiveTestAsync(string method) {
+ internal async Task ParameterizedReceiveTestAsync(HttpMethod method) {
var fields = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
TestMessage expectedMessage = GetStandardTestMessage(FieldFill.CompleteBeforeBindings);
@@ -167,7 +167,7 @@ namespace DotNetOpenAuth.Test {
utcCreatedDate = DateTime.Parse(utcCreatedDate.Value.ToUniversalTime().ToString()); // round off the milliseconds so comparisons work later
fields.Add("created_on", XmlConvert.ToString(utcCreatedDate.Value, XmlDateTimeSerializationMode.Utc));
}
- IProtocolMessage requestMessage = await this.Channel.ReadFromRequestAsync(CreateHttpRequestInfo("GET", fields), CancellationToken.None);
+ IProtocolMessage requestMessage = await this.Channel.ReadFromRequestAsync(CreateHttpRequestInfo(HttpMethod.Get, fields), CancellationToken.None);
Assert.IsNotNull(requestMessage);
Assert.IsInstanceOf<TestSignedDirectedMessage>(requestMessage);
TestSignedDirectedMessage actualMessage = (TestSignedDirectedMessage)requestMessage;
diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
index 7bb6d5c..f5fa60b 100644
--- a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
@@ -67,41 +67,6 @@ namespace DotNetOpenAuth.Test.Messaging {
}
[Test]
- public void AsHttpResponseMessage() {
- var responseContent = new byte[10];
- (new Random()).NextBytes(responseContent);
- var responseStream = new MemoryStream(responseContent);
- var outgoingResponse = new OutgoingWebResponse();
- outgoingResponse.Headers.Add("X-SOME-HEADER", "value");
- outgoingResponse.Headers.Add("Content-Length", responseContent.Length.ToString(CultureInfo.InvariantCulture));
- outgoingResponse.ResponseStream = responseStream;
-
- var httpResponseMessage = outgoingResponse.AsHttpResponseMessage();
- Assert.That(httpResponseMessage, Is.Not.Null);
- Assert.That(httpResponseMessage.Headers.GetValues("X-SOME-HEADER").ToList(), Is.EqualTo(new[] { "value" }));
- Assert.That(
- httpResponseMessage.Content.Headers.GetValues("Content-Length").ToList(),
- Is.EqualTo(new[] { responseContent.Length.ToString(CultureInfo.InvariantCulture) }));
- var actualContent = new byte[responseContent.Length + 1]; // give the opportunity to provide a bit more data than we expect.
- var bytesRead = httpResponseMessage.Content.ReadAsStreamAsync().Result.Read(actualContent, 0, actualContent.Length);
- Assert.That(bytesRead, Is.EqualTo(responseContent.Length)); // verify that only the data we expected came back.
- var trimmedActualContent = new byte[bytesRead];
- Array.Copy(actualContent, trimmedActualContent, bytesRead);
- Assert.That(trimmedActualContent, Is.EqualTo(responseContent));
- }
-
- [Test]
- public void AsHttpResponseMessageNoContent() {
- var outgoingResponse = new OutgoingWebResponse();
- outgoingResponse.Headers.Add("X-SOME-HEADER", "value");
-
- var httpResponseMessage = outgoingResponse.AsHttpResponseMessage();
- Assert.That(httpResponseMessage, Is.Not.Null);
- Assert.That(httpResponseMessage.Headers.GetValues("X-SOME-HEADER").ToList(), Is.EqualTo(new[] { "value" }));
- Assert.That(httpResponseMessage.Content, Is.Null);
- }
-
- [Test]
public void ToDictionary() {
NameValueCollection nvc = new NameValueCollection();
nvc["a"] = "b";
@@ -178,35 +143,6 @@ namespace DotNetOpenAuth.Test.Messaging {
}
/// <summary>
- /// Verifies the overall format of the multipart POST is correct.
- /// </summary>
- [Test]
- public void PostMultipart() {
- var httpHandler = new TestWebRequestHandler();
- bool callbackTriggered = false;
- httpHandler.Callback = req => {
- var m = Regex.Match(req.ContentType, "multipart/form-data; boundary=(.+)");
- Assert.IsTrue(m.Success, "Content-Type HTTP header not set correctly.");
- string boundary = m.Groups[1].Value;
- boundary = boundary.Substring(0, boundary.IndexOf(';')); // trim off charset
- string expectedEntity = "--{0}\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\nb\r\n--{0}--\r\n";
- expectedEntity = string.Format(expectedEntity, boundary);
- string actualEntity = httpHandler.RequestEntityAsString;
- Assert.AreEqual(expectedEntity, actualEntity);
- callbackTriggered = true;
- Assert.AreEqual(req.ContentLength, actualEntity.Length);
- IncomingWebResponse resp = new CachedDirectWebResponse();
- return resp;
- };
- var request = (HttpWebRequest)WebRequest.Create("http://someserver");
- var parts = new[] {
- MultipartPostPart.CreateFormPart("a", "b"),
- };
- request.PostMultipart(httpHandler, parts);
- Assert.IsTrue(callbackTriggered);
- }
-
- /// <summary>
/// Verifies proper behavior of GetHttpVerb
/// </summary>
[Test]
@@ -215,16 +151,16 @@ namespace DotNetOpenAuth.Test.Messaging {
Assert.AreEqual("POST", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PostRequest));
Assert.AreEqual("HEAD", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.HeadRequest));
Assert.AreEqual("DELETE", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.DeleteRequest));
- Assert.AreEqual("PUT", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PutRequest));
- Assert.AreEqual("PATCH", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PatchRequest));
+ Assert.AreEqual("PUT", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PutRequest));
+ Assert.AreEqual("PATCH", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PatchRequest));
Assert.AreEqual("OPTIONS", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.OptionsRequest));
Assert.AreEqual("GET", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
Assert.AreEqual("POST", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
Assert.AreEqual("HEAD", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.HeadRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
Assert.AreEqual("DELETE", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.DeleteRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
- Assert.AreEqual("PUT", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PutRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
- Assert.AreEqual("PATCH", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PatchRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
+ Assert.AreEqual("PUT", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PutRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
+ Assert.AreEqual("PATCH", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.PatchRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
Assert.AreEqual("OPTIONS", MessagingUtilities.GetHttpVerb(HttpDeliveryMethods.OptionsRequest | HttpDeliveryMethods.AuthorizationHeaderRequest));
}
@@ -245,8 +181,8 @@ namespace DotNetOpenAuth.Test.Messaging {
Assert.AreEqual(HttpDeliveryMethods.PostRequest, MessagingUtilities.GetHttpDeliveryMethod("POST"));
Assert.AreEqual(HttpDeliveryMethods.HeadRequest, MessagingUtilities.GetHttpDeliveryMethod("HEAD"));
Assert.AreEqual(HttpDeliveryMethods.PutRequest, MessagingUtilities.GetHttpDeliveryMethod("PUT"));
- Assert.AreEqual(HttpDeliveryMethods.DeleteRequest, MessagingUtilities.GetHttpDeliveryMethod("DELETE"));
- Assert.AreEqual(HttpDeliveryMethods.PatchRequest, MessagingUtilities.GetHttpDeliveryMethod("PATCH"));
+ Assert.AreEqual(HttpDeliveryMethods.DeleteRequest, MessagingUtilities.GetHttpDeliveryMethod("DELETE"));
+ Assert.AreEqual(HttpDeliveryMethods.PatchRequest, MessagingUtilities.GetHttpDeliveryMethod("PATCH"));
Assert.AreEqual(HttpDeliveryMethods.OptionsRequest, MessagingUtilities.GetHttpDeliveryMethod("OPTIONS"));
}
diff --git a/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs b/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs
deleted file mode 100644
index e9ac5aa..0000000
--- a/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="MultipartPostPartTests.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Messaging {
- using System.CodeDom.Compiler;
- using System.Collections.Generic;
- using System.IO;
- using System.Net;
- using DotNetOpenAuth.Messaging;
- using NUnit.Framework;
- using Validation;
-
- [TestFixture]
- public class MultipartPostPartTests : TestBase {
- /// <summary>
- /// Verifies that the Length property matches the length actually serialized.
- /// </summary>
- [Test]
- public void FormDataSerializeMatchesLength() {
- var part = MultipartPostPart.CreateFormPart("a", "b");
- VerifyLength(part);
- }
-
- /// <summary>
- /// Verifies that the length property matches the length actually serialized.
- /// </summary>
- [Test]
- public void FileSerializeMatchesLength() {
- using (TempFileCollection tfc = new TempFileCollection()) {
- string file = tfc.AddExtension(".txt");
- File.WriteAllText(file, "sometext");
- var part = MultipartPostPart.CreateFormFilePart("someformname", file, "text/plain");
- VerifyLength(part);
- }
- }
-
- /// <summary>
- /// Verifies file multiparts identify themselves as files and not merely form-data.
- /// </summary>
- [Test]
- public void FilePartAsFile() {
- var part = MultipartPostPart.CreateFormFilePart("somename", "somefile", "plain/text", new MemoryStream());
- Assert.AreEqual("file", part.ContentDisposition);
- }
-
- /// <summary>
- /// Verifies MultiPartPost sends the right number of bytes.
- /// </summary>
- [Test]
- public void MultiPartPostAscii() {
- using (TempFileCollection tfc = new TempFileCollection()) {
- string file = tfc.AddExtension("txt");
- File.WriteAllText(file, "sometext");
- this.VerifyFullPost(new List<MultipartPostPart> {
- MultipartPostPart.CreateFormPart("a", "b"),
- MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"),
- });
- }
- }
-
- /// <summary>
- /// Verifies MultiPartPost sends the right number of bytes.
- /// </summary>
- [Test]
- public void MultiPartPostMultiByteCharacters() {
- using (TempFileCollection tfc = new TempFileCollection()) {
- string file = tfc.AddExtension("txt");
- File.WriteAllText(file, "\x1020\x818");
- this.VerifyFullPost(new List<MultipartPostPart> {
- MultipartPostPart.CreateFormPart("a", "\x987"),
- MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"),
- });
- }
- }
-
- private static void VerifyLength(MultipartPostPart part) {
- Requires.NotNull(part, "part");
-
- var expectedLength = part.Length;
- var ms = new MemoryStream();
- var sw = new StreamWriter(ms);
- part.Serialize(sw);
- sw.Flush();
- var actualLength = ms.Length;
- Assert.AreEqual(expectedLength, actualLength);
- }
-
- private void VerifyFullPost(List<MultipartPostPart> parts) {
- var request = (HttpWebRequest)WebRequest.Create("http://localhost");
- var handler = new Mocks.TestWebRequestHandler();
- bool posted = false;
- handler.Callback = req => {
- foreach (string header in req.Headers) {
- TestUtilities.TestLogger.InfoFormat("{0}: {1}", header, req.Headers[header]);
- }
- TestUtilities.TestLogger.InfoFormat(handler.RequestEntityAsString);
- Assert.AreEqual(req.ContentLength, handler.RequestEntityStream.Length);
- posted = true;
- return null;
- };
- request.PostMultipart(handler, parts);
- Assert.IsTrue(posted, "HTTP POST never sent.");
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs b/src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs
deleted file mode 100644
index 52f031e..0000000
--- a/src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="ResponseTests.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Messaging {
- using System;
- using System.IO;
- using System.Web;
- using DotNetOpenAuth.Messaging;
- using NUnit.Framework;
-
- [TestFixture]
- public class ResponseTests : TestBase {
- [Test, ExpectedException(typeof(InvalidOperationException))]
- public void RespondWithoutAspNetContext() {
- HttpContext.Current = null;
- new OutgoingWebResponse().Respond();
- }
-
- [Test]
- public void Respond() {
- StringWriter writer = new StringWriter();
- HttpRequest httpRequest = new HttpRequest("file", "http://server", string.Empty);
- HttpResponse httpResponse = new HttpResponse(writer);
- HttpContext context = new HttpContext(httpRequest, httpResponse);
- HttpContext.Current = context;
-
- OutgoingWebResponse response = new OutgoingWebResponse();
- response.Status = System.Net.HttpStatusCode.OK;
- response.Headers["someHeaderName"] = "someHeaderValue";
- response.Body = "some body";
- response.Respond();
- string results = writer.ToString();
- // For some reason the only output in test is the body... the headers require a web host
- Assert.AreEqual(response.Body, results);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs
deleted file mode 100644
index 475f4b5..0000000
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs
+++ /dev/null
@@ -1,348 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CoordinatingChannel.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Mocks {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Text;
- using System.Threading;
- using System.Web;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Reflection;
- using DotNetOpenAuth.Test.OpenId;
- using NUnit.Framework;
- using Validation;
-
- internal class CoordinatingChannel : Channel {
- /// <summary>
- /// A lock to use when checking and setting the <see cref="waitingForMessage"/>
- /// or the <see cref="simulationCompleted"/> fields.
- /// </summary>
- /// <remarks>
- /// This is a static member so that all coordinating channels share a lock
- /// since they peak at each others fields.
- /// </remarks>
- private static readonly object waitingForMessageCoordinationLock = new object();
-
- /// <summary>
- /// The original product channel whose behavior is being modified to work
- /// better in automated testing.
- /// </summary>
- private Channel wrappedChannel;
-
- /// <summary>
- /// A flag set to true when this party in a two-party test has completed
- /// its part of the testing.
- /// </summary>
- private bool simulationCompleted;
-
- /// <summary>
- /// A thread-coordinating signal that is set when another thread has a
- /// message ready for this channel to receive.
- /// </summary>
- private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false);
-
- /// <summary>
- /// A thread-coordinating signal that is set briefly by this thread whenever
- /// a message is picked up.
- /// </summary>
- private EventWaitHandle messageReceivedSignal = new AutoResetEvent(false);
-
- /// <summary>
- /// A flag used to indicate when this channel is waiting for a message
- /// to arrive.
- /// </summary>
- private bool waitingForMessage;
-
- /// <summary>
- /// An incoming message that has been posted by a remote channel and
- /// is waiting for receipt by this channel.
- /// </summary>
- private IDictionary<string, string> incomingMessage;
-
- /// <summary>
- /// The recipient URL of the <see cref="incomingMessage"/>, where applicable.
- /// </summary>
- private MessageReceivingEndpoint incomingMessageRecipient;
-
- /// <summary>
- /// The headers of the <see cref="incomingMessage"/>, where applicable.
- /// </summary>
- private WebHeaderCollection incomingMessageHttpHeaders;
-
- /// <summary>
- /// A delegate that gets a chance to peak at and fiddle with all
- /// incoming messages.
- /// </summary>
- private Action<IProtocolMessage> incomingMessageFilter;
-
- /// <summary>
- /// A delegate that gets a chance to peak at and fiddle with all
- /// outgoing messages.
- /// </summary>
- private Action<IProtocolMessage> outgoingMessageFilter;
-
- /// <summary>
- /// The simulated clients cookies.
- /// </summary>
- private HttpCookieCollection cookies = new HttpCookieCollection();
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingChannel"/> class.
- /// </summary>
- /// <param name="wrappedChannel">The wrapped channel. Must not be null.</param>
- /// <param name="incomingMessageFilter">The incoming message filter. May be null.</param>
- /// <param name="outgoingMessageFilter">The outgoing message filter. May be null.</param>
- internal CoordinatingChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter)
- : base(GetMessageFactory(wrappedChannel), wrappedChannel.BindingElements.ToArray()) {
- Requires.NotNull(wrappedChannel, "wrappedChannel");
-
- this.wrappedChannel = wrappedChannel;
- this.incomingMessageFilter = incomingMessageFilter;
- this.outgoingMessageFilter = outgoingMessageFilter;
-
- // Preserve any customized binding element ordering.
- this.CustomizeBindingElementOrder(this.wrappedChannel.OutgoingBindingElements, this.wrappedChannel.IncomingBindingElements);
- }
-
- /// <summary>
- /// Gets or sets the coordinating channel used by the other party.
- /// </summary>
- internal CoordinatingChannel RemoteChannel { get; set; }
-
- /// <summary>
- /// Indicates that the simulation that uses this channel has completed work.
- /// </summary>
- /// <remarks>
- /// Calling this method is not strictly necessary, but it gives the channel
- /// coordination a chance to recognize when another channel is left dangling
- /// waiting for a message from another channel that may never come.
- /// </remarks>
- internal void Close() {
- lock (waitingForMessageCoordinationLock) {
- this.simulationCompleted = true;
- if (this.RemoteChannel.waitingForMessage && this.RemoteChannel.incomingMessage == null) {
- TestUtilities.TestLogger.Debug("CoordinatingChannel is closing while remote channel is waiting for an incoming message. Signaling channel to unblock it to receive a null message.");
- this.RemoteChannel.incomingMessageSignal.Set();
- }
-
- this.Dispose();
- }
- }
-
- /// <summary>
- /// Replays the specified message as if it were received again.
- /// </summary>
- /// <param name="message">The message to replay.</param>
- internal void Replay(IProtocolMessage message) {
- this.ProcessIncomingMessage(this.CloneSerializedParts(message));
- }
-
- /// <summary>
- /// Called from a remote party's thread to post a message to this channel for processing.
- /// </summary>
- /// <param name="message">The message that this channel should receive. This message will be cloned.</param>
- internal void PostMessage(IProtocolMessage message) {
- if (this.incomingMessage != null) {
- // The remote party hasn't picked up the last message we sent them.
- // Wait for a short period for them to pick it up before failing.
- TestBase.TestLogger.Warn("We're blocked waiting to send a message to the remote party and they haven't processed the last message we sent them.");
- this.RemoteChannel.messageReceivedSignal.WaitOne(500);
- }
- ErrorUtilities.VerifyInternal(this.incomingMessage == null, "Oops, a message is already waiting for the remote party!");
- this.incomingMessage = this.MessageDescriptions.GetAccessor(message).Serialize();
- var directedMessage = message as IDirectedProtocolMessage;
- this.incomingMessageRecipient = (directedMessage != null && directedMessage.Recipient != null) ? new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods) : null;
- var httpMessage = message as IHttpDirectRequest;
- this.incomingMessageHttpHeaders = (httpMessage != null) ? httpMessage.Headers.Clone() : null;
- this.incomingMessageSignal.Set();
- }
-
- internal void SaveCookies(HttpCookieCollection cookies) {
- Requires.NotNull(cookies, "cookies");
- foreach (string cookieName in cookies) {
- var cookie = cookies[cookieName];
- this.cookies.Set(cookie);
- }
- }
-
- protected internal override HttpRequestBase GetRequestFromContext() {
- MessageReceivingEndpoint recipient;
- WebHeaderCollection headers;
- var messageData = this.AwaitIncomingMessage(out recipient, out headers);
- CoordinatingHttpRequestInfo result;
- if (messageData != null) {
- result = new CoordinatingHttpRequestInfo(this, this.MessageFactory, messageData, recipient, this.cookies);
- } else {
- result = new CoordinatingHttpRequestInfo(recipient, this.cookies);
- }
-
- if (headers != null) {
- headers.ApplyTo(result.Headers);
- }
-
- return result;
- }
-
- protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request) {
- this.ProcessMessageFilter(request, true);
-
- // Drop the outgoing message in the other channel's in-slot and let them know it's there.
- this.RemoteChannel.PostMessage(request);
-
- // Now wait for a response...
- MessageReceivingEndpoint recipient;
- WebHeaderCollection headers;
- IDictionary<string, string> responseData = this.AwaitIncomingMessage(out recipient, out headers);
- ErrorUtilities.VerifyInternal(recipient == null, "The recipient is expected to be null for direct responses.");
-
- // And deserialize it.
- IDirectResponseProtocolMessage responseMessage = this.MessageFactory.GetNewResponseMessage(request, responseData);
- if (responseMessage == null) {
- return null;
- }
-
- var responseAccessor = this.MessageDescriptions.GetAccessor(responseMessage);
- responseAccessor.Deserialize(responseData);
- var responseMessageHttpRequest = responseMessage as IHttpDirectRequest;
- if (headers != null && responseMessageHttpRequest != null) {
- headers.ApplyTo(responseMessageHttpRequest.Headers);
- }
-
- this.ProcessMessageFilter(responseMessage, false);
- return responseMessage;
- }
-
- protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
- this.ProcessMessageFilter(response, true);
- return new CoordinatingOutgoingWebResponse(response, this.RemoteChannel, this);
- }
-
- protected override OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) {
- this.ProcessMessageFilter(message, true);
- // In this mock transport, direct and indirect messages are the same.
- return this.PrepareDirectResponse(message);
- }
-
- protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestBase request) {
- var mockRequest = (CoordinatingHttpRequestInfo)request;
- if (mockRequest.Message != null) {
- this.ProcessMessageFilter(mockRequest.Message, false);
- }
-
- return mockRequest.Message;
- }
-
- protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) {
- return this.wrappedChannel.ReadFromResponseCoreTestHook(response);
- }
-
- protected override void ProcessIncomingMessage(IProtocolMessage message) {
- this.wrappedChannel.ProcessIncomingMessageTestHook(message);
- }
-
- /// <summary>
- /// Clones a message, instantiating the new instance using <i>this</i> channel's
- /// message factory.
- /// </summary>
- /// <typeparam name="T">The type of message to clone.</typeparam>
- /// <param name="message">The message to clone.</param>
- /// <returns>The new instance of the message.</returns>
- /// <remarks>
- /// This Clone method should <i>not</i> be used to send message clones to the remote
- /// channel since their message factory is not used.
- /// </remarks>
- protected virtual T CloneSerializedParts<T>(T message) where T : class, IProtocolMessage {
- Requires.NotNull(message, "message");
-
- IProtocolMessage clonedMessage;
- var messageAccessor = this.MessageDescriptions.GetAccessor(message);
- var fields = messageAccessor.Serialize();
-
- MessageReceivingEndpoint recipient = null;
- var directedMessage = message as IDirectedProtocolMessage;
- var directResponse = message as IDirectResponseProtocolMessage;
- if (directedMessage != null && directedMessage.IsRequest()) {
- if (directedMessage.Recipient != null) {
- recipient = new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods);
- }
-
- clonedMessage = this.MessageFactory.GetNewRequestMessage(recipient, fields);
- } else if (directResponse != null && directResponse.IsDirectResponse()) {
- clonedMessage = this.MessageFactory.GetNewResponseMessage(directResponse.OriginatingRequest, fields);
- } else {
- throw new InvalidOperationException("Totally expected a message to implement one of the two derived interface types.");
- }
-
- ErrorUtilities.VerifyInternal(clonedMessage != null, "Message factory did not generate a message instance for " + message.GetType().Name);
-
- // Fill the cloned message with data.
- var clonedMessageAccessor = this.MessageDescriptions.GetAccessor(clonedMessage);
- clonedMessageAccessor.Deserialize(fields);
-
- return (T)clonedMessage;
- }
-
- private static IMessageFactory GetMessageFactory(Channel channel) {
- Requires.NotNull(channel, "channel");
-
- return channel.MessageFactoryTestHook;
- }
-
- private IDictionary<string, string> AwaitIncomingMessage(out MessageReceivingEndpoint recipient, out WebHeaderCollection headers) {
- // Special care should be taken so that we don't indefinitely
- // wait for a message that may never come due to a bug in the product
- // or the test.
- // There are two scenarios that we need to watch out for:
- // 1. Two channels are waiting to receive messages from each other.
- // 2. One channel is waiting for a message that will never come because
- // the remote party has already finished executing.
- lock (waitingForMessageCoordinationLock) {
- // It's possible that a message was just barely transmitted either to this
- // or the remote channel. So it's ok for the remote channel to be waiting
- // if either it or we are already about to receive a message.
- ErrorUtilities.VerifyInternal(!this.RemoteChannel.waitingForMessage || this.RemoteChannel.incomingMessage != null || this.incomingMessage != null, "This channel is expecting an incoming message from another channel that is also blocked waiting for an incoming message from us!");
-
- // It's permissible that the remote channel has already closed if it left a message
- // for us already.
- ErrorUtilities.VerifyInternal(!this.RemoteChannel.simulationCompleted || this.incomingMessage != null, "This channel is expecting an incoming message from another channel that has already been closed.");
- this.waitingForMessage = true;
- }
-
- this.incomingMessageSignal.WaitOne();
-
- lock (waitingForMessageCoordinationLock) {
- this.waitingForMessage = false;
- var response = this.incomingMessage;
- recipient = this.incomingMessageRecipient;
- headers = this.incomingMessageHttpHeaders;
- this.incomingMessage = null;
- this.incomingMessageRecipient = null;
- this.incomingMessageHttpHeaders = null;
-
- // Briefly signal to another thread that might be waiting for our inbox to be empty
- this.messageReceivedSignal.Set();
- this.messageReceivedSignal.Reset();
-
- return response;
- }
- }
-
- private void ProcessMessageFilter(IProtocolMessage message, bool outgoing) {
- if (outgoing) {
- if (this.outgoingMessageFilter != null) {
- this.outgoingMessageFilter(message);
- }
- } else {
- if (this.incomingMessageFilter != null) {
- this.incomingMessageFilter(message);
- }
- }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingHttpRequestInfo.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingHttpRequestInfo.cs
deleted file mode 100644
index 497503c..0000000
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingHttpRequestInfo.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CoordinatingHttpRequestInfo.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Mocks {
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Web;
-
- using DotNetOpenAuth.Messaging;
- using Validation;
-
- internal class CoordinatingHttpRequestInfo : HttpRequestInfo {
- private readonly Channel channel;
-
- private readonly IDictionary<string, string> messageData;
-
- private readonly IMessageFactory messageFactory;
-
- private readonly MessageReceivingEndpoint recipient;
-
- private IDirectedProtocolMessage message;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingHttpRequestInfo"/> class
- /// that will generate a message when the <see cref="Message"/> property getter is called.
- /// </summary>
- /// <param name="channel">The channel.</param>
- /// <param name="messageFactory">The message factory.</param>
- /// <param name="messageData">The message data.</param>
- /// <param name="recipient">The recipient.</param>
- /// <param name="cookies">Cookies included in the incoming request.</param>
- internal CoordinatingHttpRequestInfo(
- Channel channel,
- IMessageFactory messageFactory,
- IDictionary<string, string> messageData,
- MessageReceivingEndpoint recipient,
- HttpCookieCollection cookies)
- : this(recipient, cookies) {
- Requires.NotNull(channel, "channel");
- Requires.NotNull(messageFactory, "messageFactory");
- Requires.NotNull(messageData, "messageData");
- this.channel = channel;
- this.messageData = messageData;
- this.messageFactory = messageFactory;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingHttpRequestInfo"/> class
- /// that will not generate any message.
- /// </summary>
- /// <param name="recipient">The recipient.</param>
- /// <param name="cookies">Cookies included in the incoming request.</param>
- internal CoordinatingHttpRequestInfo(MessageReceivingEndpoint recipient, HttpCookieCollection cookies)
- : base(GetHttpVerb(recipient), recipient != null ? recipient.Location : new Uri("http://host/path"), cookies: cookies) {
- this.recipient = recipient;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingHttpRequestInfo"/> class.
- /// </summary>
- /// <param name="message">The message being passed in through a mock transport. May be null.</param>
- /// <param name="httpMethod">The HTTP method that the incoming request came in on, whether or not <paramref name="message"/> is null.</param>
- internal CoordinatingHttpRequestInfo(IDirectedProtocolMessage message, HttpDeliveryMethods httpMethod)
- : base(GetHttpVerb(httpMethod), message.Recipient) {
- this.message = message;
- }
-
- /// <summary>
- /// Gets the message deserialized from the remote channel.
- /// </summary>
- internal IDirectedProtocolMessage Message {
- get {
- if (this.message == null && this.messageData != null) {
- var message = this.messageFactory.GetNewRequestMessage(this.recipient, this.messageData);
- if (message != null) {
- this.channel.MessageDescriptions.GetAccessor(message).Deserialize(this.messageData);
- this.message = message;
- }
- }
-
- return this.message;
- }
- }
-
- private static string GetHttpVerb(MessageReceivingEndpoint recipient) {
- if (recipient == null) {
- return "GET";
- }
-
- return GetHttpVerb(recipient.AllowedMethods);
- }
-
- private static string GetHttpVerb(HttpDeliveryMethods httpMethod) {
- if ((httpMethod & HttpDeliveryMethods.GetRequest) != 0) {
- return "GET";
- }
-
- if ((httpMethod & HttpDeliveryMethods.PostRequest) != 0) {
- return "POST";
- }
-
- throw new ArgumentOutOfRangeException();
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2AuthServerChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2AuthServerChannel.cs
deleted file mode 100644
index 463b149..0000000
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2AuthServerChannel.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CoordinatingOAuth2AuthServerChannel.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Mocks {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth2;
- using DotNetOpenAuth.OAuth2.ChannelElements;
-
- internal class CoordinatingOAuth2AuthServerChannel : CoordinatingChannel, IOAuth2ChannelWithAuthorizationServer {
- private OAuth2AuthorizationServerChannel wrappedChannel;
-
- internal CoordinatingOAuth2AuthServerChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter)
- : base(wrappedChannel, incomingMessageFilter, outgoingMessageFilter) {
- this.wrappedChannel = (OAuth2AuthorizationServerChannel)wrappedChannel;
- }
-
- public IAuthorizationServerHost AuthorizationServer {
- get { return this.wrappedChannel.AuthorizationServer; }
- }
-
- public IScopeSatisfiedCheck ScopeSatisfiedCheck {
- get { return this.wrappedChannel.ScopeSatisfiedCheck; }
- set { this.wrappedChannel.ScopeSatisfiedCheck = value; }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs
deleted file mode 100644
index 96091ac..0000000
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CoordinatingOAuth2ClientChannel.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Mocks {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth2.ChannelElements;
-
- internal class CoordinatingOAuth2ClientChannel : CoordinatingChannel, IOAuth2ChannelWithClient {
- private OAuth2ClientChannel wrappedChannel;
-
- internal CoordinatingOAuth2ClientChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter)
- : base(wrappedChannel, incomingMessageFilter, outgoingMessageFilter) {
- this.wrappedChannel = (OAuth2ClientChannel)wrappedChannel;
- }
-
- public string ClientIdentifier {
- get { return this.wrappedChannel.ClientIdentifier; }
- set { this.wrappedChannel.ClientIdentifier = value; }
- }
-
- public DotNetOpenAuth.OAuth2.ClientCredentialApplicator ClientCredentialApplicator {
- get { return this.wrappedChannel.ClientCredentialApplicator; }
- set { this.wrappedChannel.ClientCredentialApplicator = value; }
- }
-
- public System.Xml.XmlDictionaryReaderQuotas JsonReaderQuotas {
- get { return this.XmlDictionaryReaderQuotas; }
- }
- }
-} \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs
deleted file mode 100644
index 9b552d3..0000000
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CoordinatingOAuthConsumerChannel.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Mocks {
- using System;
- using System.Threading;
- using System.Web;
-
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.OAuth.ChannelElements;
- using DotNetOpenAuth.OAuth.Messages;
- using Validation;
-
- /// <summary>
- /// A special channel used in test simulations to pass messages directly between two parties.
- /// </summary>
- internal class CoordinatingOAuthConsumerChannel : OAuthConsumerChannel {
- private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false);
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingOAuthConsumerChannel"/> class.
- /// </summary>
- /// <param name="signingBindingElement">The signing element for the Consumer to use. Null for the Service Provider.</param>
- /// <param name="tokenManager">The token manager to use.</param>
- /// <param name="securitySettings">The security settings.</param>
- internal CoordinatingOAuthConsumerChannel(ITamperProtectionChannelBindingElement signingBindingElement, IConsumerTokenManager tokenManager, DotNetOpenAuth.OAuth.ConsumerSecuritySettings securitySettings)
- : base(
- signingBindingElement,
- new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge),
- tokenManager,
- securitySettings) {
- }
-
- internal EventWaitHandle IncomingMessageSignal {
- get { return this.incomingMessageSignal; }
- }
-
- internal IProtocolMessage IncomingMessage { get; set; }
-
- internal OutgoingWebResponse IncomingRawResponse { get; set; }
-
- /// <summary>
- /// Gets or sets the coordinating channel used by the other party.
- /// </summary>
- internal CoordinatingOAuthServiceProviderChannel RemoteChannel { get; set; }
-
- internal OutgoingWebResponse RequestProtectedResource(AccessProtectedResourceRequest request) {
- ((ITamperResistantOAuthMessage)request).HttpMethod = this.GetHttpMethod(((ITamperResistantOAuthMessage)request).HttpMethods);
- this.ProcessOutgoingMessage(request);
- var requestInfo = this.SpoofHttpMethod(request);
- TestBase.TestLogger.InfoFormat("Sending protected resource request: {0}", requestInfo.Message);
- // Drop the outgoing message in the other channel's in-slot and let them know it's there.
- this.RemoteChannel.IncomingMessage = requestInfo.Message;
- this.RemoteChannel.IncomingMessageSignal.Set();
- return this.AwaitIncomingRawResponse();
- }
-
- protected internal override HttpRequestBase GetRequestFromContext() {
- var directedMessage = (IDirectedProtocolMessage)this.AwaitIncomingMessage();
- return new CoordinatingHttpRequestInfo(directedMessage, directedMessage.HttpMethods);
- }
-
- protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request) {
- var requestInfo = this.SpoofHttpMethod(request);
- // Drop the outgoing message in the other channel's in-slot and let them know it's there.
- this.RemoteChannel.IncomingMessage = requestInfo.Message;
- this.RemoteChannel.IncomingMessageSignal.Set();
- // Now wait for a response...
- return this.AwaitIncomingMessage();
- }
-
- protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
- this.RemoteChannel.IncomingMessage = this.CloneSerializedParts(response);
- this.RemoteChannel.IncomingMessageSignal.Set();
- return new OutgoingWebResponse(); // not used, but returning null is not allowed
- }
-
- protected override OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) {
- // In this mock transport, direct and indirect messages are the same.
- return this.PrepareDirectResponse(message);
- }
-
- protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestBase request) {
- var mockRequest = (CoordinatingHttpRequestInfo)request;
- return mockRequest.Message;
- }
-
- /// <summary>
- /// Spoof HTTP request information for signing/verification purposes.
- /// </summary>
- /// <param name="message">The message to add a pretend HTTP method to.</param>
- /// <returns>A spoofed HttpRequestInfo that wraps the new message.</returns>
- private CoordinatingHttpRequestInfo SpoofHttpMethod(IDirectedProtocolMessage message) {
- var signedMessage = message as ITamperResistantOAuthMessage;
- if (signedMessage != null) {
- string httpMethod = this.GetHttpMethod(signedMessage.HttpMethods);
- signedMessage.HttpMethod = httpMethod;
- }
-
- var requestInfo = new CoordinatingHttpRequestInfo(this.CloneSerializedParts(message), message.HttpMethods);
- return requestInfo;
- }
-
- private IProtocolMessage AwaitIncomingMessage() {
- this.incomingMessageSignal.WaitOne();
- IProtocolMessage response = this.IncomingMessage;
- this.IncomingMessage = null;
- return response;
- }
-
- private OutgoingWebResponse AwaitIncomingRawResponse() {
- this.incomingMessageSignal.WaitOne();
- OutgoingWebResponse response = this.IncomingRawResponse;
- this.IncomingRawResponse = null;
- return response;
- }
-
- private T CloneSerializedParts<T>(T message) where T : class, IProtocolMessage {
- Requires.NotNull(message, "message");
-
- IProtocolMessage clonedMessage;
- var messageAccessor = this.MessageDescriptions.GetAccessor(message);
- var fields = messageAccessor.Serialize();
-
- MessageReceivingEndpoint recipient = null;
- var directedMessage = message as IDirectedProtocolMessage;
- var directResponse = message as IDirectResponseProtocolMessage;
- if (directedMessage != null && directedMessage.IsRequest()) {
- if (directedMessage.Recipient != null) {
- recipient = new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods);
- }
-
- clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewRequestMessage(recipient, fields);
- } else if (directResponse != null && directResponse.IsDirectResponse()) {
- clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewResponseMessage(directResponse.OriginatingRequest, fields);
- } else {
- throw new InvalidOperationException("Totally expected a message to implement one of the two derived interface types.");
- }
-
- // Fill the cloned message with data.
- var clonedMessageAccessor = this.MessageDescriptions.GetAccessor(clonedMessage);
- clonedMessageAccessor.Deserialize(fields);
-
- return (T)clonedMessage;
- }
-
- private string GetHttpMethod(HttpDeliveryMethods methods) {
- return (methods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET";
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
deleted file mode 100644
index a6f2a7f..0000000
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CoordinatingOAuthServiceProviderChannel.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Mocks {
- using System;
- using System.Threading;
- using System.Web;
-
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.OAuth.ChannelElements;
- using DotNetOpenAuth.OAuth.Messages;
- using NUnit.Framework;
- using Validation;
-
- /// <summary>
- /// A special channel used in test simulations to pass messages directly between two parties.
- /// </summary>
- internal class CoordinatingOAuthServiceProviderChannel : OAuthServiceProviderChannel {
- private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false);
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingOAuthServiceProviderChannel"/> class.
- /// </summary>
- /// <param name="signingBindingElement">The signing element for the Consumer to use. Null for the Service Provider.</param>
- /// <param name="tokenManager">The token manager to use.</param>
- /// <param name="securitySettings">The security settings.</param>
- internal CoordinatingOAuthServiceProviderChannel(ITamperProtectionChannelBindingElement signingBindingElement, IServiceProviderTokenManager tokenManager, DotNetOpenAuth.OAuth.ServiceProviderSecuritySettings securitySettings)
- : base(
- signingBindingElement,
- new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge),
- tokenManager,
- securitySettings,
- new OAuthServiceProviderMessageFactory(tokenManager)) {
- }
-
- internal EventWaitHandle IncomingMessageSignal {
- get { return this.incomingMessageSignal; }
- }
-
- internal IProtocolMessage IncomingMessage { get; set; }
-
- internal OutgoingWebResponse IncomingRawResponse { get; set; }
-
- /// <summary>
- /// Gets or sets the coordinating channel used by the other party.
- /// </summary>
- internal CoordinatingOAuthConsumerChannel RemoteChannel { get; set; }
-
- internal OutgoingWebResponse RequestProtectedResource(AccessProtectedResourceRequest request) {
- ((ITamperResistantOAuthMessage)request).HttpMethod = GetHttpMethod(((ITamperResistantOAuthMessage)request).HttpMethods);
- this.ProcessOutgoingMessage(request);
- var requestInfo = this.SpoofHttpMethod(request);
- TestBase.TestLogger.InfoFormat("Sending protected resource request: {0}", requestInfo.Message);
- // Drop the outgoing message in the other channel's in-slot and let them know it's there.
- this.RemoteChannel.IncomingMessage = requestInfo.Message;
- this.RemoteChannel.IncomingMessageSignal.Set();
- return this.AwaitIncomingRawResponse();
- }
-
- internal void SendDirectRawResponse(OutgoingWebResponse response) {
- this.RemoteChannel.IncomingRawResponse = response;
- this.RemoteChannel.IncomingMessageSignal.Set();
- }
-
- protected internal override HttpRequestBase GetRequestFromContext() {
- var directedMessage = (IDirectedProtocolMessage)this.AwaitIncomingMessage();
- return new CoordinatingHttpRequestInfo(directedMessage, directedMessage.HttpMethods);
- }
-
- protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request) {
- var requestInfo = this.SpoofHttpMethod(request);
- // Drop the outgoing message in the other channel's in-slot and let them know it's there.
- this.RemoteChannel.IncomingMessage = requestInfo.Message;
- this.RemoteChannel.IncomingMessageSignal.Set();
- // Now wait for a response...
- return this.AwaitIncomingMessage();
- }
-
- protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
- this.RemoteChannel.IncomingMessage = this.CloneSerializedParts(response);
- this.RemoteChannel.IncomingMessageSignal.Set();
- return new OutgoingWebResponse(); // not used, but returning null is not allowed
- }
-
- protected override OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) {
- // In this mock transport, direct and indirect messages are the same.
- return this.PrepareDirectResponse(message);
- }
-
- protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestBase request) {
- var mockRequest = (CoordinatingHttpRequestInfo)request;
- return mockRequest.Message;
- }
-
- private static string GetHttpMethod(HttpDeliveryMethods methods) {
- return (methods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET";
- }
-
- /// <summary>
- /// Spoof HTTP request information for signing/verification purposes.
- /// </summary>
- /// <param name="message">The message to add a pretend HTTP method to.</param>
- /// <returns>A spoofed HttpRequestInfo that wraps the new message.</returns>
- private CoordinatingHttpRequestInfo SpoofHttpMethod(IDirectedProtocolMessage message) {
- var signedMessage = message as ITamperResistantOAuthMessage;
- if (signedMessage != null) {
- string httpMethod = GetHttpMethod(signedMessage.HttpMethods);
- signedMessage.HttpMethod = httpMethod;
- }
-
- var requestInfo = new CoordinatingHttpRequestInfo(this.CloneSerializedParts(message), message.HttpMethods);
- return requestInfo;
- }
-
- private IProtocolMessage AwaitIncomingMessage() {
- this.IncomingMessageSignal.WaitOne();
- Assert.That(this.IncomingMessage, Is.Not.Null, "Incoming message signaled, but none supplied.");
- IProtocolMessage response = this.IncomingMessage;
- this.IncomingMessage = null;
- return response;
- }
-
- private OutgoingWebResponse AwaitIncomingRawResponse() {
- this.IncomingMessageSignal.WaitOne();
- OutgoingWebResponse response = this.IncomingRawResponse;
- this.IncomingRawResponse = null;
- return response;
- }
-
- private T CloneSerializedParts<T>(T message) where T : class, IProtocolMessage {
- Requires.NotNull(message, "message");
-
- IProtocolMessage clonedMessage;
- var messageAccessor = this.MessageDescriptions.GetAccessor(message);
- var fields = messageAccessor.Serialize();
-
- MessageReceivingEndpoint recipient = null;
- var directedMessage = message as IDirectedProtocolMessage;
- var directResponse = message as IDirectResponseProtocolMessage;
- if (directedMessage != null && directedMessage.IsRequest()) {
- if (directedMessage.Recipient != null) {
- recipient = new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods);
- }
-
- clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewRequestMessage(recipient, fields);
- } else if (directResponse != null && directResponse.IsDirectResponse()) {
- clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewResponseMessage(directResponse.OriginatingRequest, fields);
- } else {
- throw new InvalidOperationException("Totally expected a message to implement one of the two derived interface types.");
- }
-
- // Fill the cloned message with data.
- var clonedMessageAccessor = this.MessageDescriptions.GetAccessor(clonedMessage);
- clonedMessageAccessor.Deserialize(fields);
-
- return (T)clonedMessage;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs
deleted file mode 100644
index 9df791c..0000000
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CoordinatingOutgoingWebResponse.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Mocks {
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using Validation;
-
- internal class CoordinatingOutgoingWebResponse : OutgoingWebResponse {
- private CoordinatingChannel receivingChannel;
-
- private CoordinatingChannel sendingChannel;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingOutgoingWebResponse"/> class.
- /// </summary>
- /// <param name="message">The direct response message to send to the remote channel. This message will be cloned.</param>
- /// <param name="receivingChannel">The receiving channel.</param>
- /// <param name="sendingChannel">The sending channel.</param>
- internal CoordinatingOutgoingWebResponse(IProtocolMessage message, CoordinatingChannel receivingChannel, CoordinatingChannel sendingChannel) {
- Requires.NotNull(message, "message");
- Requires.NotNull(receivingChannel, "receivingChannel");
- Requires.NotNull(sendingChannel, "sendingChannel");
-
- this.receivingChannel = receivingChannel;
- this.sendingChannel = sendingChannel;
- this.OriginalMessage = message;
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public override void Send() {
- this.Respond();
- }
-
- public override void Respond() {
- this.sendingChannel.SaveCookies(this.Cookies);
- this.receivingChannel.PostMessage(this.OriginalMessage);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
index 494a1c1..7fac125 100644
--- a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
@@ -14,7 +14,7 @@ namespace DotNetOpenAuth.Test.Mocks {
using DotNetOpenAuth.OAuth.Messages;
using DotNetOpenAuth.Test.OAuth;
- internal class InMemoryTokenManager : IConsumerTokenManager, IServiceProviderTokenManager {
+ internal class InMemoryTokenManager : IServiceProviderTokenManager {
private KeyedCollectionDelegate<string, ConsumerInfo> consumers = new KeyedCollectionDelegate<string, ConsumerInfo>(c => c.Key);
private KeyedCollectionDelegate<string, TokenInfo> tokens = new KeyedCollectionDelegate<string, TokenInfo>(t => t.Token);
@@ -28,18 +28,6 @@ namespace DotNetOpenAuth.Test.Mocks {
/// </summary>
private List<string> accessTokens = new List<string>();
- #region IConsumerTokenManager Members
-
- public string ConsumerKey {
- get { return this.consumers.Single().Key; }
- }
-
- public string ConsumerSecret {
- get { return this.consumers.Single().Secret; }
- }
-
- #endregion
-
#region ITokenManager Members
public string GetTokenSecret(string token) {
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs
index 0118851..3fd7517 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Test.Mocks {
using System.Collections.Generic;
using System.Linq;
using System.Text;
+ using System.Threading.Tasks;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
@@ -26,20 +27,17 @@ namespace DotNetOpenAuth.Test.Mocks {
/// Performs discovery on the specified identifier.
/// </summary>
/// <param name="identifier">The identifier to perform discovery on.</param>
- /// <param name="requestHandler">The means to place outgoing HTTP requests.</param>
- /// <param name="abortDiscoveryChain">if set to <c>true</c>, no further discovery services will be called for this identifier.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty.
/// </returns>
- public IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) {
+ public Task<IdentifierDiscoveryServiceResult> DiscoverAsync(Identifier identifier, System.Threading.CancellationToken cancellationToken) {
var mockIdentifier = identifier as MockIdentifier;
if (mockIdentifier == null) {
- abortDiscoveryChain = false;
- return Enumerable.Empty<IdentifierDiscoveryResult>();
+ return Task.FromResult(new IdentifierDiscoveryServiceResult(Enumerable.Empty<IdentifierDiscoveryResult>(), abortDiscoveryChain: false));
}
- abortDiscoveryChain = true;
- return mockIdentifier.DiscoveryEndpoints;
+ return Task.FromResult(new IdentifierDiscoveryServiceResult(mockIdentifier.DiscoveryEndpoints, abortDiscoveryChain: true));
}
#endregion
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs
index 8509c03..38f9daf 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs
@@ -7,6 +7,9 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
+ using System.Threading;
+ using System.Threading.Tasks;
+
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using Validation;
@@ -30,15 +33,16 @@ namespace DotNetOpenAuth.Test.Mocks {
/// 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="hostFactories">The host factories.</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>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// The details of the endpoints if found, otherwise null.
/// </returns>
- internal override IEnumerable<RelyingPartyEndpointDescription> DiscoverReturnToEndpoints(IDirectWebRequestHandler requestHandler, bool allowRedirects) {
- return this.relyingPartyDescriptions;
+ internal override Task<IEnumerable<RelyingPartyEndpointDescription>> DiscoverReturnToEndpointsAsync(IHostFactories hostFactories, bool allowRedirects, CancellationToken cancellationToken) {
+ return Task.FromResult<IEnumerable<RelyingPartyEndpointDescription>>(this.relyingPartyDescriptions);
}
}
}
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs b/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs
index 1733f17..58a2367 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs
@@ -5,6 +5,9 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.Mocks {
+ using System.Threading;
+ using System.Threading.Tasks;
+
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
using NUnit.Framework;
@@ -23,17 +26,17 @@ namespace DotNetOpenAuth.Test.Mocks {
/// </summary>
public Channel Channel { get; set; }
- MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) {
+ Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
var replayMessage = message as IReplayProtectedProtocolMessage;
if (replayMessage != null) {
replayMessage.Nonce = "someNonce";
- return MessageProtections.ReplayProtection;
+ return MessageProtectionTasks.ReplayProtection;
}
- return null;
+ return MessageProtectionTasks.Null;
}
- MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) {
+ Task<MessageProtections?> IChannelBindingElement.ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
var replayMessage = message as IReplayProtectedProtocolMessage;
if (replayMessage != null) {
Assert.AreEqual("someNonce", replayMessage.Nonce, "The nonce didn't serialize correctly, or something");
@@ -42,10 +45,10 @@ namespace DotNetOpenAuth.Test.Mocks {
throw new ReplayedMessageException(message);
}
this.messageReceived = true;
- return MessageProtections.ReplayProtection;
+ return MessageProtectionTasks.ReplayProtection;
}
- return null;
+ return MessageProtectionTasks.Null;
}
#endregion
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs b/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs
index aa68b0b..f0b2bfc 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs
@@ -9,6 +9,9 @@ namespace DotNetOpenAuth.Test.Mocks {
using System.Collections.Generic;
using System.Linq;
using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
+
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
@@ -26,26 +29,26 @@ namespace DotNetOpenAuth.Test.Mocks {
/// </summary>
public Channel Channel { get; set; }
- MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) {
- ITamperResistantProtocolMessage signedMessage = message as ITamperResistantProtocolMessage;
+ Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
+ var signedMessage = message as ITamperResistantProtocolMessage;
if (signedMessage != null) {
signedMessage.Signature = MessageSignature;
- return MessageProtections.TamperProtection;
+ return MessageProtectionTasks.TamperProtection;
}
- return null;
+ return MessageProtectionTasks.Null;
}
- MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) {
- ITamperResistantProtocolMessage signedMessage = message as ITamperResistantProtocolMessage;
+ Task<MessageProtections?> IChannelBindingElement.ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
+ var signedMessage = message as ITamperResistantProtocolMessage;
if (signedMessage != null) {
if (signedMessage.Signature != MessageSignature) {
throw new InvalidSignatureException(message);
}
- return MessageProtections.TamperProtection;
+ return MessageProtectionTasks.TamperProtection;
}
- return null;
+ return MessageProtectionTasks.Null;
}
#endregion
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs b/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs
index 2b3249f..35d7f1b 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs
@@ -9,11 +9,14 @@ namespace DotNetOpenAuth.Test.Mocks {
using System.Collections.Generic;
using System.Linq;
using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
+
using DotNetOpenAuth.Messaging;
using NUnit.Framework;
internal class MockTransformationBindingElement : IChannelBindingElement {
- private string transform;
+ private readonly string transform;
internal MockTransformationBindingElement(string transform) {
if (transform == null) {
@@ -34,25 +37,25 @@ namespace DotNetOpenAuth.Test.Mocks {
/// </summary>
public Channel Channel { get; set; }
- MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) {
+ Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
var testMessage = message as TestMessage;
if (testMessage != null) {
testMessage.Name = this.transform + testMessage.Name;
- return MessageProtections.None;
+ return MessageProtectionTasks.None;
}
- return null;
+ return MessageProtectionTasks.Null;
}
- MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) {
+ Task<MessageProtections?> IChannelBindingElement.ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
var testMessage = message as TestMessage;
if (testMessage != null) {
StringAssert.StartsWith(this.transform, testMessage.Name);
testMessage.Name = testMessage.Name.Substring(this.transform.Length);
- return MessageProtections.None;
+ return MessageProtectionTasks.None;
}
- return null;
+ return MessageProtectionTasks.Null;
}
#endregion
diff --git a/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs b/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs
index 263f0fd..2a8e7b9 100644
--- a/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs
@@ -7,6 +7,9 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
+ using System.Net.Http;
+ using System.Threading;
+ using System.Threading.Tasks;
using System.Web;
using DotNetOpenAuth.Messaging;
@@ -34,15 +37,15 @@ namespace DotNetOpenAuth.Test.Mocks {
return base.Receive(fields, recipient);
}
- internal new IProtocolMessage ReadFromRequest(HttpRequestBase request) {
- return base.ReadFromRequest(request);
+ internal new Task<IDirectedProtocolMessage> ReadFromRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
+ return base.ReadFromRequestAsync(request, cancellationToken);
}
- protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) {
+ protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) {
throw new NotImplementedException();
}
- protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
+ protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response) {
throw new NotImplementedException();
}
}
diff --git a/src/DotNetOpenAuth.Test/OAuth/AppendixScenarios.cs b/src/DotNetOpenAuth.Test/OAuth/AppendixScenarios.cs
index a295732..88e461c 100644
--- a/src/DotNetOpenAuth.Test/OAuth/AppendixScenarios.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/AppendixScenarios.cs
@@ -8,6 +8,9 @@ namespace DotNetOpenAuth.Test.OAuth {
using System;
using System.IO;
using System.Net;
+ using System.Net.Http;
+ using System.Net.Http.Headers;
+ using System.Threading.Tasks;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
@@ -17,50 +20,79 @@ namespace DotNetOpenAuth.Test.OAuth {
[TestFixture]
public class AppendixScenarios : TestBase {
[Test]
- public void SpecAppendixAExample() {
- ServiceProviderDescription serviceDescription = new ServiceProviderDescription() {
- RequestTokenEndpoint = new MessageReceivingEndpoint("https://photos.example.net/request_token", HttpDeliveryMethods.PostRequest),
- UserAuthorizationEndpoint = new MessageReceivingEndpoint("http://photos.example.net/authorize", HttpDeliveryMethods.GetRequest),
- AccessTokenEndpoint = new MessageReceivingEndpoint("https://photos.example.net/access_token", HttpDeliveryMethods.PostRequest),
- TamperProtectionElements = new ITamperProtectionChannelBindingElement[] {
- new PlaintextSigningBindingElement(),
- new HmacSha1SigningBindingElement(),
- },
+ public async Task SpecAppendixAExample() {
+ var serviceDescription = new ServiceProviderDescription(
+ "https://photos.example.net/request_token",
+ "http://photos.example.net/authorize",
+ "https://photos.example.net/access_token");
+ var serviceHostDescription = new ServiceProviderHostDescription {
+ RequestTokenEndpoint = new MessageReceivingEndpoint(serviceDescription.TemporaryCredentialsRequestEndpoint, HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
+ UserAuthorizationEndpoint = new MessageReceivingEndpoint(serviceDescription.ResourceOwnerAuthorizationEndpoint, HttpDeliveryMethods.GetRequest),
+ AccessTokenEndpoint = new MessageReceivingEndpoint(serviceDescription.TokenRequestEndpoint, HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement(), },
};
- MessageReceivingEndpoint accessPhotoEndpoint = new MessageReceivingEndpoint("http://photos.example.net/photos?file=vacation.jpg&size=original", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest);
- ConsumerDescription consumerDescription = new ConsumerDescription("dpf43f3p2l4k3l03", "kd94hf93k423kf44");
+ var accessPhotoEndpoint = new Uri("http://photos.example.net/photos?file=vacation.jpg&size=original");
+ var consumerDescription = new ConsumerDescription("dpf43f3p2l4k3l03", "kd94hf93k423kf44");
+
+ var tokenManager = new InMemoryTokenManager();
+ tokenManager.AddConsumer(consumerDescription);
+ var sp = new ServiceProvider(serviceHostDescription, tokenManager);
+
+ var coordinator = new CoordinatorBase(
+ async (hostFactories, ct) => {
+ var consumer = new Consumer(
+ consumerDescription.ConsumerKey,
+ consumerDescription.ConsumerSecret,
+ serviceDescription,
+ new MemoryTemporaryCredentialStorage());
+ consumer.HostFactories = hostFactories;
+ var authorizeUrl = await consumer.RequestUserAuthorizationAsync(new Uri("http://printer.example.com/request_token_ready"));
+ Uri authorizeResponseUri;
+ using (var httpClient = hostFactories.CreateHttpClient()) {
+ using (var response = await httpClient.GetAsync(authorizeUrl, ct)) {
+ Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redirect));
+ authorizeResponseUri = response.Headers.Location;
+ }
+ }
+
+ var accessTokenResponse = await consumer.ProcessUserAuthorizationAsync(authorizeResponseUri, ct);
+ Assert.That(accessTokenResponse, Is.Not.Null);
- OAuthCoordinator coordinator = new OAuthCoordinator(
- consumerDescription,
- serviceDescription,
- consumer => {
- consumer.Channel.PrepareResponse(consumer.PrepareRequestUserAuthorization(new Uri("http://printer.example.com/request_token_ready"), null, null)); // .Send() dropped because this is just a simulation
- string accessToken = consumer.ProcessUserAuthorization().AccessToken;
- var photoRequest = consumer.CreateAuthorizingMessage(accessPhotoEndpoint, accessToken);
- OutgoingWebResponse protectedPhoto = ((CoordinatingOAuthConsumerChannel)consumer.Channel).RequestProtectedResource(photoRequest);
- Assert.IsNotNull(protectedPhoto);
- Assert.AreEqual(HttpStatusCode.OK, protectedPhoto.Status);
- Assert.AreEqual("image/jpeg", protectedPhoto.Headers[HttpResponseHeader.ContentType]);
- Assert.AreNotEqual(0, protectedPhoto.ResponseStream.Length);
+ using (var authorizingClient = consumer.CreateHttpClient(accessTokenResponse.AccessToken)) {
+ using (var protectedPhoto = await authorizingClient.GetAsync(accessPhotoEndpoint, ct)) {
+ Assert.That(protectedPhoto, Is.Not.Null);
+ protectedPhoto.EnsureSuccessStatusCode();
+ Assert.That("image/jpeg", Is.EqualTo(protectedPhoto.Content.Headers.ContentType.MediaType));
+ Assert.That(protectedPhoto.Content.Headers.ContentLength, Is.Not.EqualTo(0));
+ }
+ }
},
- sp => {
- var requestTokenMessage = sp.ReadTokenRequest();
- sp.Channel.PrepareResponse(sp.PrepareUnauthorizedTokenMessage(requestTokenMessage)); // .Send() dropped because this is just a simulation
- var authRequest = sp.ReadAuthorizationRequest();
- ((InMemoryTokenManager)sp.TokenManager).AuthorizeRequestToken(authRequest.RequestToken);
- sp.Channel.PrepareResponse(sp.PrepareAuthorizationResponse(authRequest)); // .Send() dropped because this is just a simulation
- var accessRequest = sp.ReadAccessTokenRequest();
- sp.Channel.PrepareResponse(sp.PrepareAccessTokenMessage(accessRequest)); // .Send() dropped because this is just a simulation
- string accessToken = sp.ReadProtectedResourceAuthorization().AccessToken;
- ((CoordinatingOAuthServiceProviderChannel)sp.Channel).SendDirectRawResponse(new OutgoingWebResponse {
- ResponseStream = new MemoryStream(new byte[] { 0x33, 0x66 }),
- Headers = new WebHeaderCollection {
- { HttpResponseHeader.ContentType, "image/jpeg" },
- },
- });
- });
+ CoordinatorBase.Handle(serviceDescription.TemporaryCredentialsRequestEndpoint).By(
+ async (request, ct) => {
+ var requestTokenMessage = await sp.ReadTokenRequestAsync(request, ct);
+ return await sp.Channel.PrepareResponseAsync(sp.PrepareUnauthorizedTokenMessage(requestTokenMessage));
+ }),
+ CoordinatorBase.Handle(serviceDescription.ResourceOwnerAuthorizationEndpoint).By(
+ async (request, ct) => {
+ var authRequest = await sp.ReadAuthorizationRequestAsync(request, ct);
+ ((InMemoryTokenManager)sp.TokenManager).AuthorizeRequestToken(authRequest.RequestToken);
+ return await sp.Channel.PrepareResponseAsync(sp.PrepareAuthorizationResponse(authRequest));
+ }),
+ CoordinatorBase.Handle(serviceDescription.TokenRequestEndpoint).By(
+ async (request, ct) => {
+ var accessRequest = await sp.ReadAccessTokenRequestAsync(request, ct);
+ return await sp.Channel.PrepareResponseAsync(sp.PrepareAccessTokenMessage(accessRequest), ct);
+ }),
+ CoordinatorBase.Handle(accessPhotoEndpoint).By(
+ async (request, ct) => {
+ string accessToken = (await sp.ReadProtectedResourceAuthorizationAsync(request)).AccessToken;
+ Assert.That(accessToken, Is.Not.Null.And.Not.Empty);
+ var responseMessage = new HttpResponseMessage { Content = new ByteArrayContent(new byte[] { 0x33, 0x66 }), };
+ responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
+ return responseMessage;
+ }));
- coordinator.Run();
+ await coordinator.RunAsync();
}
}
}
diff --git a/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs b/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs
index 74752f8..5c25d30 100644
--- a/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs
@@ -5,6 +5,8 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.OAuth {
+ using DotNetOpenAuth.OAuth;
+
/// <summary>
/// Information necessary to initialize a <see cref="Consumer"/>,
/// and to tell a <see cref="ServiceProvider"/> about it.
diff --git a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs b/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
deleted file mode 100644
index 21c1775..0000000
--- a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthCoordinator.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.OAuth {
- using System;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.OAuth;
- using DotNetOpenAuth.OAuth.ChannelElements;
- using DotNetOpenAuth.Test.Mocks;
- using Validation;
-
- /// <summary>
- /// Runs a Consumer and Service Provider simultaneously so they can interact in a full simulation.
- /// </summary>
- internal class OAuthCoordinator : CoordinatorBase<WebConsumer, ServiceProvider> {
- private ConsumerDescription consumerDescription;
- private ServiceProviderDescription serviceDescription;
- private DotNetOpenAuth.OAuth.ServiceProviderSecuritySettings serviceProviderSecuritySettings = DotNetOpenAuth.Configuration.OAuthElement.Configuration.ServiceProvider.SecuritySettings.CreateSecuritySettings();
- private DotNetOpenAuth.OAuth.ConsumerSecuritySettings consumerSecuritySettings = DotNetOpenAuth.Configuration.OAuthElement.Configuration.Consumer.SecuritySettings.CreateSecuritySettings();
-
- /// <summary>Initializes a new instance of the <see cref="OAuthCoordinator"/> class.</summary>
- /// <param name="consumerDescription">The description of the consumer.</param>
- /// <param name="serviceDescription">The service description that will be used to construct the Consumer and ServiceProvider objects.</param>
- /// <param name="consumerAction">The code path of the Consumer.</param>
- /// <param name="serviceProviderAction">The code path of the Service Provider.</param>
- internal OAuthCoordinator(ConsumerDescription consumerDescription, ServiceProviderDescription serviceDescription, Action<WebConsumer> consumerAction, Action<ServiceProvider> serviceProviderAction)
- : base(consumerAction, serviceProviderAction) {
- Requires.NotNull(consumerDescription, "consumerDescription");
- Requires.NotNull(serviceDescription, "serviceDescription");
-
- this.consumerDescription = consumerDescription;
- this.serviceDescription = serviceDescription;
- }
-
- /// <summary>
- /// Starts the simulation.
- /// </summary>
- internal override void Run() {
- // Clone the template signing binding element.
- var signingElement = this.serviceDescription.CreateTamperProtectionElement();
- var consumerSigningElement = signingElement.Clone();
- var spSigningElement = signingElement.Clone();
-
- // Prepare token managers
- InMemoryTokenManager consumerTokenManager = new InMemoryTokenManager();
- InMemoryTokenManager serviceTokenManager = new InMemoryTokenManager();
- consumerTokenManager.AddConsumer(this.consumerDescription);
- serviceTokenManager.AddConsumer(this.consumerDescription);
-
- // Prepare channels that will pass messages directly back and forth.
- var consumerChannel = new CoordinatingOAuthConsumerChannel(consumerSigningElement, (IConsumerTokenManager)consumerTokenManager, this.consumerSecuritySettings);
- var serviceProviderChannel = new CoordinatingOAuthServiceProviderChannel(spSigningElement, (IServiceProviderTokenManager)serviceTokenManager, this.serviceProviderSecuritySettings);
- consumerChannel.RemoteChannel = serviceProviderChannel;
- serviceProviderChannel.RemoteChannel = consumerChannel;
-
- // Prepare the Consumer and Service Provider objects
- WebConsumer consumer = new WebConsumer(this.serviceDescription, consumerTokenManager) {
- OAuthChannel = consumerChannel,
- };
- ServiceProvider serviceProvider = new ServiceProvider(this.serviceDescription, serviceTokenManager, new NonceMemoryStore()) {
- OAuthChannel = serviceProviderChannel,
- };
-
- this.RunCore(consumer, serviceProvider);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
index 14bcaec..acb37fc 100644
--- a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
@@ -178,7 +178,7 @@ namespace DotNetOpenAuth.Test.OpenId {
// When the RP notices the replay we get a specific ReplayMessageException.
try {
CoordinatingChannel channel = (CoordinatingChannel)rp.Channel;
- channel.Replay(response);
+ await channel.ReplayAsync(response);
Assert.Fail("Expected ProtocolException was not thrown.");
} catch (ProtocolException ex) {
Assert.IsTrue(ex is ReplayedMessageException || ex is InvalidSignatureException, "A {0} exception was thrown instead of the expected {1} or {2}.", ex.GetType(), typeof(ReplayedMessageException).Name, typeof(InvalidSignatureException).Name);