summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Test/Mocks
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.Test/Mocks')
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs151
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs (renamed from src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthChannel.cs)35
2 files changed, 162 insertions, 24 deletions
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs
new file mode 100644
index 0000000..5b9c3b0
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs
@@ -0,0 +1,151 @@
+//-----------------------------------------------------------------------
+// <copyright file="CoordinatingOAuthChannel.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.Mocks {
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.Threading;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ /// <summary>
+ /// A special channel used in test simulations to pass messages directly between two parties.
+ /// </summary>
+ internal class CoordinatingOAuthConsumerChannel : OAuthConsumerChannel {
+ internal EventWaitHandle incomingMessageSignal = new AutoResetEvent(false);
+ internal IProtocolMessage incomingMessage;
+ internal OutgoingWebResponse incomingRawResponse;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CoordinatingOAuthChannel"/> class for Consumers.
+ /// </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) {
+ }
+
+ /// <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);
+ HttpRequestInfo 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 HttpRequestInfo GetRequestFromContext() {
+ var directedMessage = (IDirectedProtocolMessage)this.AwaitIncomingMessage();
+ return new HttpRequestInfo(directedMessage, directedMessage.HttpMethods);
+ }
+
+ protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request) {
+ HttpRequestInfo 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 = CloneSerializedParts(response, null);
+ 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(HttpRequestInfo request) {
+ return request.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 HttpRequestInfo SpoofHttpMethod(IDirectedProtocolMessage message) {
+ HttpRequestInfo requestInfo = new HttpRequestInfo(message, message.HttpMethods);
+
+ var signedMessage = message as ITamperResistantOAuthMessage;
+ if (signedMessage != null) {
+ string httpMethod = this.GetHttpMethod(signedMessage.HttpMethods);
+ requestInfo.HttpMethod = httpMethod;
+ requestInfo.UrlBeforeRewriting = message.Recipient;
+ signedMessage.HttpMethod = httpMethod;
+ }
+
+ requestInfo.Message = this.CloneSerializedParts(message, requestInfo);
+
+ 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, HttpRequestInfo requestInfo) where T : class, IProtocolMessage {
+ Contract.Requires<ArgumentNullException>(message != null);
+
+ 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/CoordinatingOAuthChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
index 74e23bd..9bdbc04 100644
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthChannel.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
@@ -16,43 +16,30 @@ namespace DotNetOpenAuth.Test.Mocks {
/// <summary>
/// A special channel used in test simulations to pass messages directly between two parties.
/// </summary>
- internal class CoordinatingOAuthChannel : OAuthChannel {
- private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false);
- private IProtocolMessage incomingMessage;
- private OutgoingWebResponse incomingRawResponse;
+ internal class CoordinatingOAuthServiceProviderChannel : OAuthServiceProviderChannel {
+ internal EventWaitHandle incomingMessageSignal = new AutoResetEvent(false);
+ internal IProtocolMessage incomingMessage;
+ internal OutgoingWebResponse incomingRawResponse;
/// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingOAuthChannel"/> class for Consumers.
+ /// Initializes a new instance of the <see cref="CoordinatingOAuthChannel"/> class for Service Providers.
/// </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 CoordinatingOAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, IConsumerTokenManager tokenManager, DotNetOpenAuth.OAuth.ConsumerSecuritySettings securitySettings)
+ internal CoordinatingOAuthServiceProviderChannel(ITamperProtectionChannelBindingElement signingBindingElement, IServiceProviderTokenManager tokenManager, DotNetOpenAuth.OAuth.ServiceProviderSecuritySettings securitySettings)
: base(
signingBindingElement,
new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge),
tokenManager,
- securitySettings) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CoordinatingOAuthChannel"/> class for Consumers.
- /// </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 CoordinatingOAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, IServiceProviderTokenManager tokenManager, DotNetOpenAuth.OAuth.ServiceProviderSecuritySettings securitySettings)
- : base(
- signingBindingElement,
- new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge),
- tokenManager,
- securitySettings) {
+ securitySettings,
+ new OAuthServiceProviderMessageFactory(tokenManager)) {
}
/// <summary>
/// Gets or sets the coordinating channel used by the other party.
/// </summary>
- internal CoordinatingOAuthChannel RemoteChannel { get; set; }
+ internal CoordinatingOAuthConsumerChannel RemoteChannel { get; set; }
internal OutgoingWebResponse RequestProtectedResource(AccessProtectedResourceRequest request) {
((ITamperResistantOAuthMessage)request).HttpMethod = this.GetHttpMethod(((ITamperResistantOAuthMessage)request).HttpMethods);
@@ -149,9 +136,9 @@ namespace DotNetOpenAuth.Test.Mocks {
recipient = new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods);
}
- clonedMessage = this.RemoteChannel.MessageFactory.GetNewRequestMessage(recipient, fields);
+ clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewRequestMessage(recipient, fields);
} else if (directResponse != null && directResponse.IsDirectResponse()) {
- clonedMessage = this.RemoteChannel.MessageFactory.GetNewResponseMessage(directResponse.OriginatingRequest, fields);
+ 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.");
}