diff options
Diffstat (limited to 'src/DotNetOpenAuth.Test')
7 files changed, 644 insertions, 634 deletions
diff --git a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs index 7033382..6bf7130 100644 --- a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs +++ b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs @@ -1,290 +1,292 @@ -//----------------------------------------------------------------------- -// <copyright file="ChannelTests.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Messaging { - using System; - using System.Collections.Generic; - using System.IO; - using System.Net; - using System.Web; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.Messaging.Bindings; - using DotNetOpenAuth.Test.Mocks; - using Microsoft.VisualStudio.TestTools.UnitTesting; - - [TestClass] - public class ChannelTests : MessagingTestBase { - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void CtorNull() { - // This bad channel is deliberately constructed to pass null to - // its protected base class' constructor. - new TestBadChannel(true); - } - - [TestMethod] - public void ReadFromRequestQueryString() { - this.ParameterizedReceiveTest("GET"); - } - - [TestMethod] - public void ReadFromRequestForm() { - this.ParameterizedReceiveTest("POST"); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void SendNull() { - this.Channel.Send(null); - } - - [TestMethod, ExpectedException(typeof(ArgumentException))] - public void SendIndirectedUndirectedMessage() { - IProtocolMessage message = new TestDirectedMessage(MessageTransport.Indirect); - this.Channel.Send(message); - } - - [TestMethod, ExpectedException(typeof(ArgumentException))] - public void SendDirectedNoRecipientMessage() { - IProtocolMessage message = new TestDirectedMessage(MessageTransport.Indirect); - this.Channel.Send(message); - } - - [TestMethod, ExpectedException(typeof(ArgumentException))] - public void SendInvalidMessageTransport() { - IProtocolMessage message = new TestDirectedMessage((MessageTransport)100); - this.Channel.Send(message); - } - - [TestMethod] - public void SendIndirectMessage301Get() { - TestDirectedMessage message = new TestDirectedMessage(MessageTransport.Indirect); - GetStandardTestMessage(FieldFill.CompleteBeforeBindings, message); - message.Recipient = new Uri("http://provider/path"); - var expected = GetStandardTestFields(FieldFill.CompleteBeforeBindings); - - UserAgentResponse response = this.Channel.Send(message); - Assert.AreEqual(HttpStatusCode.Redirect, response.Status); - StringAssert.StartsWith(response.Headers[HttpResponseHeader.Location], "http://provider/path"); - foreach (var pair in expected) { - string key = HttpUtility.UrlEncode(pair.Key); - string value = HttpUtility.UrlEncode(pair.Value); - string substring = string.Format("{0}={1}", key, value); - StringAssert.Contains(response.Headers[HttpResponseHeader.Location], substring); - } - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void SendIndirectMessage301GetNullMessage() { - TestBadChannel badChannel = new TestBadChannel(false); - badChannel.Create301RedirectResponse(null, new Dictionary<string, string>()); - } - - [TestMethod, ExpectedException(typeof(ArgumentException))] - public void SendIndirectMessage301GetEmptyRecipient() { - TestBadChannel badChannel = new TestBadChannel(false); - var message = new TestDirectedMessage(MessageTransport.Indirect); - badChannel.Create301RedirectResponse(message, new Dictionary<string, string>()); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void SendIndirectMessage301GetNullFields() { - TestBadChannel badChannel = new TestBadChannel(false); - var message = new TestDirectedMessage(MessageTransport.Indirect); - message.Recipient = new Uri("http://someserver"); - badChannel.Create301RedirectResponse(message, null); - } - - [TestMethod] - public void SendIndirectMessageFormPost() { - // We craft a very large message to force fallback to form POST. - // We'll also stick some HTML reserved characters in the string value - // to test proper character escaping. - var message = new TestDirectedMessage(MessageTransport.Indirect) { - Age = 15, - Name = "c<b" + new string('a', 10 * 1024), - Location = new Uri("http://host/path"), - Recipient = new Uri("http://provider/path"), - }; - UserAgentResponse response = this.Channel.Send(message); - Assert.AreEqual(HttpStatusCode.OK, response.Status, "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; - StringAssert.Contains(body, "<form "); - StringAssert.Contains(body, "action=\"http://provider/path\""); - StringAssert.Contains(body, "method=\"post\""); - StringAssert.Contains(body, "<input type=\"hidden\" name=\"age\" value=\"15\" />"); - StringAssert.Contains(body, "<input type=\"hidden\" name=\"Location\" value=\"http://host/path\" />"); - StringAssert.Contains(body, "<input type=\"hidden\" name=\"Name\" value=\"" + HttpUtility.HtmlEncode(message.Name) + "\" />"); - StringAssert.Contains(body, ".submit()", "There should be some javascript to automate form submission."); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void SendIndirectMessageFormPostNullMessage() { - TestBadChannel badChannel = new TestBadChannel(false); - badChannel.CreateFormPostResponse(null, new Dictionary<string, string>()); - } - - [TestMethod, ExpectedException(typeof(ArgumentException))] - public void SendIndirectMessageFormPostEmptyRecipient() { - TestBadChannel badChannel = new TestBadChannel(false); - var message = new TestDirectedMessage(MessageTransport.Indirect); - badChannel.CreateFormPostResponse(message, new Dictionary<string, string>()); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void SendIndirectMessageFormPostNullFields() { - TestBadChannel badChannel = new TestBadChannel(false); - var message = new TestDirectedMessage(MessageTransport.Indirect); - message.Recipient = new Uri("http://someserver"); - badChannel.CreateFormPostResponse(message, null); - } - - /// <summary> - /// Tests that a direct message is sent when the appropriate message type is provided. - /// </summary> - /// <remarks> - /// Since this is a mock channel that doesn't actually formulate a direct message response, - /// we just check that the right method was called. - /// </remarks> - [TestMethod, ExpectedException(typeof(NotImplementedException), "SendDirectMessageResponse")] - public void SendDirectMessageResponse() { - IProtocolMessage message = new TestDirectedMessage { - Age = 15, - Name = "Andrew", - Location = new Uri("http://host/path"), - }; - this.Channel.Send(message); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void SendIndirectMessageNull() { - TestBadChannel badChannel = new TestBadChannel(false); - badChannel.SendIndirectMessage(null); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void ReceiveNull() { - TestBadChannel badChannel = new TestBadChannel(false); - badChannel.Receive(null, null); - } - - [TestMethod] - public void ReceiveUnrecognizedMessage() { - TestBadChannel badChannel = new TestBadChannel(false); - Assert.IsNull(badChannel.Receive(new Dictionary<string, string>(), null)); - } - - [TestMethod] - public void ReadFromRequestWithContext() { - var fields = GetStandardTestFields(FieldFill.AllRequired); - 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 = this.Channel.ReadFromRequest(); - Assert.IsNotNull(message); - Assert.IsInstanceOfType(message, typeof(TestMessage)); - Assert.AreEqual(expectedMessage.Age, ((TestMessage)message).Age); - } - - [TestMethod, ExpectedException(typeof(InvalidOperationException))] - public void ReadFromRequestNoContext() { - TestBadChannel badChannel = new TestBadChannel(false); - badChannel.ReadFromRequest(); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void ReadFromRequestNull() { - TestBadChannel badChannel = new TestBadChannel(false); - badChannel.ReadFromRequest(null); - } - - [TestMethod] - public void SendReplayProtectedMessageSetsNonce() { - TestReplayProtectedMessage message = new TestReplayProtectedMessage(MessageTransport.Indirect); - message.Recipient = new Uri("http://localtest"); - - this.Channel = CreateChannel(MessageProtections.ReplayProtection); - this.Channel.Send(message); - Assert.IsNotNull(((IReplayProtectedProtocolMessage)message).Nonce); - } - - [TestMethod, ExpectedException(typeof(InvalidSignatureException))] - public void ReceivedInvalidSignature() { - this.Channel = CreateChannel(MessageProtections.TamperProtection); - this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, true); - } - - [TestMethod] - public void ReceivedReplayProtectedMessageJustOnce() { - this.Channel = CreateChannel(MessageProtections.ReplayProtection); - this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false); - } - - [TestMethod, ExpectedException(typeof(ReplayedMessageException))] - public void ReceivedReplayProtectedMessageTwice() { - this.Channel = CreateChannel(MessageProtections.ReplayProtection); - this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false); - this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false); - } - - [TestMethod, ExpectedException(typeof(ProtocolException))] - public void MessageExpirationWithoutTamperResistance() { - new TestChannel( - new TestMessageFactory(), - new StandardExpirationBindingElement()); - } - - [TestMethod, ExpectedException(typeof(ProtocolException))] - public void TooManyBindingElementsProvidingSameProtection() { - new TestChannel( - new TestMessageFactory(), - new MockSigningBindingElement(), - new MockSigningBindingElement()); - } - - [TestMethod] - public void BindingElementsOrdering() { - IChannelBindingElement transformA = new MockTransformationBindingElement("a"); - IChannelBindingElement transformB = new MockTransformationBindingElement("b"); - IChannelBindingElement sign = new MockSigningBindingElement(); - IChannelBindingElement replay = new MockReplayProtectionBindingElement(); - IChannelBindingElement expire = new StandardExpirationBindingElement(); - - Channel channel = new TestChannel( - new TestMessageFactory(), - sign, - replay, - expire, - transformB, - transformA); - - Assert.AreEqual(5, channel.BindingElements.Count); - Assert.AreSame(transformB, channel.BindingElements[0]); - Assert.AreSame(transformA, channel.BindingElements[1]); - Assert.AreSame(replay, channel.BindingElements[2]); - Assert.AreSame(expire, channel.BindingElements[3]); - Assert.AreSame(sign, channel.BindingElements[4]); - } - - [TestMethod, ExpectedException(typeof(UnprotectedMessageException))] - public void InsufficientlyProtectedMessageSent() { - var message = new TestSignedDirectedMessage(MessageTransport.Direct); - message.Recipient = new Uri("http://localtest"); - this.Channel.Send(message); - } - - [TestMethod, ExpectedException(typeof(UnprotectedMessageException))] - public void InsufficientlyProtectedMessageReceived() { - this.Channel = CreateChannel(MessageProtections.None, MessageProtections.TamperProtection); - this.ParameterizedReceiveProtectedTest(DateTime.Now, false); - } - - [TestMethod, ExpectedException(typeof(ProtocolException))] - public void IncomingMessageMissingRequiredParameters() { - var fields = GetStandardTestFields(FieldFill.IdentifiableButNotAllRequired); - this.Channel.ReadFromRequest(CreateHttpRequestInfo("GET", fields)); - } - } -} +//-----------------------------------------------------------------------
+// <copyright file="ChannelTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.Messaging {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Net;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.Test.Mocks;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class ChannelTests : MessagingTestBase {
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void CtorNull() {
+ // This bad channel is deliberately constructed to pass null to
+ // its protected base class' constructor.
+ new TestBadChannel(true);
+ }
+
+ [TestMethod]
+ public void ReadFromRequestQueryString() {
+ this.ParameterizedReceiveTest("GET");
+ }
+
+ [TestMethod]
+ public void ReadFromRequestForm() {
+ this.ParameterizedReceiveTest("POST");
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void SendNull() {
+ this.Channel.Send(null);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void SendIndirectedUndirectedMessage() {
+ IProtocolMessage message = new TestDirectedMessage(MessageTransport.Indirect);
+ this.Channel.Send(message);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void SendDirectedNoRecipientMessage() {
+ IProtocolMessage message = new TestDirectedMessage(MessageTransport.Indirect);
+ this.Channel.Send(message);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void SendInvalidMessageTransport() {
+ IProtocolMessage message = new TestDirectedMessage((MessageTransport)100);
+ this.Channel.Send(message);
+ }
+
+ [TestMethod]
+ public void SendIndirectMessage301Get() {
+ TestDirectedMessage message = new TestDirectedMessage(MessageTransport.Indirect);
+ GetStandardTestMessage(FieldFill.CompleteBeforeBindings, message);
+ message.Recipient = new Uri("http://provider/path");
+ var expected = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
+
+ UserAgentResponse response = this.Channel.Send(message);
+ Assert.AreEqual(HttpStatusCode.Redirect, response.Status);
+ StringAssert.StartsWith(response.Headers[HttpResponseHeader.Location], "http://provider/path");
+ foreach (var pair in expected) {
+ string key = HttpUtility.UrlEncode(pair.Key);
+ string value = HttpUtility.UrlEncode(pair.Value);
+ string substring = string.Format("{0}={1}", key, value);
+ StringAssert.Contains(response.Headers[HttpResponseHeader.Location], substring);
+ }
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void SendIndirectMessage301GetNullMessage() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ badChannel.Create301RedirectResponse(null, new Dictionary<string, string>());
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void SendIndirectMessage301GetEmptyRecipient() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ var message = new TestDirectedMessage(MessageTransport.Indirect);
+ badChannel.Create301RedirectResponse(message, new Dictionary<string, string>());
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void SendIndirectMessage301GetNullFields() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ var message = new TestDirectedMessage(MessageTransport.Indirect);
+ message.Recipient = new Uri("http://someserver");
+ badChannel.Create301RedirectResponse(message, null);
+ }
+
+ [TestMethod]
+ public void SendIndirectMessageFormPost() {
+ // We craft a very large message to force fallback to form POST.
+ // We'll also stick some HTML reserved characters in the string value
+ // to test proper character escaping.
+ var message = new TestDirectedMessage(MessageTransport.Indirect) {
+ Age = 15,
+ Name = "c<b" + new string('a', 10 * 1024),
+ Location = new Uri("http://host/path"),
+ Recipient = new Uri("http://provider/path"),
+ };
+ UserAgentResponse response = this.Channel.Send(message);
+ Assert.AreEqual(HttpStatusCode.OK, response.Status, "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;
+ StringAssert.Contains(body, "<form ");
+ StringAssert.Contains(body, "action=\"http://provider/path\"");
+ StringAssert.Contains(body, "method=\"post\"");
+ StringAssert.Contains(body, "<input type=\"hidden\" name=\"age\" value=\"15\" />");
+ StringAssert.Contains(body, "<input type=\"hidden\" name=\"Location\" value=\"http://host/path\" />");
+ StringAssert.Contains(body, "<input type=\"hidden\" name=\"Name\" value=\"" + HttpUtility.HtmlEncode(message.Name) + "\" />");
+ StringAssert.Contains(body, ".submit()", "There should be some javascript to automate form submission.");
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void SendIndirectMessageFormPostNullMessage() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ badChannel.CreateFormPostResponse(null, new Dictionary<string, string>());
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
+ public void SendIndirectMessageFormPostEmptyRecipient() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ var message = new TestDirectedMessage(MessageTransport.Indirect);
+ badChannel.CreateFormPostResponse(message, new Dictionary<string, string>());
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void SendIndirectMessageFormPostNullFields() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ var message = new TestDirectedMessage(MessageTransport.Indirect);
+ message.Recipient = new Uri("http://someserver");
+ badChannel.CreateFormPostResponse(message, null);
+ }
+
+ /// <summary>
+ /// Tests that a direct message is sent when the appropriate message type is provided.
+ /// </summary>
+ /// <remarks>
+ /// Since this is a mock channel that doesn't actually formulate a direct message response,
+ /// we just check that the right method was called.
+ /// </remarks>
+ [TestMethod, ExpectedException(typeof(NotImplementedException), "SendDirectMessageResponse")]
+ public void SendDirectMessageResponse() {
+ IProtocolMessage message = new TestDirectedMessage {
+ Age = 15,
+ Name = "Andrew",
+ Location = new Uri("http://host/path"),
+ };
+ this.Channel.Send(message);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void SendIndirectMessageNull() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ badChannel.SendIndirectMessage(null);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void ReceiveNull() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ badChannel.Receive(null, null);
+ }
+
+ [TestMethod]
+ public void ReceiveUnrecognizedMessage() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ Assert.IsNull(badChannel.Receive(new Dictionary<string, string>(), null));
+ }
+
+ [TestMethod]
+ public void ReadFromRequestWithContext() {
+ var fields = GetStandardTestFields(FieldFill.AllRequired);
+ 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 = this.Channel.ReadFromRequest();
+ Assert.IsNotNull(message);
+ Assert.IsInstanceOfType(message, typeof(TestMessage));
+ Assert.AreEqual(expectedMessage.Age, ((TestMessage)message).Age);
+ }
+
+ [TestMethod, ExpectedException(typeof(InvalidOperationException))]
+ public void ReadFromRequestNoContext() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ badChannel.ReadFromRequest();
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void ReadFromRequestNull() {
+ TestBadChannel badChannel = new TestBadChannel(false);
+ badChannel.ReadFromRequest(null);
+ }
+
+ [TestMethod]
+ public void SendReplayProtectedMessageSetsNonce() {
+ TestReplayProtectedMessage message = new TestReplayProtectedMessage(MessageTransport.Indirect);
+ message.Recipient = new Uri("http://localtest");
+
+ this.Channel = CreateChannel(MessageProtections.ReplayProtection);
+ this.Channel.Send(message);
+ Assert.IsNotNull(((IReplayProtectedProtocolMessage)message).Nonce);
+ }
+
+ [TestMethod, ExpectedException(typeof(InvalidSignatureException))]
+ public void ReceivedInvalidSignature() {
+ this.Channel = CreateChannel(MessageProtections.TamperProtection);
+ this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, true);
+ }
+
+ [TestMethod]
+ public void ReceivedReplayProtectedMessageJustOnce() {
+ this.Channel = CreateChannel(MessageProtections.ReplayProtection);
+ this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
+ }
+
+ [TestMethod, ExpectedException(typeof(ReplayedMessageException))]
+ public void ReceivedReplayProtectedMessageTwice() {
+ this.Channel = CreateChannel(MessageProtections.ReplayProtection);
+ this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
+ this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
+ }
+
+ [TestMethod, ExpectedException(typeof(ProtocolException))]
+ public void MessageExpirationWithoutTamperResistance() {
+ new TestChannel(
+ new TestMessageFactory(),
+ new StandardExpirationBindingElement());
+ }
+
+ [TestMethod, ExpectedException(typeof(ProtocolException))]
+ public void TooManyBindingElementsProvidingSameProtection() {
+ Channel channel = new TestChannel(
+ new TestMessageFactory(),
+ new MockSigningBindingElement(),
+ new MockSigningBindingElement());
+ Channel_Accessor accessor = Channel_Accessor.AttachShadow(channel);
+ accessor.PrepareMessageForSending(new TestSignedDirectedMessage());
+ }
+
+ [TestMethod]
+ public void BindingElementsOrdering() {
+ IChannelBindingElement transformA = new MockTransformationBindingElement("a");
+ IChannelBindingElement transformB = new MockTransformationBindingElement("b");
+ IChannelBindingElement sign = new MockSigningBindingElement();
+ IChannelBindingElement replay = new MockReplayProtectionBindingElement();
+ IChannelBindingElement expire = new StandardExpirationBindingElement();
+
+ Channel channel = new TestChannel(
+ new TestMessageFactory(),
+ sign,
+ replay,
+ expire,
+ transformB,
+ transformA);
+
+ Assert.AreEqual(5, channel.BindingElements.Count);
+ Assert.AreSame(transformB, channel.BindingElements[0]);
+ Assert.AreSame(transformA, channel.BindingElements[1]);
+ Assert.AreSame(replay, channel.BindingElements[2]);
+ Assert.AreSame(expire, channel.BindingElements[3]);
+ Assert.AreSame(sign, channel.BindingElements[4]);
+ }
+
+ [TestMethod, ExpectedException(typeof(UnprotectedMessageException))]
+ public void InsufficientlyProtectedMessageSent() {
+ var message = new TestSignedDirectedMessage(MessageTransport.Direct);
+ message.Recipient = new Uri("http://localtest");
+ this.Channel.Send(message);
+ }
+
+ [TestMethod, ExpectedException(typeof(UnprotectedMessageException))]
+ public void InsufficientlyProtectedMessageReceived() {
+ this.Channel = CreateChannel(MessageProtections.None, MessageProtections.TamperProtection);
+ this.ParameterizedReceiveProtectedTest(DateTime.Now, false);
+ }
+
+ [TestMethod, ExpectedException(typeof(ProtocolException))]
+ public void IncomingMessageMissingRequiredParameters() {
+ var fields = GetStandardTestFields(FieldFill.IdentifiableButNotAllRequired);
+ this.Channel.ReadFromRequest(CreateHttpRequestInfo("GET", fields));
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs index 7a96718..1731afb 100644 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs +++ b/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs @@ -1,149 +1,152 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingChannel.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 System.Threading; - using DotNetOpenAuth.Messaging; - - internal class CoordinatingChannel : Channel { - private Channel wrappedChannel; - private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false); - private IProtocolMessage incomingMessage; - private Action<IProtocolMessage> incomingMessageFilter; - private Action<IProtocolMessage> outgoingMessageFilter; - - internal CoordinatingChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter) - : base(GetMessageFactory(wrappedChannel), wrappedChannel.BindingElements.ToArray()) { - ErrorUtilities.VerifyArgumentNotNull(wrappedChannel, "wrappedChannel"); - - this.wrappedChannel = wrappedChannel; - this.incomingMessageFilter = incomingMessageFilter; - this.outgoingMessageFilter = outgoingMessageFilter; - } - - /// <summary> - /// Gets or sets the coordinating channel used by the other party. - /// </summary> - internal CoordinatingChannel RemoteChannel { get; set; } - - protected internal override HttpRequestInfo GetRequestFromContext() { - return new HttpRequestInfo((IDirectedProtocolMessage)this.AwaitIncomingMessage()); - } - - protected override IProtocolMessage RequestInternal(IDirectedProtocolMessage request) { - this.ProcessMessageFilter(request, true); - 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... - IProtocolMessage response = this.AwaitIncomingMessage(); - this.ProcessMessageFilter(response, false); - return response; - } - - protected override UserAgentResponse SendDirectMessageResponse(IProtocolMessage response) { - this.ProcessMessageFilter(response, true); - this.RemoteChannel.incomingMessage = CloneSerializedParts(response, null); - this.RemoteChannel.incomingMessageSignal.Set(); - return null; - } - - protected override UserAgentResponse SendIndirectMessage(IDirectedProtocolMessage message) { - this.ProcessMessageFilter(message, true); - // In this mock transport, direct and indirect messages are the same. - return this.SendDirectMessageResponse(message); - } - - protected override IDirectedProtocolMessage ReadFromRequestInternal(HttpRequestInfo request) { - this.ProcessMessageFilter(request.Message, false); - return request.Message; - } - - protected override IDictionary<string, string> ReadFromResponseInternal(DirectWebResponse response) { - Channel_Accessor accessor = Channel_Accessor.AttachShadow(this.wrappedChannel); - return accessor.ReadFromResponseInternal(response); - } - - protected override void VerifyMessageAfterReceiving(IProtocolMessage message) { - Channel_Accessor accessor = Channel_Accessor.AttachShadow(this.wrappedChannel); - accessor.VerifyMessageAfterReceiving(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> - protected virtual HttpRequestInfo SpoofHttpMethod(IDirectedProtocolMessage message) { - HttpRequestInfo requestInfo = new HttpRequestInfo(message); - - requestInfo.Message = this.CloneSerializedParts(message, requestInfo); - - return requestInfo; - } - - protected virtual T CloneSerializedParts<T>(T message, HttpRequestInfo requestInfo) where T : class, IProtocolMessage { - ErrorUtilities.VerifyArgumentNotNull(message, "message"); - - IProtocolMessage clonedMessage; - MessageSerializer serializer = MessageSerializer.Get(message.GetType()); - var fields = serializer.Serialize(message); - - 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.MessageFactory.GetNewRequestMessage(recipient, fields); - } else if (directResponse != null && directResponse.IsDirectResponse()) { - clonedMessage = this.RemoteChannel.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. - serializer.Deserialize(fields, clonedMessage); - - return (T)clonedMessage; - } - - private static IMessageFactory GetMessageFactory(Channel channel) { - ErrorUtilities.VerifyArgumentNotNull(channel, "channel"); - - Channel_Accessor accessor = Channel_Accessor.AttachShadow(channel); - return accessor.MessageFactory; - } - - private IProtocolMessage AwaitIncomingMessage() { - this.incomingMessageSignal.WaitOne(); - IProtocolMessage response = this.incomingMessage; - this.incomingMessage = null; - 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); - } - } - } - } -} +//-----------------------------------------------------------------------
+// <copyright file="CoordinatingChannel.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 System.Threading;
+ using DotNetOpenAuth.Messaging;
+
+ internal class CoordinatingChannel : Channel {
+ private Channel wrappedChannel;
+ private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false);
+ private IProtocolMessage incomingMessage;
+ private Action<IProtocolMessage> incomingMessageFilter;
+ private Action<IProtocolMessage> outgoingMessageFilter;
+
+ internal CoordinatingChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter)
+ : base(GetMessageFactory(wrappedChannel), wrappedChannel.BindingElements.ToArray()) {
+ ErrorUtilities.VerifyArgumentNotNull(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; }
+
+ protected internal override HttpRequestInfo GetRequestFromContext() {
+ return new HttpRequestInfo((IDirectedProtocolMessage)this.AwaitIncomingMessage());
+ }
+
+ protected override IProtocolMessage RequestInternal(IDirectedProtocolMessage request) {
+ this.ProcessMessageFilter(request, true);
+ 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...
+ IProtocolMessage response = this.AwaitIncomingMessage();
+ this.ProcessMessageFilter(response, false);
+ return response;
+ }
+
+ protected override UserAgentResponse SendDirectMessageResponse(IProtocolMessage response) {
+ this.ProcessMessageFilter(response, true);
+ this.RemoteChannel.incomingMessage = CloneSerializedParts(response, null);
+ this.RemoteChannel.incomingMessageSignal.Set();
+ return null;
+ }
+
+ protected override UserAgentResponse SendIndirectMessage(IDirectedProtocolMessage message) {
+ this.ProcessMessageFilter(message, true);
+ // In this mock transport, direct and indirect messages are the same.
+ return this.SendDirectMessageResponse(message);
+ }
+
+ protected override IDirectedProtocolMessage ReadFromRequestInternal(HttpRequestInfo request) {
+ this.ProcessMessageFilter(request.Message, false);
+ return request.Message;
+ }
+
+ protected override IDictionary<string, string> ReadFromResponseInternal(DirectWebResponse response) {
+ Channel_Accessor accessor = Channel_Accessor.AttachShadow(this.wrappedChannel);
+ return accessor.ReadFromResponseInternal(response);
+ }
+
+ protected override void VerifyMessageAfterReceiving(IProtocolMessage message) {
+ Channel_Accessor accessor = Channel_Accessor.AttachShadow(this.wrappedChannel);
+ accessor.VerifyMessageAfterReceiving(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>
+ protected virtual HttpRequestInfo SpoofHttpMethod(IDirectedProtocolMessage message) {
+ HttpRequestInfo requestInfo = new HttpRequestInfo(message);
+
+ requestInfo.Message = this.CloneSerializedParts(message, requestInfo);
+
+ return requestInfo;
+ }
+
+ protected virtual T CloneSerializedParts<T>(T message, HttpRequestInfo requestInfo) where T : class, IProtocolMessage {
+ ErrorUtilities.VerifyArgumentNotNull(message, "message");
+
+ IProtocolMessage clonedMessage;
+ MessageSerializer serializer = MessageSerializer.Get(message.GetType());
+ var fields = serializer.Serialize(message);
+
+ 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.MessageFactory.GetNewRequestMessage(recipient, fields);
+ } else if (directResponse != null && directResponse.IsDirectResponse()) {
+ clonedMessage = this.RemoteChannel.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.
+ serializer.Deserialize(fields, clonedMessage);
+
+ return (T)clonedMessage;
+ }
+
+ private static IMessageFactory GetMessageFactory(Channel channel) {
+ ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+
+ Channel_Accessor accessor = Channel_Accessor.AttachShadow(channel);
+ return accessor.MessageFactory;
+ }
+
+ private IProtocolMessage AwaitIncomingMessage() {
+ this.incomingMessageSignal.WaitOne();
+ IProtocolMessage response = this.incomingMessage;
+ this.incomingMessage = null;
+ 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/OpenId/AuthenticationTests.cs b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs index b02cfee..ca1e5f1 100644 --- a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs @@ -16,9 +16,6 @@ namespace DotNetOpenAuth.Test.OpenId { using DotNetOpenAuth.OpenId.Messages; using Microsoft.VisualStudio.TestTools.UnitTesting; - // TODO: make all the tests in this class test every version of the protocol. - // Currently this fails because we don't have a "token"-like facility of - // DotNetOpenID yet. [TestClass] public class AuthenticationTests : OpenIdTestBase { [TestInitialize] @@ -28,7 +25,7 @@ namespace DotNetOpenAuth.Test.OpenId { [TestMethod] public void SharedAssociationPositive() { - this.ParameterizedPositiveAuthenticationTest(Protocol.Default, true, true, false); + this.ParameterizedPositiveAuthenticationTest(true, true, false); } /// <summary> @@ -36,17 +33,17 @@ namespace DotNetOpenAuth.Test.OpenId { /// </summary> [TestMethod] public void SharedAssociationTampered() { - this.ParameterizedPositiveAuthenticationTest(Protocol.Default, true, true, true); + this.ParameterizedPositiveAuthenticationTest(true, true, true); } [TestMethod] public void SharedAssociationNegative() { - this.ParameterizedPositiveAuthenticationTest(Protocol.V11, true, false, false); + this.ParameterizedPositiveAuthenticationTest(true, false, false); } [TestMethod] public void PrivateAssociationPositive() { - this.ParameterizedPositiveAuthenticationTest(Protocol.Default, false, true, false); + this.ParameterizedPositiveAuthenticationTest(false, true, false); } /// <summary> @@ -54,12 +51,12 @@ namespace DotNetOpenAuth.Test.OpenId { /// </summary> [TestMethod] public void PrivateAssociationTampered() { - this.ParameterizedPositiveAuthenticationTest(Protocol.Default, false, true, true); + this.ParameterizedPositiveAuthenticationTest(false, true, true); } [TestMethod] public void NoAssociationNegative() { - this.ParameterizedPositiveAuthenticationTest(Protocol.Default, false, false, false); + this.ParameterizedPositiveAuthenticationTest(false, false, false); } private void ParameterizedPositiveAuthenticationTest(bool sharedAssociation, bool positive, bool tamper) { @@ -132,10 +129,10 @@ namespace DotNetOpenAuth.Test.OpenId { coordinator.IncomingMessageFilter = message => { var assertion = message as PositiveAssertionResponse; if (assertion != null) { - // Alter the Claimed Identifier between the Provider and the Relying Party. + // Alter the Local Identifier between the Provider and the Relying Party. // If the signature binding element does its job, this should cause the RP // to throw. - assertion.ClaimedIdentifier = "http://victim"; + assertion.LocalIdentifier = "http://victim"; } }; } diff --git a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs index 6eafb13..c7e445c 100644 --- a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs @@ -85,6 +85,14 @@ namespace DotNetOpenAuth.Test.OpenId.ChannelElements { Assert.AreEqual("extra", ext.Data);
}
+ /// <summary>
+ /// Verifies that unsigned extension responses (where any or all fields are unsigned) are ignored.
+ /// </summary>
+ [TestMethod, Ignore]
+ public void UnsignedExtensionsAreIgnored() {
+ Assert.Inconclusive("Not yet implemented.");
+ }
+
private static IEnumerable<string> GetAliases(IDictionary<string, string> extraData) {
Regex regex = new Regex(@"^openid\.ns\.(\w+)");
return from key in extraData.Keys
diff --git a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/OpenIdChannelTests.cs b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/OpenIdChannelTests.cs index f47dfdf..a548969 100644 --- a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/OpenIdChannelTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/OpenIdChannelTests.cs @@ -1,102 +1,102 @@ -//----------------------------------------------------------------------- -// <copyright file="OpenIdChannelTests.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.OpenId.ChannelElements { - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Text; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.Messaging.Bindings; - using DotNetOpenAuth.Messaging.Reflection; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.ChannelElements; - using Microsoft.VisualStudio.TestTools.UnitTesting; - - [TestClass] - public class OpenIdChannelTests : TestBase { - private static readonly TimeSpan maximumMessageAge = TimeSpan.FromHours(3); // good for tests, too long for production - private OpenIdChannel channel; - private OpenIdChannel_Accessor accessor; - private Mocks.TestWebRequestHandler webHandler; - - [TestInitialize] - public void Setup() { - this.webHandler = new Mocks.TestWebRequestHandler(); - this.channel = new OpenIdChannel(new AssociationMemoryStore<Uri>(), new NonceMemoryStore(maximumMessageAge)); - this.accessor = OpenIdChannel_Accessor.AttachShadow(this.channel); - this.channel.WebRequestHandler = this.webHandler; - } - - [TestMethod] - public void Ctor() { - // Verify that the channel stack includes the expected types. - // While other binding elements may be substituted for these, we'd then have - // to test them. Since we're not testing them in the OpenID battery of tests, - // we make sure they are the standard ones so that we trust they are tested - // elsewhere by the testing library. - var replayElement = (StandardReplayProtectionBindingElement)this.channel.BindingElements.SingleOrDefault(el => el is StandardReplayProtectionBindingElement); - Assert.IsTrue(this.channel.BindingElements.Any(el => el is StandardExpirationBindingElement)); - Assert.IsNotNull(replayElement); - - // Verify that empty nonces are allowed, since OpenID 2.0 allows this. - Assert.IsTrue(replayElement.AllowZeroLengthNonce); - } - - /// <summary> - /// Verifies that the channel sends direct message requests as HTTP POST requests. - /// </summary> - [TestMethod] - public void DirectRequestsUsePost() { - IDirectedProtocolMessage requestMessage = new Mocks.TestDirectedMessage(MessageTransport.Direct) { - Recipient = new Uri("http://host"), - Name = "Andrew", - }; - HttpWebRequest httpRequest = this.accessor.CreateHttpRequest(requestMessage); - Assert.AreEqual("POST", httpRequest.Method); - StringAssert.Contains(this.webHandler.RequestEntityAsString, "Name=Andrew"); - } - - /// <summary> - /// Verifies that direct response messages are encoded using Key Value Form. - /// </summary> - /// <remarks> - /// The validity of the actual KVF encoding is not checked here. We assume that the KVF encoding - /// class is verified elsewhere. We're only checking that the KVF class is being used by the - /// <see cref="OpenIdChannel.SendDirectMessageResponse"/> method. - /// </remarks> - [TestMethod] - public void DirectResponsesSentUsingKeyValueForm() { - IProtocolMessage message = MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired); - MessageDictionary messageFields = new MessageDictionary(message); - byte[] expectedBytes = KeyValueFormEncoding.GetBytes(messageFields); - string expectedContentType = OpenIdChannel_Accessor.KeyValueFormContentType; - - UserAgentResponse directResponse = this.accessor.SendDirectMessageResponse(message); - Assert.AreEqual(expectedContentType, directResponse.Headers[HttpResponseHeader.ContentType]); - byte[] actualBytes = new byte[directResponse.ResponseStream.Length]; - directResponse.ResponseStream.Read(actualBytes, 0, actualBytes.Length); - Assert.IsTrue(MessagingUtilities.AreEquivalent(expectedBytes, actualBytes)); - } - - /// <summary> - /// Verifies that direct message responses are read in using the Key Value Form decoder. - /// </summary> - [TestMethod] - public void DirectResponsesReceivedAsKeyValueForm() { - var fields = new Dictionary<string, string> { - { "var1", "value1" }, - { "var2", "value2" }, - }; - var response = new DirectWebResponse { - ResponseStream = new MemoryStream(KeyValueFormEncoding.GetBytes(fields)), - }; - Assert.IsTrue(MessagingUtilities.AreEquivalent(fields, this.accessor.ReadFromResponseInternal(response))); - } - } -} +//-----------------------------------------------------------------------
+// <copyright file="OpenIdChannelTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId.ChannelElements {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Net;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.Messaging.Reflection;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.ChannelElements;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class OpenIdChannelTests : TestBase {
+ private static readonly TimeSpan maximumMessageAge = TimeSpan.FromHours(3); // good for tests, too long for production
+ private OpenIdChannel channel;
+ private OpenIdChannel_Accessor accessor;
+ private Mocks.TestWebRequestHandler webHandler;
+
+ [TestInitialize]
+ public void Setup() {
+ this.webHandler = new Mocks.TestWebRequestHandler();
+ this.channel = new OpenIdChannel(new AssociationMemoryStore<Uri>(), new NonceMemoryStore(maximumMessageAge), new PrivateSecretMemoryStore());
+ this.accessor = OpenIdChannel_Accessor.AttachShadow(this.channel);
+ this.channel.WebRequestHandler = this.webHandler;
+ }
+
+ [TestMethod]
+ public void Ctor() {
+ // Verify that the channel stack includes the expected types.
+ // While other binding elements may be substituted for these, we'd then have
+ // to test them. Since we're not testing them in the OpenID battery of tests,
+ // we make sure they are the standard ones so that we trust they are tested
+ // elsewhere by the testing library.
+ var replayElement = (StandardReplayProtectionBindingElement)this.channel.BindingElements.SingleOrDefault(el => el is StandardReplayProtectionBindingElement);
+ Assert.IsTrue(this.channel.BindingElements.Any(el => el is StandardExpirationBindingElement));
+ Assert.IsNotNull(replayElement);
+
+ // Verify that empty nonces are allowed, since OpenID 2.0 allows this.
+ Assert.IsTrue(replayElement.AllowZeroLengthNonce);
+ }
+
+ /// <summary>
+ /// Verifies that the channel sends direct message requests as HTTP POST requests.
+ /// </summary>
+ [TestMethod]
+ public void DirectRequestsUsePost() {
+ IDirectedProtocolMessage requestMessage = new Mocks.TestDirectedMessage(MessageTransport.Direct) {
+ Recipient = new Uri("http://host"),
+ Name = "Andrew",
+ };
+ HttpWebRequest httpRequest = this.accessor.CreateHttpRequest(requestMessage);
+ Assert.AreEqual("POST", httpRequest.Method);
+ StringAssert.Contains(this.webHandler.RequestEntityAsString, "Name=Andrew");
+ }
+
+ /// <summary>
+ /// Verifies that direct response messages are encoded using Key Value Form.
+ /// </summary>
+ /// <remarks>
+ /// The validity of the actual KVF encoding is not checked here. We assume that the KVF encoding
+ /// class is verified elsewhere. We're only checking that the KVF class is being used by the
+ /// <see cref="OpenIdChannel.SendDirectMessageResponse"/> method.
+ /// </remarks>
+ [TestMethod]
+ public void DirectResponsesSentUsingKeyValueForm() {
+ IProtocolMessage message = MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired);
+ MessageDictionary messageFields = new MessageDictionary(message);
+ byte[] expectedBytes = KeyValueFormEncoding.GetBytes(messageFields);
+ string expectedContentType = OpenIdChannel_Accessor.KeyValueFormContentType;
+
+ UserAgentResponse directResponse = this.accessor.SendDirectMessageResponse(message);
+ Assert.AreEqual(expectedContentType, directResponse.Headers[HttpResponseHeader.ContentType]);
+ byte[] actualBytes = new byte[directResponse.ResponseStream.Length];
+ directResponse.ResponseStream.Read(actualBytes, 0, actualBytes.Length);
+ Assert.IsTrue(MessagingUtilities.AreEquivalent(expectedBytes, actualBytes));
+ }
+
+ /// <summary>
+ /// Verifies that direct message responses are read in using the Key Value Form decoder.
+ /// </summary>
+ [TestMethod]
+ public void DirectResponsesReceivedAsKeyValueForm() {
+ var fields = new Dictionary<string, string> {
+ { "var1", "value1" },
+ { "var2", "value2" },
+ };
+ var response = new DirectWebResponse {
+ ResponseStream = new MemoryStream(KeyValueFormEncoding.GetBytes(fields)),
+ };
+ Assert.IsTrue(MessagingUtilities.AreEquivalent(fields, this.accessor.ReadFromResponseInternal(response)));
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs index 4e74525..3b925a8 100644 --- a/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs +++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs @@ -1,47 +1,47 @@ -//----------------------------------------------------------------------- -// <copyright file="OpenIdCoordinator.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.OpenId { - using System; - using DotNetOpenAuth.Messaging.Bindings; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; - using DotNetOpenAuth.Test.Mocks; - - internal class OpenIdCoordinator : CoordinatorBase<OpenIdRelyingParty, OpenIdProvider> { - internal OpenIdCoordinator(Action<OpenIdRelyingParty> rpAction, Action<OpenIdProvider> opAction) - : base(rpAction, opAction) { - } - - internal OpenIdProvider Provider { get; set; } - - internal OpenIdRelyingParty RelyingParty { get; set; } - - internal override void Run() { - this.EnsurePartiesAreInitialized(); - var rpCoordinatingChannel = new CoordinatingChannel(this.RelyingParty.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); - var opCoordinatingChannel = new CoordinatingChannel(this.Provider.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); - rpCoordinatingChannel.RemoteChannel = opCoordinatingChannel; - opCoordinatingChannel.RemoteChannel = rpCoordinatingChannel; - - this.RelyingParty.Channel = rpCoordinatingChannel; - this.Provider.Channel = opCoordinatingChannel; - - RunCore(this.RelyingParty, this.Provider); - } - - private void EnsurePartiesAreInitialized() { - if (this.RelyingParty == null) { - this.RelyingParty = new OpenIdRelyingParty(new AssociationMemoryStore<Uri>(), new NonceMemoryStore(TimeSpan.FromHours(3))); - } - - if (this.Provider == null) { - this.Provider = new OpenIdProvider(new AssociationMemoryStore<AssociationRelyingPartyType>(), new NonceMemoryStore(TimeSpan.FromHours(3))); - } - } - } -} +//-----------------------------------------------------------------------
+// <copyright file="OpenIdCoordinator.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId {
+ using System;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Provider;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using DotNetOpenAuth.Test.Mocks;
+
+ internal class OpenIdCoordinator : CoordinatorBase<OpenIdRelyingParty, OpenIdProvider> {
+ internal OpenIdCoordinator(Action<OpenIdRelyingParty> rpAction, Action<OpenIdProvider> opAction)
+ : base(rpAction, opAction) {
+ }
+
+ internal OpenIdProvider Provider { get; set; }
+
+ internal OpenIdRelyingParty RelyingParty { get; set; }
+
+ internal override void Run() {
+ this.EnsurePartiesAreInitialized();
+ var rpCoordinatingChannel = new CoordinatingChannel(this.RelyingParty.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter);
+ var opCoordinatingChannel = new CoordinatingChannel(this.Provider.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter);
+ rpCoordinatingChannel.RemoteChannel = opCoordinatingChannel;
+ opCoordinatingChannel.RemoteChannel = rpCoordinatingChannel;
+
+ this.RelyingParty.Channel = rpCoordinatingChannel;
+ this.Provider.Channel = opCoordinatingChannel;
+
+ RunCore(this.RelyingParty, this.Provider);
+ }
+
+ private void EnsurePartiesAreInitialized() {
+ if (this.RelyingParty == null) {
+ this.RelyingParty = new OpenIdRelyingParty(new AssociationMemoryStore<Uri>(), new NonceMemoryStore(TimeSpan.FromHours(3)), new PrivateSecretMemoryStore());
+ }
+
+ if (this.Provider == null) {
+ this.Provider = new OpenIdProvider(new AssociationMemoryStore<AssociationRelyingPartyType>(), new NonceMemoryStore(TimeSpan.FromHours(3)));
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs index c68ba0c..d53810a 100644 --- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdRelyingPartyTests.cs @@ -1,35 +1,35 @@ -//----------------------------------------------------------------------- -// <copyright file="OpenIdRelyingPartyTests.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.OpenId.RelyingParty { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging.Bindings; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; - using Microsoft.VisualStudio.TestTools.UnitTesting; - - [TestClass] - public class OpenIdRelyingPartyTests : OpenIdTestBase { - [TestInitialize] - public override void SetUp() { - base.SetUp(); - } - - [TestMethod, Ignore] // ignored, pending work to make dumb mode a supported scenario. - public void CtorNullAssociationStore() { - new OpenIdRelyingParty(null, null); - } - - [TestMethod, ExpectedException(typeof(ArgumentNullException))] - public void SecuritySettingsSetNull() { - var rp = new OpenIdRelyingParty(new AssociationMemoryStore<Uri>(), new NonceMemoryStore(TimeSpan.FromMinutes(5))); - rp.SecuritySettings = null; - } - } -} +//-----------------------------------------------------------------------
+// <copyright file="OpenIdRelyingPartyTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId.RelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class OpenIdRelyingPartyTests : OpenIdTestBase {
+ [TestInitialize]
+ public override void SetUp() {
+ base.SetUp();
+ }
+
+ [TestMethod, Ignore] // ignored, pending work to make dumb mode a supported scenario.
+ public void CtorNullAssociationStore() {
+ new OpenIdRelyingParty(null, null, null);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void SecuritySettingsSetNull() {
+ var rp = new OpenIdRelyingParty(new AssociationMemoryStore<Uri>(), new NonceMemoryStore(TimeSpan.FromMinutes(5)), new PrivateSecretMemoryStore());
+ rp.SecuritySettings = null;
+ }
+ }
+}
|