summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2012-01-29 14:32:45 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2012-01-29 14:32:45 -0800
commit5fec515095ee10b522f414a03e78f282aaf520dc (patch)
tree204c75486639c23cdda2ef38b34d7e5050a1a2e3 /src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
parentf1a4155398635a4fd9f485eec817152627682704 (diff)
parent8f4165ee515728aca3faaa26e8354a40612e85e4 (diff)
downloadDotNetOpenAuth-5fec515095ee10b522f414a03e78f282aaf520dc.zip
DotNetOpenAuth-5fec515095ee10b522f414a03e78f282aaf520dc.tar.gz
DotNetOpenAuth-5fec515095ee10b522f414a03e78f282aaf520dc.tar.bz2
Merge branch 'splitDlls'.
DNOA now builds and (in some cases) ships as many distinct assemblies.
Diffstat (limited to 'src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs')
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
new file mode 100644
index 0000000..d07f794
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs
@@ -0,0 +1,163 @@
+//-----------------------------------------------------------------------
+// <copyright file="CoordinatingOAuthServiceProviderChannel.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 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 = 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();
+ }
+
+ internal void SendDirectRawResponse(OutgoingWebResponse response) {
+ this.RemoteChannel.IncomingRawResponse = response;
+ this.RemoteChannel.IncomingMessageSignal.Set();
+ }
+
+ 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 {
+ 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";
+ }
+ }
+}