diff options
Diffstat (limited to 'src/DotNetOpenAuth.Test/OAuth/ChannelElements')
3 files changed, 118 insertions, 7 deletions
diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs index 2596bc5..fcdb5e8 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs @@ -14,7 +14,7 @@ namespace DotNetOpenAuth.Test.ChannelElements { public class HmacSha1SigningBindingElementTests : MessagingTestBase { [TestMethod] public void SignatureTest() { - UnauthorizedTokenRequest message = SigningBindingElementBaseTests.CreateTestRequestTokenMessage(this.MessageDescriptions); + UnauthorizedTokenRequest message = SigningBindingElementBaseTests.CreateTestRequestTokenMessage(this.MessageDescriptions, null); HmacSha1SigningBindingElement_Accessor hmac = new HmacSha1SigningBindingElement_Accessor(); hmac.Channel = new TestChannel(this.MessageDescriptions); diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs index 401153d..449a033 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs @@ -15,6 +15,7 @@ namespace DotNetOpenAuth.Test.ChannelElements { using System.Xml; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.Test.Mocks; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -69,6 +70,41 @@ namespace DotNetOpenAuth.Test.ChannelElements { this.ParameterizedReceiveTest(HttpDeliveryMethods.AuthorizationHeaderRequest); } + /// <summary> + /// Verifies that the OAuth ReadFromRequest method gathers parameters + /// from the Authorization header, the query string and the entity form data. + /// </summary> + [TestMethod] + public void ReadFromRequestAuthorizationScattered() { + // Start by creating a standard POST HTTP request. + var fields = new Dictionary<string, string> { + { "age", "15" }, + }; + HttpRequestInfo requestInfo = CreateHttpRequestInfo(HttpDeliveryMethods.PostRequest, fields); + + // Now add another field to the request URL + UriBuilder builder = new UriBuilder(requestInfo.Url); + builder.Query = "Name=Andrew"; + requestInfo.Url = builder.Uri; + requestInfo.RawUrl = builder.Path + builder.Query + builder.Fragment; + + // Finally, add an Authorization header + fields = new Dictionary<string, string> { + { "Location", "http://hostb/pathB" }, + { "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) }, + }; + requestInfo.Headers.Add(HttpRequestHeader.Authorization, CreateAuthorizationHeader(fields)); + + IDirectedProtocolMessage requestMessage = this.channel.ReadFromRequest(requestInfo); + + Assert.IsNotNull(requestMessage); + Assert.IsInstanceOfType(requestMessage, typeof(TestMessage)); + TestMessage testMessage = (TestMessage)requestMessage; + Assert.AreEqual(15, testMessage.Age); + Assert.AreEqual("Andrew", testMessage.Name); + Assert.AreEqual("http://hostb/pathB", testMessage.Location.AbsoluteUri); + } + [TestMethod] public void ReadFromRequestForm() { this.ParameterizedReceiveTest(HttpDeliveryMethods.PostRequest); @@ -144,6 +180,42 @@ namespace DotNetOpenAuth.Test.ChannelElements { this.ParameterizedRequestTest(HttpDeliveryMethods.AuthorizationHeaderRequest); } + /// <summary> + /// Verifies that message parts can be distributed to the query, form, and Authorization header. + /// </summary> + [TestMethod] + public void RequestUsingAuthorizationHeaderScattered() { + TestDirectedMessage request = new TestDirectedMessage(MessageTransport.Direct) { + Age = 15, + Name = "Andrew", + Location = new Uri("http://hostb/pathB"), + Recipient = new Uri("http://localtest"), + Timestamp = DateTime.UtcNow, + HttpMethods = HttpDeliveryMethods.AuthorizationHeaderRequest, + }; + + // ExtraData should appear in the form since this is a POST request, + // and only official message parts get a place in the Authorization header. + ((IProtocolMessage)request).ExtraData["appearinform"] = "formish"; + request.Recipient = new Uri("http://localhost/?appearinquery=queryish"); + request.HttpMethods = HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest; + + HttpWebRequest webRequest = this.channel.InitializeRequest(request); + Assert.IsNotNull(webRequest); + Assert.AreEqual("POST", webRequest.Method); + Assert.AreEqual(request.Recipient, webRequest.RequestUri); + + var declaredParts = new Dictionary<string, string> { + { "age", request.Age.ToString() }, + { "Name", request.Name }, + { "Location", request.Location.AbsoluteUri }, + { "Timestamp", XmlConvert.ToString(request.Timestamp, XmlDateTimeSerializationMode.Utc) }, + }; + + Assert.AreEqual(CreateAuthorizationHeader(declaredParts), webRequest.Headers[HttpRequestHeader.Authorization]); + Assert.AreEqual("appearinform=formish", this.webRequestHandler.RequestEntityAsString); + } + [TestMethod] public void RequestUsingGet() { this.ParameterizedRequestTest(HttpDeliveryMethods.GetRequest); @@ -171,9 +243,7 @@ namespace DotNetOpenAuth.Test.ChannelElements { } private static string CreateAuthorizationHeader(IDictionary<string, string> fields) { - if (fields == null) { - throw new ArgumentNullException("fields"); - } + ErrorUtilities.VerifyArgumentNotNull(fields, "fields"); StringBuilder authorization = new StringBuilder(); authorization.Append("OAuth "); @@ -219,6 +289,7 @@ namespace DotNetOpenAuth.Test.ChannelElements { HttpRequestInfo request = new HttpRequestInfo { HttpMethod = method, Url = requestUri.Uri, + RawUrl = requestUri.Path + requestUri.Query + requestUri.Fragment, Headers = headers, InputStream = ms, }; @@ -230,6 +301,7 @@ namespace DotNetOpenAuth.Test.ChannelElements { HttpRequestInfo info = new HttpRequestInfo { HttpMethod = request.Method, Url = request.RequestUri, + RawUrl = request.RequestUri.AbsolutePath + request.RequestUri.Query + request.RequestUri.Fragment, Headers = request.Headers, InputStream = postEntity, }; diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs index e890b6f..93c0b3f 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs @@ -15,15 +15,54 @@ namespace DotNetOpenAuth.Test.ChannelElements { public class SigningBindingElementBaseTests : MessagingTestBase { [TestMethod] public void BaseSignatureStringTest() { - UnauthorizedTokenRequest message = CreateTestRequestTokenMessage(this.MessageDescriptions); + // Tests a message sent by HTTP GET, with no query string included in the endpoint. + UnauthorizedTokenRequest message = CreateTestRequestTokenMessage( + this.MessageDescriptions, + new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest)); + Assert.AreEqual( + "GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_consumer_key%3Dnerdbank.org%26oauth_nonce%3Dfe4045a3f0efdd1e019fa8f8ae3f5c38%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222665749%26oauth_version%3D1.0%26scope%3Dhttp%253A%252F%252Fwww.google.com%252Fm8%252Ffeeds%252F", + SigningBindingElementBase_Accessor.ConstructSignatureBaseString(message, MessageDictionary_Accessor.AttachShadow(this.MessageDescriptions.GetAccessor(message)))); + + // Test HTTP GET with an attached query string. We're elevating the scope parameter to the query string + // and removing it from the extradata dictionary. This should NOT affect the base signature string. + message = CreateTestRequestTokenMessage( + this.MessageDescriptions, + new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www.google.com/m8/feeds/", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest)); + message.ExtraData.Remove("scope"); // remove it from ExtraData since we put it in the URL + Assert.AreEqual( + "GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_consumer_key%3Dnerdbank.org%26oauth_nonce%3Dfe4045a3f0efdd1e019fa8f8ae3f5c38%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222665749%26oauth_version%3D1.0%26scope%3Dhttp%253A%252F%252Fwww.google.com%252Fm8%252Ffeeds%252F", + SigningBindingElementBase_Accessor.ConstructSignatureBaseString(message, MessageDictionary_Accessor.AttachShadow(this.MessageDescriptions.GetAccessor(message)))); + + // Test HTTP POST, with query string as well + message = CreateTestRequestTokenMessage( + this.MessageDescriptions, + new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www.google.com/m8/feeds/", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest)); + message.ExtraData.Remove("scope"); // remove it from ExtraData since we put it in the URL + Assert.AreEqual( + "GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_consumer_key%3Dnerdbank.org%26oauth_nonce%3Dfe4045a3f0efdd1e019fa8f8ae3f5c38%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222665749%26oauth_version%3D1.0%26scope%3Dhttp%253A%252F%252Fwww.google.com%252Fm8%252Ffeeds%252F", + SigningBindingElementBase_Accessor.ConstructSignatureBaseString(message, MessageDictionary_Accessor.AttachShadow(this.MessageDescriptions.GetAccessor(message)))); + + // Test HTTP POST, with query string, but not using the Authorization header + message = CreateTestRequestTokenMessage( + this.MessageDescriptions, + new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www.google.com/m8/feeds/", HttpDeliveryMethods.PostRequest)); + message.ExtraData.Remove("scope"); // remove it from ExtraData since we put it in the URL + Assert.AreEqual( + "GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_consumer_key%3Dnerdbank.org%26oauth_nonce%3Dfe4045a3f0efdd1e019fa8f8ae3f5c38%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222665749%26oauth_version%3D1.0%26scope%3Dhttp%253A%252F%252Fwww.google.com%252Fm8%252Ffeeds%252F", + SigningBindingElementBase_Accessor.ConstructSignatureBaseString(message, MessageDictionary_Accessor.AttachShadow(this.MessageDescriptions.GetAccessor(message)))); + // This is a simulation of receiving the message, where the query string is still in the URL, + // but has been read into ExtraData, so parameters in the query string appear twice. + message = CreateTestRequestTokenMessage( + this.MessageDescriptions, + new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www.google.com/m8/feeds/", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest)); Assert.AreEqual( "GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_consumer_key%3Dnerdbank.org%26oauth_nonce%3Dfe4045a3f0efdd1e019fa8f8ae3f5c38%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222665749%26oauth_version%3D1.0%26scope%3Dhttp%253A%252F%252Fwww.google.com%252Fm8%252Ffeeds%252F", SigningBindingElementBase_Accessor.ConstructSignatureBaseString(message, MessageDictionary_Accessor.AttachShadow(this.MessageDescriptions.GetAccessor(message)))); } - internal static UnauthorizedTokenRequest CreateTestRequestTokenMessage(MessageDescriptionCollection messageDescriptions) { - MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest); + internal static UnauthorizedTokenRequest CreateTestRequestTokenMessage(MessageDescriptionCollection messageDescriptions, MessageReceivingEndpoint endpoint) { + endpoint = endpoint ?? new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest); UnauthorizedTokenRequest message = new UnauthorizedTokenRequest(endpoint); message.ConsumerKey = "nerdbank.org"; ((ITamperResistantOAuthMessage)message).ConsumerSecret = "nerdbanksecret"; |