diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2008-10-07 21:36:29 -0700 |
---|---|---|
committer | Andrew <andrewarnott@gmail.com> | 2008-10-07 21:36:29 -0700 |
commit | 29d897769f3e7a9568fa668836807d9a31b5fabc (patch) | |
tree | fb9a91e0804ed5a92d183268309ea0234732682b /src | |
parent | 43188751fe5c64c8f29f62e448a2c6a798910328 (diff) | |
download | DotNetOpenAuth-29d897769f3e7a9568fa668836807d9a31b5fabc.zip DotNetOpenAuth-29d897769f3e7a9568fa668836807d9a31b5fabc.tar.gz DotNetOpenAuth-29d897769f3e7a9568fa668836807d9a31b5fabc.tar.bz2 |
Added strong-typed request token message to sample.
This proves that messages can be derived from and tailored to provide type-safe additions where the OAuth protocol permits it.
As can be seen, several more types and members had to be made public for this to work.
Diffstat (limited to 'src')
13 files changed, 48 insertions, 36 deletions
diff --git a/src/DotNetOAuth.Test/Mocks/InMemoryTokenManager.cs b/src/DotNetOAuth.Test/Mocks/InMemoryTokenManager.cs index 87d7608..7f8c3b7 100644 --- a/src/DotNetOAuth.Test/Mocks/InMemoryTokenManager.cs +++ b/src/DotNetOAuth.Test/Mocks/InMemoryTokenManager.cs @@ -9,6 +9,7 @@ namespace DotNetOAuth.Test.Mocks { using System.Collections.Generic;
using System.Diagnostics;
using DotNetOAuth.ChannelElements;
+ using DotNetOAuth.Messages;
internal class InMemoryTokenManager : ITokenManager {
private Dictionary<string, string> consumersAndSecrets = new Dictionary<string, string>();
@@ -34,9 +35,9 @@ namespace DotNetOAuth.Test.Mocks { return this.tokensAndSecrets[token];
}
- public void StoreNewRequestToken(string consumerKey, string requestToken, string requestTokenSecret, IDictionary<string, string> requestParameters, IDictionary<string, string> responseParameters) {
- this.tokensAndSecrets[requestToken] = requestTokenSecret;
- this.requestTokens.Add(requestToken, false);
+ public void StoreNewRequestToken(RequestTokenMessage request, UnauthorizedRequestTokenMessage response) {
+ this.tokensAndSecrets[response.RequestToken] = response.TokenSecret;
+ this.requestTokens.Add(response.RequestToken, false);
}
/// <summary>
diff --git a/src/DotNetOAuth/ChannelElements/ITokenManager.cs b/src/DotNetOAuth/ChannelElements/ITokenManager.cs index 4cb6ce7..e3b218b 100644 --- a/src/DotNetOAuth/ChannelElements/ITokenManager.cs +++ b/src/DotNetOAuth/ChannelElements/ITokenManager.cs @@ -9,6 +9,7 @@ namespace DotNetOAuth.ChannelElements { using System.Collections.Generic;
using System.Linq;
using System.Text;
+ using DotNetOAuth.Messages;
/// <summary>
/// An interface OAuth hosts must implement for persistent storage and recall of tokens and secrets.
@@ -38,13 +39,10 @@ namespace DotNetOAuth.ChannelElements { /// Stores a newly generated unauthorized request token, secret, and optional
/// application-specific parameters for later recall.
/// </summary>
- /// <param name="consumerKey">The key of the Consumer that requested this token.</param>
- /// <param name="requestToken">The token to store.</param>
- /// <param name="requestTokenSecret">The secret to store as associated with the request token.</param>
- /// <param name="requestParameters">The optional application-specific parameters sent in the request message.</param>
- /// <param name="responseParameters">The optional application-specific parameters sent in the response message.</param>
+ /// <param name="request">The request message that resulted in the generation of a new unauthorized request token.</param>
+ /// <param name="response">The response message that includes the unauthorized request token.</param>
/// <exception cref="ArgumentException">Thrown if the consumer key is not registered, or a required parameter was not found in the parameters collection.</exception>
- void StoreNewRequestToken(string consumerKey, string requestToken, string requestTokenSecret, IDictionary<string, string> requestParameters, IDictionary<string, string> responseParameters);
+ void StoreNewRequestToken(RequestTokenMessage request, UnauthorizedRequestTokenMessage response);
/// <summary>
/// Checks whether a given request token has already been authorized
diff --git a/src/DotNetOAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs b/src/DotNetOAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs index 12e46cf..af17527 100644 --- a/src/DotNetOAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs +++ b/src/DotNetOAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs @@ -14,7 +14,7 @@ namespace DotNetOAuth.ChannelElements { /// An OAuth-protocol specific implementation of the <see cref="IMessageTypeProvider"/>
/// interface.
/// </summary>
- internal class OAuthConsumerMessageTypeProvider : IMessageTypeProvider {
+ public class OAuthConsumerMessageTypeProvider : IMessageTypeProvider {
/// <summary>
/// The token manager to use for discerning between request and access tokens.
/// </summary>
@@ -24,7 +24,7 @@ namespace DotNetOAuth.ChannelElements { /// Initializes a new instance of the <see cref="OAuthConsumerMessageTypeProvider"/> class.
/// </summary>
/// <param name="tokenManager">The token manager instance to use.</param>
- internal OAuthConsumerMessageTypeProvider(ITokenManager tokenManager) {
+ protected internal OAuthConsumerMessageTypeProvider(ITokenManager tokenManager) {
if (tokenManager == null) {
throw new ArgumentNullException("tokenManager");
}
@@ -47,7 +47,7 @@ namespace DotNetOAuth.ChannelElements { /// The <see cref="IProtocolMessage"/>-derived concrete class that this message can
/// deserialize to. Null if the request isn't recognized as a valid protocol message.
/// </returns>
- public Type GetRequestMessageType(IDictionary<string, string> fields) {
+ public virtual Type GetRequestMessageType(IDictionary<string, string> fields) {
if (fields == null) {
throw new ArgumentNullException("fields");
}
@@ -77,7 +77,7 @@ namespace DotNetOAuth.ChannelElements { /// UnauthorizedRequestTokenMessage
/// GrantAccessTokenMessage
/// </remarks>
- public Type GetResponseMessageType(IProtocolMessage request, IDictionary<string, string> fields) {
+ public virtual Type GetResponseMessageType(IProtocolMessage request, IDictionary<string, string> fields) {
if (fields == null) {
throw new ArgumentNullException("fields");
}
diff --git a/src/DotNetOAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs b/src/DotNetOAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs index d47d396..ab9105f 100644 --- a/src/DotNetOAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs +++ b/src/DotNetOAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs @@ -14,7 +14,7 @@ namespace DotNetOAuth.ChannelElements { /// An OAuth-protocol specific implementation of the <see cref="IMessageTypeProvider"/>
/// interface.
/// </summary>
- internal class OAuthServiceProviderMessageTypeProvider : IMessageTypeProvider {
+ public class OAuthServiceProviderMessageTypeProvider : IMessageTypeProvider {
/// <summary>
/// The token manager to use for discerning between request and access tokens.
/// </summary>
@@ -24,7 +24,7 @@ namespace DotNetOAuth.ChannelElements { /// Initializes a new instance of the <see cref="OAuthServiceProviderMessageTypeProvider"/> class.
/// </summary>
/// <param name="tokenManager">The token manager instance to use.</param>
- internal OAuthServiceProviderMessageTypeProvider(ITokenManager tokenManager) {
+ protected internal OAuthServiceProviderMessageTypeProvider(ITokenManager tokenManager) {
if (tokenManager == null) {
throw new ArgumentNullException("tokenManager");
}
@@ -50,7 +50,7 @@ namespace DotNetOAuth.ChannelElements { /// The <see cref="IProtocolMessage"/>-derived concrete class that this message can
/// deserialize to. Null if the request isn't recognized as a valid protocol message.
/// </returns>
- public Type GetRequestMessageType(IDictionary<string, string> fields) {
+ public virtual Type GetRequestMessageType(IDictionary<string, string> fields) {
if (fields == null) {
throw new ArgumentNullException("fields");
}
@@ -92,7 +92,7 @@ namespace DotNetOAuth.ChannelElements { /// The response messages are:
/// None.
/// </remarks>
- public Type GetResponseMessageType(IProtocolMessage request, IDictionary<string, string> fields) {
+ public virtual Type GetResponseMessageType(IProtocolMessage request, IDictionary<string, string> fields) {
if (fields == null) {
throw new ArgumentNullException("fields");
}
diff --git a/src/DotNetOAuth/Consumer.cs b/src/DotNetOAuth/Consumer.cs index b8d16f3..881eec8 100644 --- a/src/DotNetOAuth/Consumer.cs +++ b/src/DotNetOAuth/Consumer.cs @@ -203,8 +203,7 @@ namespace DotNetOAuth { };
requestToken.AddNonOAuthParameters(requestParameters);
var requestTokenResponse = this.Channel.Request<UnauthorizedRequestTokenMessage>(requestToken);
- IDictionary<string, string> responseParameters = ((IProtocolMessage)requestTokenResponse).ExtraData;
- this.TokenManager.StoreNewRequestToken(this.ConsumerKey, requestTokenResponse.RequestToken, requestTokenResponse.TokenSecret, requestParameters, responseParameters);
+ this.TokenManager.StoreNewRequestToken(requestToken, requestTokenResponse);
// Request user authorization.
var requestAuthorization = new DirectUserToServiceProviderMessage(this.ServiceProvider.UserAuthorizationEndpoint) {
diff --git a/src/DotNetOAuth/Messages/AccessProtectedResourcesMessage.cs b/src/DotNetOAuth/Messages/AccessProtectedResourcesMessage.cs index 9db6a0a..b9817f6 100644 --- a/src/DotNetOAuth/Messages/AccessProtectedResourcesMessage.cs +++ b/src/DotNetOAuth/Messages/AccessProtectedResourcesMessage.cs @@ -17,7 +17,7 @@ namespace DotNetOAuth.Messages { /// Initializes a new instance of the <see cref="AccessProtectedResourcesMessage"/> class.
/// </summary>
/// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
- internal AccessProtectedResourcesMessage(MessageReceivingEndpoint serviceProvider)
+ protected internal AccessProtectedResourcesMessage(MessageReceivingEndpoint serviceProvider)
: base(MessageTransport.Direct, serviceProvider) {
}
diff --git a/src/DotNetOAuth/Messages/GrantAccessTokenMessage.cs b/src/DotNetOAuth/Messages/GrantAccessTokenMessage.cs index 504af4a..f1c5214 100644 --- a/src/DotNetOAuth/Messages/GrantAccessTokenMessage.cs +++ b/src/DotNetOAuth/Messages/GrantAccessTokenMessage.cs @@ -15,7 +15,7 @@ namespace DotNetOAuth.Messages { /// <summary>
/// Initializes a new instance of the <see cref="GrantAccessTokenMessage"/> class.
/// </summary>
- internal GrantAccessTokenMessage()
+ protected internal GrantAccessTokenMessage()
: base(MessageProtection.None, MessageTransport.Direct) {
}
diff --git a/src/DotNetOAuth/Messages/RequestAccessTokenMessage.cs b/src/DotNetOAuth/Messages/RequestAccessTokenMessage.cs index 6d334e7..12bd577 100644 --- a/src/DotNetOAuth/Messages/RequestAccessTokenMessage.cs +++ b/src/DotNetOAuth/Messages/RequestAccessTokenMessage.cs @@ -17,7 +17,7 @@ namespace DotNetOAuth.Messages { /// Initializes a new instance of the <see cref="RequestAccessTokenMessage"/> class.
/// </summary>
/// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
- internal RequestAccessTokenMessage(MessageReceivingEndpoint serviceProvider)
+ protected internal RequestAccessTokenMessage(MessageReceivingEndpoint serviceProvider)
: base(MessageTransport.Direct, serviceProvider) {
}
diff --git a/src/DotNetOAuth/Messages/RequestTokenMessage.cs b/src/DotNetOAuth/Messages/RequestTokenMessage.cs index 727cde0..e90b63d 100644 --- a/src/DotNetOAuth/Messages/RequestTokenMessage.cs +++ b/src/DotNetOAuth/Messages/RequestTokenMessage.cs @@ -15,7 +15,7 @@ namespace DotNetOAuth.Messages { /// Initializes a new instance of the <see cref="RequestTokenMessage"/> class.
/// </summary>
/// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
- internal RequestTokenMessage(MessageReceivingEndpoint serviceProvider)
+ protected internal RequestTokenMessage(MessageReceivingEndpoint serviceProvider)
: base(MessageTransport.Direct, serviceProvider) {
}
}
diff --git a/src/DotNetOAuth/Messages/UnauthorizedRequestTokenMessage.cs b/src/DotNetOAuth/Messages/UnauthorizedRequestTokenMessage.cs index bbeeb31..dd1203e 100644 --- a/src/DotNetOAuth/Messages/UnauthorizedRequestTokenMessage.cs +++ b/src/DotNetOAuth/Messages/UnauthorizedRequestTokenMessage.cs @@ -11,11 +11,11 @@ namespace DotNetOAuth.Messages { /// A direct message sent from Service Provider to Consumer in response to
/// a Consumer's <see cref="RequestTokenMessage"/> request.
/// </summary>
- internal class UnauthorizedRequestTokenMessage : MessageBase {
+ public class UnauthorizedRequestTokenMessage : MessageBase {
/// <summary>
/// Initializes a new instance of the <see cref="UnauthorizedRequestTokenMessage"/> class.
/// </summary>
- internal UnauthorizedRequestTokenMessage()
+ protected internal UnauthorizedRequestTokenMessage()
: base(MessageProtection.None, MessageTransport.Direct) {
}
@@ -23,12 +23,12 @@ namespace DotNetOAuth.Messages { /// Gets or sets the Request Token.
/// </summary>
[MessagePart(Name = "oauth_token", IsRequired = true)]
- internal string RequestToken { get; set; }
+ public string RequestToken { get; set; }
/// <summary>
/// Gets or sets the Token Secret.
/// </summary>
[MessagePart(Name = "oauth_token_secret", IsRequired = true)]
- internal string TokenSecret { get; set; }
+ public string TokenSecret { get; set; }
}
}
diff --git a/src/DotNetOAuth/Messaging/MessagePartAttribute.cs b/src/DotNetOAuth/Messaging/MessagePartAttribute.cs index ae88b61..91053b6 100644 --- a/src/DotNetOAuth/Messaging/MessagePartAttribute.cs +++ b/src/DotNetOAuth/Messaging/MessagePartAttribute.cs @@ -13,7 +13,7 @@ namespace DotNetOAuth.Messaging { /// Applied to fields and properties that form a key/value in a protocol message.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
- internal sealed class MessagePartAttribute : Attribute {
+ public sealed class MessagePartAttribute : Attribute {
/// <summary>
/// The overridden name to use as the serialized name for the property.
/// </summary>
@@ -22,7 +22,7 @@ namespace DotNetOAuth.Messaging { /// <summary>
/// Initializes a new instance of the <see cref="MessagePartAttribute"/> class.
/// </summary>
- internal MessagePartAttribute() {
+ public MessagePartAttribute() {
}
/// <summary>
@@ -32,7 +32,7 @@ namespace DotNetOAuth.Messaging { /// A special name to give the value of this member in the serialized message.
/// When null or empty, the name of the member will be used in the serialized message.
/// </param>
- internal MessagePartAttribute(string name) {
+ public MessagePartAttribute(string name) {
this.Name = name;
}
diff --git a/src/DotNetOAuth/Messaging/MessageSerializer.cs b/src/DotNetOAuth/Messaging/MessageSerializer.cs index fd42108..1239dd0 100644 --- a/src/DotNetOAuth/Messaging/MessageSerializer.cs +++ b/src/DotNetOAuth/Messaging/MessageSerializer.cs @@ -103,24 +103,25 @@ namespace DotNetOAuth.Messaging { /// <returns>The newly created message object.</returns>
private IProtocolMessage CreateMessage(MessageReceivingEndpoint recipient) {
IProtocolMessage result;
+ BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
if (typeof(IOAuthDirectedMessage).IsAssignableFrom(this.messageType)) {
// Some OAuth messages take just the recipient, while others take the whole endpoint
ConstructorInfo ctor;
- if ((ctor = this.messageType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(Uri) }, null)) != null) {
+ if ((ctor = this.messageType.GetConstructor(bindingFlags, null, new Type[] { typeof(Uri) }, null)) != null) {
if (recipient == null) {
// We need a recipient to deserialize directed messages.
throw new ArgumentNullException("recipient");
}
result = (IProtocolMessage)ctor.Invoke(new object[] { recipient.Location });
- } else if ((ctor = this.messageType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(MessageReceivingEndpoint) }, null)) != null) {
+ } else if ((ctor = this.messageType.GetConstructor(bindingFlags, null, new Type[] { typeof(MessageReceivingEndpoint) }, null)) != null) {
if (recipient == null) {
// We need a recipient to deserialize directed messages.
throw new ArgumentNullException("recipient");
}
result = (IProtocolMessage)ctor.Invoke(new object[] { recipient });
- } else if ((ctor = this.messageType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null)) != null) {
+ } else if ((ctor = this.messageType.GetConstructor(bindingFlags, null, new Type[0], null)) != null) {
result = (IProtocolMessage)ctor.Invoke(new object[0]);
} else {
throw new InvalidOperationException("Unrecognized constructor signature on type " + this.messageType);
diff --git a/src/DotNetOAuth/ServiceProvider.cs b/src/DotNetOAuth/ServiceProvider.cs index 4168846..135ecd0 100644 --- a/src/DotNetOAuth/ServiceProvider.cs +++ b/src/DotNetOAuth/ServiceProvider.cs @@ -32,19 +32,32 @@ namespace DotNetOAuth { /// </summary>
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, ITokenManager tokenManager) {
+ public ServiceProvider(ServiceProviderDescription serviceDescription, ITokenManager tokenManager)
+ : this(serviceDescription, tokenManager, new OAuthServiceProviderMessageTypeProvider(tokenManager)) {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ServiceProvider"/> class.
+ /// </summary>
+ /// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
+ /// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
+ /// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
+ public ServiceProvider(ServiceProviderDescription serviceDescription, ITokenManager tokenManager, OAuthServiceProviderMessageTypeProvider messageTypeProvider) {
if (serviceDescription == null) {
throw new ArgumentNullException("serviceDescription");
}
if (tokenManager == null) {
throw new ArgumentNullException("tokenManager");
}
+ if (messageTypeProvider == null) {
+ throw new ArgumentNullException("messageTypeProvider");
+ }
var signingElement = serviceDescription.CreateTamperProtectionElement();
signingElement.SignatureVerificationCallback = this.TokenSignatureVerificationCallback;
INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge);
this.ServiceDescription = serviceDescription;
- this.Channel = new OAuthChannel(signingElement, store, tokenManager, false);
+ this.Channel = new OAuthChannel(signingElement, store, messageTypeProvider, new StandardWebRequestHandler());
this.TokenGenerator = new StandardTokenGenerator();
this.TokenManager = tokenManager;
}
@@ -118,12 +131,12 @@ namespace DotNetOAuth { public Response SendUnauthorizedTokenResponse(RequestTokenMessage request, IDictionary<string, string> extraParameters) {
string token = this.TokenGenerator.GenerateRequestToken(request.ConsumerKey);
string secret = this.TokenGenerator.GenerateSecret();
- this.TokenManager.StoreNewRequestToken(request.ConsumerKey, token, secret, ((IProtocolMessage)request).ExtraData, extraParameters);
UnauthorizedRequestTokenMessage response = new UnauthorizedRequestTokenMessage {
RequestToken = token,
TokenSecret = secret,
};
response.AddNonOAuthParameters(extraParameters);
+ this.TokenManager.StoreNewRequestToken(request, response);
return this.Channel.Send(response);
}
|