diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2008-10-08 11:53:25 -0700 |
---|---|---|
committer | Andrew <andrewarnott@gmail.com> | 2008-10-08 11:53:25 -0700 |
commit | 1e707db5f5551a545ad0bbcc71df9d19f2a79029 (patch) | |
tree | e4824dcff0ea75d650314c1826023f0e3b382443 | |
parent | 2276413c733f6a26e9b366214bdfb5677e711c75 (diff) | |
download | DotNetOpenAuth-1e707db5f5551a545ad0bbcc71df9d19f2a79029.zip DotNetOpenAuth-1e707db5f5551a545ad0bbcc71df9d19f2a79029.tar.gz DotNetOpenAuth-1e707db5f5551a545ad0bbcc71df9d19f2a79029.tar.bz2 |
Reworked cloning of signing binding elements, and a bit of the appendix sample test.
8 files changed, 53 insertions, 44 deletions
diff --git a/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs b/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs index debff53..46d7950 100644 --- a/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs +++ b/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs @@ -29,27 +29,25 @@ namespace DotNetOAuth.Test { },
};
MessageReceivingEndpoint accessPhotoEndpoint = new MessageReceivingEndpoint("http://photos.example.net/photos?file=vacation.jpg&size=original", HttpDeliveryMethod.AuthorizationHeaderRequest | HttpDeliveryMethod.GetRequest);
- var sp = new ServiceProvider(serviceDescription, new InMemoryTokenManager());
- Consumer consumer = new Consumer(serviceDescription, new InMemoryTokenManager()) {
- ConsumerKey = "dpf43f3p2l4k3l03",
- ConsumerSecret = "kd94hf93k423kf44",
- };
+ string consumerKey = "dpf43f3p2l4k3l03";
+ string consumerSecret = "kd94hf93k423kf44";
Coordinator coordinator = new Coordinator(
- channel => {
- consumer.Channel = channel;
+ serviceDescription,
+ consumer => {
+ consumer.ConsumerKey = consumerKey;
+ consumer.ConsumerSecret = consumerSecret;
consumer.RequestUserAuthorization(new Uri("http://printer.example.com/request_token_ready"), null, null);
string accessToken = consumer.ProcessUserAuthorization().AccessToken;
var photoRequest = consumer.CreateAuthorizedRequestInternal(accessPhotoEndpoint, accessToken);
- Response protectedPhoto = channel.RequestProtectedResource(photoRequest);
+ Response protectedPhoto = ((CoordinatingOAuthChannel)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);
},
- channel => {
- sp.Channel = channel;
- ((InMemoryTokenManager)sp.TokenManager).AddConsumer(consumer.ConsumerKey, consumer.ConsumerSecret);
+ sp => {
+ ((InMemoryTokenManager)sp.TokenManager).AddConsumer(consumerKey, consumerSecret);
var requestTokenMessage = sp.ReadTokenRequest();
sp.SendUnauthorizedTokenResponse(requestTokenMessage, null);
var authRequest = sp.ReadAuthorizationRequest();
@@ -58,7 +56,7 @@ namespace DotNetOAuth.Test { var accessRequest = sp.ReadAccessTokenRequest();
sp.SendAccessToken(accessRequest, null);
string accessToken = sp.GetProtectedResourceAuthorization().AccessToken;
- channel.SendDirectRawResponse(new Response {
+ ((CoordinatingOAuthChannel)sp.Channel).SendDirectRawResponse(new Response {
ResponseStream = new MemoryStream(new byte[] { 0x33, 0x66 }),
Headers = new WebHeaderCollection {
{ HttpResponseHeader.ContentType, "image/jpeg" },
@@ -66,7 +64,6 @@ namespace DotNetOAuth.Test { });
});
- coordinator.SigningElement = (ITamperProtectionChannelBindingElement)consumer.Channel.BindingElements.Single(el => el is ITamperProtectionChannelBindingElement);
coordinator.Run();
}
}
diff --git a/src/DotNetOAuth.Test/Scenarios/Coordinator.cs b/src/DotNetOAuth.Test/Scenarios/Coordinator.cs index f5e6adc..67b4257 100644 --- a/src/DotNetOAuth.Test/Scenarios/Coordinator.cs +++ b/src/DotNetOAuth.Test/Scenarios/Coordinator.cs @@ -6,21 +6,28 @@ namespace DotNetOAuth.Test.Scenarios {
using System;
+ using System.Linq;
using System.Threading;
using DotNetOAuth.Messaging;
+ using DotNetOAuth.Test.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
/// <summary>
/// Runs a Consumer and Service Provider simultaneously so they can interact in a full simulation.
/// </summary>
internal class Coordinator {
- private Actor consumerAction;
- private Actor serviceProviderAction;
+ private ServiceProviderDescription serviceDescription;
+ private Action<Consumer> consumerAction;
+ private Action<ServiceProvider> serviceProviderAction;
/// <summary>Initializes a new instance of the <see cref="Coordinator"/> class.</summary>
+ /// <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 Coordinator(Actor consumerAction, Actor serviceProviderAction) {
+ internal Coordinator(ServiceProviderDescription serviceDescription, Action<Consumer> consumerAction, Action<ServiceProvider> serviceProviderAction) {
+ if (serviceDescription == null) {
+ throw new ArgumentNullException("serviceDescription");
+ }
if (consumerAction == null) {
throw new ArgumentNullException("consumerAction");
}
@@ -28,30 +35,19 @@ namespace DotNetOAuth.Test.Scenarios { throw new ArgumentNullException("serviceProviderAction");
}
+ this.serviceDescription = serviceDescription;
this.consumerAction = consumerAction;
this.serviceProviderAction = serviceProviderAction;
}
- internal delegate void Actor(CoordinatingOAuthChannel channel);
-
- /// <summary>
- /// Gets or sets the signing element the channels should clone and use.
- /// </summary>
- internal ITamperProtectionChannelBindingElement SigningElement { get; set; }
-
/// <summary>
/// Starts the simulation.
/// </summary>
internal void Run() {
- if (this.SigningElement == null) {
- throw new InvalidOperationException("SigningElement must be set first.");
- }
-
- // Clone and reset the template signing binding element.
- var consumerSigningElement = (ITamperProtectionChannelBindingElement)this.SigningElement.Clone();
- var spSigningElement = (ITamperProtectionChannelBindingElement)this.SigningElement.Clone();
- consumerSigningElement.SignatureVerificationCallback = null;
- spSigningElement.SignatureVerificationCallback = null;
+ // Clone the template signing binding element.
+ var signingElement = this.serviceDescription.CreateTamperProtectionElement();
+ var consumerSigningElement = signingElement.Clone();
+ var spSigningElement = signingElement.Clone();
// Prepare channels that will pass messages directly back and forth.
CoordinatingOAuthChannel consumerChannel = new CoordinatingOAuthChannel(consumerSigningElement, true);
@@ -59,14 +55,22 @@ namespace DotNetOAuth.Test.Scenarios { consumerChannel.RemoteChannel = serviceProviderChannel;
serviceProviderChannel.RemoteChannel = consumerChannel;
+ // Prepare the Consumer and Service Provider objects
+ Consumer consumer = new Consumer(this.serviceDescription, new InMemoryTokenManager()) {
+ Channel = consumerChannel,
+ };
+ ServiceProvider serviceProvider = new ServiceProvider(this.serviceDescription, new InMemoryTokenManager()) {
+ Channel = serviceProviderChannel,
+ };
+
Thread consumerThread = null, serviceProviderThread = null;
Exception failingException = null;
// Each thread we create needs a surrounding exception catcher so that we can
// terminate the other thread and inform the test host that the test failed.
- Action<Actor, CoordinatingOAuthChannel> safeWrapper = (actor, channel) => {
+ Action<Action> safeWrapper = (action) => {
try {
- actor(channel);
+ action();
} catch (Exception ex) {
// We may be the second thread in an ThreadAbortException, so check the "flag"
if (failingException == null) {
@@ -82,8 +86,8 @@ namespace DotNetOAuth.Test.Scenarios { // Run the threads, and wait for them to complete.
// If this main thread is aborted (test run aborted), go ahead and abort the other two threads.
- consumerThread = new Thread(() => { safeWrapper(consumerAction, consumerChannel); });
- serviceProviderThread = new Thread(() => { safeWrapper(serviceProviderAction, serviceProviderChannel); });
+ consumerThread = new Thread(() => { safeWrapper(() => { consumerAction(consumer); }); });
+ serviceProviderThread = new Thread(() => { safeWrapper(() => { serviceProviderAction(serviceProvider); }); });
try {
consumerThread.Start();
serviceProviderThread.Start();
diff --git a/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs b/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs index 6b41542..f1455e8 100644 --- a/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs +++ b/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs @@ -8,6 +8,7 @@ namespace DotNetOAuth.ChannelElements { using System;
using System.Security.Cryptography;
using System.Text;
+ using DotNetOAuth.Messaging;
/// <summary>
/// A binding element that signs outgoing messages and verifies the signature on incoming messages.
@@ -41,7 +42,7 @@ namespace DotNetOAuth.ChannelElements { /// Clones this instance.
/// </summary>
/// <returns>A new instance of the binding element.</returns>
- protected override object Clone() {
+ protected override ITamperProtectionChannelBindingElement Clone() {
return new HmacSha1SigningBindingElement();
}
}
diff --git a/src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs b/src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs index 9cb052e..7ca5b7f 100644 --- a/src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs +++ b/src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs @@ -48,7 +48,7 @@ namespace DotNetOAuth.ChannelElements { /// Clones this instance.
/// </summary>
/// <returns>A new instance of the binding element.</returns>
- protected override object Clone() {
+ protected override ITamperProtectionChannelBindingElement Clone() {
return new PlainTextSigningBindingElement();
}
}
diff --git a/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs b/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs index e15f4b6..4862a54 100644 --- a/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs +++ b/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs @@ -8,6 +8,7 @@ namespace DotNetOAuth.ChannelElements { using System;
using System.Security.Cryptography;
using System.Text;
+ using DotNetOAuth.Messaging;
/// <summary>
/// A binding element that signs outgoing messages and verifies the signature on incoming messages.
@@ -40,7 +41,7 @@ namespace DotNetOAuth.ChannelElements { /// Clones this instance.
/// </summary>
/// <returns>A new instance of the binding element.</returns>
- protected override object Clone() {
+ protected override ITamperProtectionChannelBindingElement Clone() {
return new RsaSha1SigningBindingElement();
}
}
diff --git a/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs b/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs index aa6f19f..7850bd8 100644 --- a/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs +++ b/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs @@ -54,8 +54,8 @@ namespace DotNetOAuth.ChannelElements { /// <returns>
/// A new object that is a copy of this instance.
/// </returns>
- object ICloneable.Clone() {
- var clone = (SigningBindingElementBase)this.Clone();
+ ITamperProtectionChannelBindingElement ITamperProtectionChannelBindingElement.Clone() {
+ ITamperProtectionChannelBindingElement clone = this.Clone();
clone.SignatureVerificationCallback = this.SignatureVerificationCallback;
return clone;
}
@@ -179,7 +179,7 @@ namespace DotNetOAuth.ChannelElements { /// Implementations of this method need not clone the SignatureVerificationCallback member, as the
/// <see cref="SigningBindingElementBase"/> class does this.
/// </remarks>
- protected abstract object Clone();
+ protected abstract ITamperProtectionChannelBindingElement Clone();
/// <summary>
/// Calculates a signature for a given message.
diff --git a/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs b/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs index 9655f2c..dada28e 100644 --- a/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs +++ b/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs @@ -123,7 +123,7 @@ namespace DotNetOAuth.ChannelElements { /// <returns>
/// A new object that is a copy of this instance.
/// </returns>
- object ICloneable.Clone() {
+ ITamperProtectionChannelBindingElement ITamperProtectionChannelBindingElement.Clone() {
return new SigningBindingElementChain(this.signers.Select(el => (ITamperProtectionChannelBindingElement)el.Clone()).ToArray());
}
diff --git a/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs b/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs index cedd61c..b84b6e7 100644 --- a/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs +++ b/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs @@ -12,12 +12,18 @@ namespace DotNetOAuth.Messaging { /// An interface that must be implemented by message transforms/validators in order
/// to be included in the channel stack.
/// </summary>
- public interface ITamperProtectionChannelBindingElement : IChannelBindingElement, ICloneable {
+ public interface ITamperProtectionChannelBindingElement : IChannelBindingElement {
/// <summary>
/// Gets or sets the delegate that will initialize the non-serialized properties necessary on a signed
/// message so that its signature can be correctly calculated for verification.
/// May be null for Consumers (who never have to verify signatures).
/// </summary>
Action<ITamperResistantOAuthMessage> SignatureVerificationCallback { get; set; }
+
+ /// <summary>
+ /// Clones this instance.
+ /// </summary>
+ /// <returns>The cloned instance.</returns>
+ ITamperProtectionChannelBindingElement Clone();
}
}
|