summaryrefslogtreecommitdiffstats
path: root/src/DotNetOAuth/OAuth/Messages
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-11-03 16:02:57 -0800
committerAndrew <andrewarnott@gmail.com>2008-11-03 16:02:57 -0800
commitaa1f55f58a561ff64dc268977d0d7c9decb92bbe (patch)
treefd685f00353d26493b40df7eaeac78745e27d1b8 /src/DotNetOAuth/OAuth/Messages
parentf1794fc8779ae39ac3d5bc6e8b811523e62ca482 (diff)
downloadDotNetOpenAuth-aa1f55f58a561ff64dc268977d0d7c9decb92bbe.zip
DotNetOpenAuth-aa1f55f58a561ff64dc268977d0d7c9decb92bbe.tar.gz
DotNetOpenAuth-aa1f55f58a561ff64dc268977d0d7c9decb92bbe.tar.bz2
Moved all the OAuth classes into its own namespace in preparation to receiving DotNetOpenId merge.
Diffstat (limited to 'src/DotNetOAuth/OAuth/Messages')
-rw-r--r--src/DotNetOAuth/OAuth/Messages/AccessProtectedResourceRequest.cs45
-rw-r--r--src/DotNetOAuth/OAuth/Messages/AuthorizedTokenRequest.cs53
-rw-r--r--src/DotNetOAuth/OAuth/Messages/AuthorizedTokenResponse.cs60
-rw-r--r--src/DotNetOAuth/OAuth/Messages/ITokenContainingMessage.cs17
-rw-r--r--src/DotNetOAuth/OAuth/Messages/ITokenSecretContainingMessage.cs17
-rw-r--r--src/DotNetOAuth/OAuth/Messages/MessageBase.cs239
-rw-r--r--src/DotNetOAuth/OAuth/Messages/OAuth Messages.cd215
-rw-r--r--src/DotNetOAuth/OAuth/Messages/SignedMessageBase.cs161
-rw-r--r--src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenRequest.cs30
-rw-r--r--src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenResponse.cs92
-rw-r--r--src/DotNetOAuth/OAuth/Messages/UserAuthorizationRequest.cs71
-rw-r--r--src/DotNetOAuth/OAuth/Messages/UserAuthorizationResponse.cs40
12 files changed, 1040 insertions, 0 deletions
diff --git a/src/DotNetOAuth/OAuth/Messages/AccessProtectedResourceRequest.cs b/src/DotNetOAuth/OAuth/Messages/AccessProtectedResourceRequest.cs
new file mode 100644
index 0000000..2704dd5
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/AccessProtectedResourceRequest.cs
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------
+// <copyright file="AccessProtectedResourceRequest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System.Diagnostics.CodeAnalysis;
+ using DotNetOAuth.Messaging;
+
+ /// <summary>
+ /// A message attached to a request for protected resources that provides the necessary
+ /// credentials to be granted access to those resources.
+ /// </summary>
+ public class AccessProtectedResourceRequest : SignedMessageBase, ITokenContainingMessage {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AccessProtectedResourceRequest"/> class.
+ /// </summary>
+ /// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
+ protected internal AccessProtectedResourceRequest(MessageReceivingEndpoint serviceProvider)
+ : base(MessageTransport.Direct, serviceProvider) {
+ }
+
+ /// <summary>
+ /// Gets or sets the Token.
+ /// </summary>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "This property IS accessible by a different name.")]
+ string ITokenContainingMessage.Token {
+ get { return this.AccessToken; }
+ set { this.AccessToken = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Access Token.
+ /// </summary>
+ /// <remarks>
+ /// In addition to just allowing OAuth to verify a valid message,
+ /// this property is useful on the Service Provider to verify that the access token
+ /// has proper authorization for the resource being requested, and to know the
+ /// context around which user provided the authorization.
+ /// </remarks>
+ [MessagePart("oauth_token", IsRequired = true)]
+ public string AccessToken { get; set; }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/AuthorizedTokenRequest.cs b/src/DotNetOAuth/OAuth/Messages/AuthorizedTokenRequest.cs
new file mode 100644
index 0000000..8f76046
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/AuthorizedTokenRequest.cs
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------
+// <copyright file="AuthorizedTokenRequest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System.Globalization;
+ using DotNetOAuth.Messaging;
+
+ /// <summary>
+ /// A direct message sent by the Consumer to exchange an authorized Request Token
+ /// for an Access Token and Token Secret.
+ /// </summary>
+ /// <remarks>
+ /// The class is sealed because the OAuth spec forbids adding parameters to this message.
+ /// </remarks>
+ public sealed class AuthorizedTokenRequest : SignedMessageBase, ITokenContainingMessage {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AuthorizedTokenRequest"/> class.
+ /// </summary>
+ /// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
+ internal AuthorizedTokenRequest(MessageReceivingEndpoint serviceProvider)
+ : base(MessageTransport.Direct, serviceProvider) {
+ }
+
+ /// <summary>
+ /// Gets or sets the Token.
+ /// </summary>
+ string ITokenContainingMessage.Token {
+ get { return this.RequestToken; }
+ set { this.RequestToken = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the unauthorized Request Token used to obtain authorization.
+ /// </summary>
+ [MessagePart("oauth_token", IsRequired = true)]
+ internal string RequestToken { get; set; }
+
+ /// <summary>
+ /// Checks the message state for conformity to the protocol specification
+ /// and throws an exception if the message is invalid.
+ /// </summary>
+ protected override void EnsureValidMessage() {
+ base.EnsureValidMessage();
+
+ if (this.ExtraData.Count > 0) {
+ throw new ProtocolException(string.Format(CultureInfo.CurrentCulture, Strings.MessageNotAllowedExtraParameters, GetType().Name));
+ }
+ }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/AuthorizedTokenResponse.cs b/src/DotNetOAuth/OAuth/Messages/AuthorizedTokenResponse.cs
new file mode 100644
index 0000000..4c28edd
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/AuthorizedTokenResponse.cs
@@ -0,0 +1,60 @@
+//-----------------------------------------------------------------------
+// <copyright file="AuthorizedTokenResponse.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using DotNetOAuth.Messaging;
+
+ /// <summary>
+ /// A direct message sent from Service Provider to Consumer in response to
+ /// a Consumer's <see cref="AuthorizedTokenRequest"/> request.
+ /// </summary>
+ public class AuthorizedTokenResponse : MessageBase, ITokenSecretContainingMessage {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AuthorizedTokenResponse"/> class.
+ /// </summary>
+ protected internal AuthorizedTokenResponse()
+ : base(MessageProtections.None, MessageTransport.Direct) {
+ }
+
+ /// <summary>
+ /// Gets or sets the Access Token assigned by the Service Provider.
+ /// </summary>
+ [MessagePart("oauth_token", IsRequired = true)]
+ public string AccessToken { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Request or Access Token.
+ /// </summary>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "This property IS accessible by a different name.")]
+ string ITokenContainingMessage.Token {
+ get { return this.AccessToken; }
+ set { this.AccessToken = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Request or Access Token secret.
+ /// </summary>
+ string ITokenSecretContainingMessage.TokenSecret {
+ get { return this.TokenSecret; }
+ set { this.TokenSecret = value; }
+ }
+
+ /// <summary>
+ /// Gets the extra, non-OAuth parameters that will be included in the message.
+ /// </summary>
+ public new IDictionary<string, string> ExtraData {
+ get { return base.ExtraData; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Token Secret.
+ /// </summary>
+ [MessagePart("oauth_token_secret", IsRequired = true)]
+ protected internal string TokenSecret { get; set; }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/ITokenContainingMessage.cs b/src/DotNetOAuth/OAuth/Messages/ITokenContainingMessage.cs
new file mode 100644
index 0000000..57ee86d
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/ITokenContainingMessage.cs
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------------
+// <copyright file="ITokenContainingMessage.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ /// <summary>
+ /// An interface implemented by all OAuth messages that have a request or access token property.
+ /// </summary>
+ public interface ITokenContainingMessage {
+ /// <summary>
+ /// Gets or sets the Request or Access Token.
+ /// </summary>
+ string Token { get; set; }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/ITokenSecretContainingMessage.cs b/src/DotNetOAuth/OAuth/Messages/ITokenSecretContainingMessage.cs
new file mode 100644
index 0000000..98d09ee
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/ITokenSecretContainingMessage.cs
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------------
+// <copyright file="ITokenSecretContainingMessage.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ /// <summary>
+ /// An interface implemented by all OAuth messages that have a request or access token and secret properties.
+ /// </summary>
+ public interface ITokenSecretContainingMessage : ITokenContainingMessage {
+ /// <summary>
+ /// Gets or sets the Request or Access Token secret.
+ /// </summary>
+ string TokenSecret { get; set; }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/MessageBase.cs b/src/DotNetOAuth/OAuth/Messages/MessageBase.cs
new file mode 100644
index 0000000..a74b9f2
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/MessageBase.cs
@@ -0,0 +1,239 @@
+//-----------------------------------------------------------------------
+// <copyright file="MessageBase.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Text;
+ using DotNetOAuth.Messaging;
+ using DotNetOAuth.Messaging.Reflection;
+ using DotNetOAuth.OAuth.ChannelElements;
+
+ /// <summary>
+ /// A base class for all OAuth messages.
+ /// </summary>
+ public abstract class MessageBase : IOAuthDirectedMessage {
+ /// <summary>
+ /// A store for extra name/value data pairs that are attached to this message.
+ /// </summary>
+ private Dictionary<string, string> extraData = new Dictionary<string, string>();
+
+ /// <summary>
+ /// Gets a value indicating whether signing this message is required.
+ /// </summary>
+ private MessageProtections protectionRequired;
+
+ /// <summary>
+ /// Gets a value indicating whether this is a direct or indirect message.
+ /// </summary>
+ private MessageTransport transport;
+
+ /// <summary>
+ /// The URI to the remote endpoint to send this message to.
+ /// </summary>
+ private MessageReceivingEndpoint recipient;
+
+#if DEBUG
+ /// <summary>
+ /// Initializes static members of the <see cref="MessageBase"/> class.
+ /// </summary>
+ static MessageBase() {
+ LowSecurityMode = true;
+ }
+#endif
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MessageBase"/> class.
+ /// </summary>
+ /// <param name="protectionRequired">The level of protection the message requires.</param>
+ /// <param name="transport">A value indicating whether this message requires a direct or indirect transport.</param>
+ protected MessageBase(MessageProtections protectionRequired, MessageTransport transport) {
+ this.protectionRequired = protectionRequired;
+ this.transport = transport;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MessageBase"/> class.
+ /// </summary>
+ /// <param name="protectionRequired">The level of protection the message requires.</param>
+ /// <param name="transport">A value indicating whether this message requires a direct or indirect transport.</param>
+ /// <param name="recipient">The URI that a directed message will be delivered to.</param>
+ protected MessageBase(MessageProtections protectionRequired, MessageTransport transport, MessageReceivingEndpoint recipient) {
+ if (recipient == null) {
+ throw new ArgumentNullException("recipient");
+ }
+
+ this.protectionRequired = protectionRequired;
+ this.transport = transport;
+ this.recipient = recipient;
+ }
+
+ #region IProtocolMessage Properties
+
+ /// <summary>
+ /// Gets the version of the protocol this message is prepared to implement.
+ /// </summary>
+ Version IProtocolMessage.ProtocolVersion {
+ get { return this.ProtocolVersion; }
+ }
+
+ /// <summary>
+ /// Gets the level of protection this message requires.
+ /// </summary>
+ MessageProtections IProtocolMessage.RequiredProtection {
+ get { return this.RequiredProtection; }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this is a direct or indirect message.
+ /// </summary>
+ MessageTransport IProtocolMessage.Transport {
+ get { return this.Transport; }
+ }
+
+ /// <summary>
+ /// Gets the dictionary of additional name/value fields tacked on to this message.
+ /// </summary>
+ IDictionary<string, string> IProtocolMessage.ExtraData {
+ get { return this.ExtraData; }
+ }
+
+ #endregion
+
+ #region IDirectedProtocolMessage Members
+
+ /// <summary>
+ /// Gets the URI to the Service Provider endpoint to send this message to.
+ /// </summary>
+ Uri IDirectedProtocolMessage.Recipient {
+ get { return this.recipient.Location; }
+ }
+
+ #endregion
+
+ #region IOAuthDirectedMessage Properties
+
+ /// <summary>
+ /// Gets the preferred method of transport for the message.
+ /// </summary>
+ HttpDeliveryMethods IOAuthDirectedMessage.HttpMethods {
+ get { return this.HttpMethods; }
+ }
+
+ /// <summary>
+ /// Gets or sets the URI to the Service Provider endpoint to send this message to.
+ /// </summary>
+ Uri IOAuthDirectedMessage.Recipient {
+ get { return this.Recipient; }
+ set { this.Recipient = value; }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Gets or sets a value indicating whether security sensitive strings are
+ /// emitted from the ToString() method.
+ /// </summary>
+ internal static bool LowSecurityMode { get; set; }
+
+ /// <summary>
+ /// Gets the version of the protocol this message is prepared to implement.
+ /// </summary>
+ protected virtual Version ProtocolVersion {
+ get { return new Version(1, 0); }
+ }
+
+ /// <summary>
+ /// Gets the level of protection this message requires.
+ /// </summary>
+ protected MessageProtections RequiredProtection {
+ get { return this.protectionRequired; }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this is a direct or indirect message.
+ /// </summary>
+ protected MessageTransport Transport {
+ get { return this.transport; }
+ }
+
+ /// <summary>
+ /// Gets the dictionary of additional name/value fields tacked on to this message.
+ /// </summary>
+ protected IDictionary<string, string> ExtraData {
+ get { return this.extraData; }
+ }
+
+ /// <summary>
+ /// Gets the preferred method of transport for the message.
+ /// </summary>
+ protected HttpDeliveryMethods HttpMethods {
+ get { return this.recipient != null ? this.recipient.AllowedMethods : HttpDeliveryMethods.None; }
+ }
+
+ /// <summary>
+ /// Gets or sets the URI to the Service Provider endpoint to send this message to.
+ /// </summary>
+ protected Uri Recipient {
+ get {
+ return this.recipient != null ? this.recipient.Location : null;
+ }
+
+ set {
+ if (this.recipient != null) {
+ this.recipient = new MessageReceivingEndpoint(value, this.recipient.AllowedMethods);
+ } else if (value != null) {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ #region IProtocolMessage Methods
+
+ /// <summary>
+ /// Checks the message state for conformity to the protocol specification
+ /// and throws an exception if the message is invalid.
+ /// </summary>
+ void IProtocolMessage.EnsureValidMessage() {
+ this.EnsureValidMessage();
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Returns a human-friendly string describing the message and all serializable properties.
+ /// </summary>
+ /// <returns>The string representation of this object.</returns>
+ public override string ToString() {
+ StringBuilder builder = new StringBuilder();
+ builder.AppendFormat(CultureInfo.InvariantCulture, "{0} message", GetType().Name);
+ if (this.recipient != null) {
+ builder.AppendFormat(CultureInfo.InvariantCulture, " as {0} to {1}", this.recipient.AllowedMethods, this.recipient.Location);
+ }
+ builder.AppendLine();
+ MessageDictionary dictionary = new MessageDictionary(this);
+ foreach (var pair in dictionary) {
+ string value = pair.Value;
+ if (pair.Key == "oauth_signature" && !LowSecurityMode) {
+ value = "xxxxxxxxxxxxx (not shown)";
+ }
+ builder.Append('\t');
+ builder.Append(pair.Key);
+ builder.Append(": ");
+ builder.AppendLine(value);
+ }
+
+ return builder.ToString();
+ }
+
+ /// <summary>
+ /// Checks the message state for conformity to the protocol specification
+ /// and throws an exception if the message is invalid.
+ /// </summary>
+ protected virtual void EnsureValidMessage() { }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/OAuth Messages.cd b/src/DotNetOAuth/OAuth/Messages/OAuth Messages.cd
new file mode 100644
index 0000000..414644a
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/OAuth Messages.cd
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1" GroupingSetting="Access">
+ <Comment CommentText="Messages from Service Provider">
+ <Position X="7.912" Y="0.715" Height="0.291" Width="2.02" />
+ </Comment>
+ <Comment CommentText="Messages from Consumer">
+ <Position X="4.36" Y="0.683" Height="0.291" Width="2.02" />
+ </Comment>
+ <Class Name="DotNetOAuth.OAuth.Messages.AccessProtectedResourceRequest">
+ <Position X="4.25" Y="7.75" Width="3" />
+ <Members>
+ <Property Name="ITokenContainingMessage.Token" Hidden="true" />
+ </Members>
+ <InheritanceLine Type="DotNetOAuth.OAuth.Messages.SignedMessageBase" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="3.5" Y="5.626" />
+ <Point X="3.5" Y="8.25" />
+ <Point X="4.25" Y="8.25" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAACAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Messages\AccessProtectedResourceRequest.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.UnauthorizedTokenResponse">
+ <Position X="7.5" Y="1.5" Width="3" />
+ <Members>
+ <Property Name="ITokenContainingMessage.Token" Hidden="true" />
+ <Property Name="ITokenSecretContainingMessage.TokenSecret" Hidden="true" />
+ </Members>
+ <Compartments>
+ <Compartment Name="Methods" Collapsed="true" />
+ </Compartments>
+ <TypeIdentifier>
+ <HashCode>AAAAAAACAAAAAAAAAAEAAAAAAIAAIAAAIAAAAAAAAAA=</HashCode>
+ <FileName>Messages\UnauthorizedTokenResponse.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.UserAuthorizationResponse">
+ <Position X="7.5" Y="4.5" Width="3" />
+ <Members>
+ <Property Name="ITokenContainingMessage.Token" Hidden="true" />
+ </Members>
+ <Compartments>
+ <Compartment Name="Methods" Collapsed="true" />
+ </Compartments>
+ <InheritanceLine Type="DotNetOAuth.OAuth.Messages.MessageBase" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="10.75" Y="4.688" />
+ <Point X="10.5" Y="4.688" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAACAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Messages\UserAuthorizationResponse.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.UserAuthorizationRequest">
+ <Position X="4.25" Y="3" Width="3" />
+ <Members>
+ <Property Name="ITokenContainingMessage.Token" Hidden="true" />
+ </Members>
+ <Compartments>
+ <Compartment Name="Methods" Collapsed="true" />
+ </Compartments>
+ <InheritanceLine Type="DotNetOAuth.OAuth.Messages.MessageBase" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="10.75" Y="4.125" />
+ <Point X="7.25" Y="4.125" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAACAAAAAAAAAAAAAAAAAIAAAAAAIAAAAAAAQAA=</HashCode>
+ <FileName>Messages\UserAuthorizationRequest.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.AuthorizedTokenResponse">
+ <Position X="7.5" Y="6.25" Width="3" />
+ <Members>
+ <Property Name="ITokenContainingMessage.Token" Hidden="true" />
+ <Property Name="ITokenSecretContainingMessage.TokenSecret" Hidden="true" />
+ </Members>
+ <Compartments>
+ <Compartment Name="Methods" Collapsed="true" />
+ </Compartments>
+ <InheritanceLine Type="DotNetOAuth.OAuth.Messages.MessageBase" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="11" Y="4.805" />
+ <Point X="11" Y="7.013" />
+ <Point X="10.5" Y="7.013" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAACAAAAAAAAAAAAAAAAEAAAIAAAIAAAAAAAAAA=</HashCode>
+ <FileName>Messages\AuthorizedTokenResponse.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.MessageBase">
+ <Position X="10.75" Y="1" Width="3.5" />
+ <Members>
+ <Field Name="extraData" Hidden="true" />
+ <Property Name="IDirectedProtocolMessage.Recipient" Hidden="true" />
+ <Property Name="IOAuthDirectedMessage.HttpMethods" Hidden="true" />
+ <Property Name="IOAuthDirectedMessage.Recipient" Hidden="true" />
+ <Method Name="IProtocolMessage.EnsureValidMessage" Hidden="true" />
+ <Property Name="IProtocolMessage.ExtraData" Hidden="true" />
+ <Property Name="IProtocolMessage.ProtocolVersion" Hidden="true" />
+ <Property Name="IProtocolMessage.RequiredProtection" Hidden="true" />
+ <Property Name="IProtocolMessage.Transport" Hidden="true" />
+ <Field Name="protectionRequired" Hidden="true" />
+ <Field Name="recipient" Hidden="true" />
+ <Field Name="transport" Hidden="true" />
+ </Members>
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <TypeIdentifier>
+ <HashCode>AAAKAAAAYAAAgAEEAIAAAAYAAAQEIDAAIgCCACAAAAA=</HashCode>
+ <FileName>Messages\MessageBase.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.AuthorizedTokenRequest">
+ <Position X="4.25" Y="5.5" Width="3" />
+ <Members>
+ <Property Name="ITokenContainingMessage.Token" Hidden="true" />
+ </Members>
+ <Compartments>
+ <Compartment Name="Methods" Collapsed="true" />
+ </Compartments>
+ <InheritanceLine Type="DotNetOAuth.OAuth.Messages.SignedMessageBase" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="4" Y="4.947" />
+ <Point X="4.123" Y="4.947" />
+ <Point X="4.123" Y="5.75" />
+ <Point X="4.25" Y="5.75" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAACQAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Messages\AuthorizedTokenRequest.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.UnauthorizedTokenRequest">
+ <Position X="4.25" Y="1" Width="3" />
+ <Compartments>
+ <Compartment Name="Internal" Collapsed="true" />
+ <Compartment Name="Private" Collapsed="true" />
+ <Compartment Name="Methods" Collapsed="true" />
+ </Compartments>
+ <InheritanceLine Type="DotNetOAuth.OAuth.Messages.SignedMessageBase" FixedFromPoint="true">
+ <Path>
+ <Point X="4" Y="1.855" />
+ <Point X="4.25" Y="1.855" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAA=</HashCode>
+ <FileName>Messages\UnauthorizedTokenRequest.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="DotNetOAuth.OAuth.Messages.SignedMessageBase">
+ <Position X="0.5" Y="1.5" Width="3.5" />
+ <Members>
+ <Property Name="ITamperResistantOAuthMessage.ConsumerSecret" Hidden="true" />
+ <Property Name="ITamperResistantOAuthMessage.HttpMethod" Hidden="true" />
+ <Property Name="ITamperResistantOAuthMessage.SignatureMethod" Hidden="true" />
+ <Property Name="ITamperResistantOAuthMessage.TokenSecret" Hidden="true" />
+ <Property Name="ITamperResistantProtocolMessage.Signature" Hidden="true" />
+ </Members>
+ <InheritanceLine Type="DotNetOAuth.OAuth.Messages.MessageBase" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="12.875" Y="1" />
+ <Point X="12.875" Y="0.625" />
+ <Point X="3" Y="0.625" />
+ <Point X="3" Y="1.5" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>IIAAFAAAAIAAAAAAgICAAgAAAgAAIAQAAAEAIAAQAAE=</HashCode>
+ <FileName>Messages\SignedMessageBase.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Interface Name="DotNetOAuth.OAuth.ChannelElements.ITamperResistantOAuthMessage">
+ <Position X="11.25" Y="5.25" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AIAAAAAAAAAAAAAAAIAAAgAAAAAAIAQAAAAAAAAAAAA=</HashCode>
+ <FileName>ChannelElements\ITamperResistantOAuthMessage.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="DotNetOAuth.OAuth.Messages.ITokenSecretContainingMessage">
+ <Position X="1" Y="7.5" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Messages\ITokenSecretContainingMessage.cs</FileName>
+ <NewMemberFileName>Messages\ITokenContainingMessage.cs</NewMemberFileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="DotNetOAuth.OAuth.Messages.ITokenContainingMessage">
+ <Position X="1" Y="6" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAA=</HashCode>
+ <FileName>Messages\ITokenContainingMessage.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/DotNetOAuth/OAuth/Messages/SignedMessageBase.cs b/src/DotNetOAuth/OAuth/Messages/SignedMessageBase.cs
new file mode 100644
index 0000000..5d94013
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/SignedMessageBase.cs
@@ -0,0 +1,161 @@
+//-----------------------------------------------------------------------
+// <copyright file="SignedMessageBase.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System;
+ using System.Diagnostics.CodeAnalysis;
+ using DotNetOAuth.Messaging;
+ using DotNetOAuth.Messaging.Bindings;
+ using DotNetOAuth.OAuth.ChannelElements;
+
+ /// <summary>
+ /// A base class for all signed OAuth messages.
+ /// </summary>
+ public class SignedMessageBase : MessageBase, ITamperResistantOAuthMessage, IExpiringProtocolMessage, IReplayProtectedProtocolMessage {
+ /// <summary>
+ /// The reference date and time for calculating time stamps.
+ /// </summary>
+ private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+ /// <summary>
+ /// The number of seconds since 1/1/1970, consistent with the OAuth timestamp requirement.
+ /// </summary>
+ [MessagePart("oauth_timestamp", IsRequired = true)]
+ private long timestamp;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SignedMessageBase"/> class.
+ /// </summary>
+ /// <param name="transport">A value indicating whether this message requires a direct or indirect transport.</param>
+ /// <param name="recipient">The URI that a directed message will be delivered to.</param>
+ internal SignedMessageBase(MessageTransport transport, MessageReceivingEndpoint recipient)
+ : base(MessageProtections.All, transport, recipient) {
+ ITamperResistantOAuthMessage self = (ITamperResistantOAuthMessage)this;
+ HttpDeliveryMethods methods = ((IOAuthDirectedMessage)this).HttpMethods;
+ self.HttpMethod = (methods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET";
+ }
+
+ #region ITamperResistantOAuthMessage Members
+
+ /// <summary>
+ /// Gets or sets the signature method used to sign the request.
+ /// </summary>
+ string ITamperResistantOAuthMessage.SignatureMethod {
+ get { return this.SignatureMethod; }
+ set { this.SignatureMethod = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Token Secret used to sign the message.
+ /// </summary>
+ string ITamperResistantOAuthMessage.TokenSecret {
+ get { return this.TokenSecret; }
+ set { this.TokenSecret = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Consumer key.
+ /// </summary>
+ [MessagePart("oauth_consumer_key", IsRequired = true)]
+ public string ConsumerKey { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Consumer Secret used to sign the message.
+ /// </summary>
+ string ITamperResistantOAuthMessage.ConsumerSecret {
+ get { return this.ConsumerSecret; }
+ set { this.ConsumerSecret = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the HTTP method that will be used to transmit the message.
+ /// </summary>
+ string ITamperResistantOAuthMessage.HttpMethod {
+ get { return this.HttpMethod; }
+ set { this.HttpMethod = value; }
+ }
+
+ #endregion
+
+ #region ITamperResistantProtocolMessage Members
+
+ /// <summary>
+ /// Gets or sets the message signature.
+ /// </summary>
+ string ITamperResistantProtocolMessage.Signature {
+ get { return this.Signature; }
+ set { this.Signature = value; }
+ }
+
+ #endregion
+
+ #region IExpiringProtocolMessage Members
+
+ /// <summary>
+ /// Gets or sets the OAuth timestamp of the message.
+ /// </summary>
+ DateTime IExpiringProtocolMessage.UtcCreationDate {
+ get { return epoch + TimeSpan.FromSeconds(this.timestamp); }
+ set { this.timestamp = (long)(value - epoch).TotalSeconds; }
+ }
+
+ #endregion
+
+ #region IReplayProtectedProtocolMessage Members
+
+ /// <summary>
+ /// Gets or sets the message nonce used for replay detection.
+ /// </summary>
+ [MessagePart("oauth_nonce", IsRequired = true)]
+ string IReplayProtectedProtocolMessage.Nonce { get; set; }
+
+ #endregion
+
+ /// <summary>
+ /// Gets or sets the signature method used to sign the request.
+ /// </summary>
+ [MessagePart("oauth_signature_method", IsRequired = true)]
+ protected string SignatureMethod { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Token Secret used to sign the message.
+ /// </summary>
+ protected string TokenSecret { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Consumer Secret used to sign the message.
+ /// </summary>
+ protected string ConsumerSecret { get; set; }
+
+ /// <summary>
+ /// Gets or sets the HTTP method that will be used to transmit the message.
+ /// </summary>
+ protected string HttpMethod { get; set; }
+
+ /// <summary>
+ /// Gets or sets the message signature.
+ /// </summary>
+ [MessagePart("oauth_signature", IsRequired = true)]
+ protected string Signature { get; set; }
+
+ /// <summary>
+ /// Gets or sets the version of the protocol this message was created with.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Accessed via reflection.")]
+ [MessagePart("oauth_version", IsRequired = false)]
+ private string Version {
+ get {
+ return ProtocolVersion.ToString();
+ }
+
+ set {
+ if (value != this.Version) {
+ throw new ArgumentOutOfRangeException("value");
+ }
+ }
+ }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenRequest.cs b/src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenRequest.cs
new file mode 100644
index 0000000..7d83135
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenRequest.cs
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------
+// <copyright file="UnauthorizedTokenRequest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System.Collections.Generic;
+ using DotNetOAuth.Messaging;
+
+ /// <summary>
+ /// A direct message sent from Consumer to Service Provider to request a Request Token.
+ /// </summary>
+ public class UnauthorizedTokenRequest : SignedMessageBase {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UnauthorizedTokenRequest"/> class.
+ /// </summary>
+ /// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
+ protected internal UnauthorizedTokenRequest(MessageReceivingEndpoint serviceProvider)
+ : base(MessageTransport.Direct, serviceProvider) {
+ }
+
+ /// <summary>
+ /// Gets the extra, non-OAuth parameters that will be included in the message.
+ /// </summary>
+ public new IDictionary<string, string> ExtraData {
+ get { return base.ExtraData; }
+ }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenResponse.cs b/src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenResponse.cs
new file mode 100644
index 0000000..f527943
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/UnauthorizedTokenResponse.cs
@@ -0,0 +1,92 @@
+//-----------------------------------------------------------------------
+// <copyright file="UnauthorizedTokenResponse.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using DotNetOAuth.Messaging;
+
+ /// <summary>
+ /// A direct message sent from Service Provider to Consumer in response to
+ /// a Consumer's <see cref="UnauthorizedTokenRequest"/> request.
+ /// </summary>
+ public class UnauthorizedTokenResponse : MessageBase, ITokenSecretContainingMessage {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UnauthorizedTokenResponse"/> class.
+ /// </summary>
+ /// <param name="requestMessage">The unauthorized request token message that this message is being generated in response to.</param>
+ /// <param name="requestToken">The request token.</param>
+ /// <param name="tokenSecret">The token secret.</param>
+ /// <remarks>
+ /// This constructor is used by the Service Provider to send the message.
+ /// </remarks>
+ protected internal UnauthorizedTokenResponse(UnauthorizedTokenRequest requestMessage, string requestToken, string tokenSecret) : this() {
+ if (requestMessage == null) {
+ throw new ArgumentNullException("requestMessage");
+ }
+ if (string.IsNullOrEmpty(requestToken)) {
+ throw new ArgumentNullException("requestToken");
+ }
+ if (string.IsNullOrEmpty(tokenSecret)) {
+ throw new ArgumentNullException("tokenSecret");
+ }
+
+ this.RequestMessage = requestMessage;
+ this.RequestToken = requestToken;
+ this.TokenSecret = tokenSecret;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UnauthorizedTokenResponse"/> class.
+ /// </summary>
+ /// <remarks>This constructor is used by the consumer to deserialize the message.</remarks>
+ protected internal UnauthorizedTokenResponse()
+ : base(MessageProtections.None, MessageTransport.Direct) {
+ }
+
+ /// <summary>
+ /// Gets or sets the Request or Access Token.
+ /// </summary>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "This property IS accessible by a different name.")]
+ string ITokenContainingMessage.Token {
+ get { return this.RequestToken; }
+ set { this.RequestToken = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Request or Access Token secret.
+ /// </summary>
+ string ITokenSecretContainingMessage.TokenSecret {
+ get { return this.TokenSecret; }
+ set { this.TokenSecret = value; }
+ }
+
+ /// <summary>
+ /// Gets the extra, non-OAuth parameters that will be included in the message.
+ /// </summary>
+ public new IDictionary<string, string> ExtraData {
+ get { return base.ExtraData; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Request Token.
+ /// </summary>
+ [MessagePart("oauth_token", IsRequired = true)]
+ internal string RequestToken { get; set; }
+
+ /// <summary>
+ /// Gets the original request for an unauthorized token.
+ /// </summary>
+ internal UnauthorizedTokenRequest RequestMessage { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the Token Secret.
+ /// </summary>
+ [MessagePart("oauth_token_secret", IsRequired = true)]
+ protected internal string TokenSecret { get; set; }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/UserAuthorizationRequest.cs b/src/DotNetOAuth/OAuth/Messages/UserAuthorizationRequest.cs
new file mode 100644
index 0000000..79dd966
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/UserAuthorizationRequest.cs
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------
+// <copyright file="UserAuthorizationRequest.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using DotNetOAuth.Messaging;
+
+ /// <summary>
+ /// A message used to redirect the user from a Consumer to a Service Provider's web site
+ /// so the Service Provider can ask the user to authorize the Consumer's access to some
+ /// protected resource(s).
+ /// </summary>
+ public class UserAuthorizationRequest : MessageBase, ITokenContainingMessage {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UserAuthorizationRequest"/> class.
+ /// </summary>
+ /// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
+ /// <param name="requestToken">The request token.</param>
+ internal UserAuthorizationRequest(MessageReceivingEndpoint serviceProvider, string requestToken)
+ : this(serviceProvider) {
+ this.RequestToken = requestToken;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UserAuthorizationRequest"/> class.
+ /// </summary>
+ /// <param name="serviceProvider">The URI of the Service Provider endpoint to send this message to.</param>
+ internal UserAuthorizationRequest(MessageReceivingEndpoint serviceProvider)
+ : base(MessageProtections.None, MessageTransport.Indirect, serviceProvider) {
+ }
+
+ /// <summary>
+ /// Gets or sets the Request or Access Token.
+ /// </summary>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "This property IS accessible by a different name.")]
+ string ITokenContainingMessage.Token {
+ get { return this.RequestToken; }
+ set { this.RequestToken = value; }
+ }
+
+ /// <summary>
+ /// Gets the extra, non-OAuth parameters that will be included in the message.
+ /// </summary>
+ public new IDictionary<string, string> ExtraData {
+ get { return base.ExtraData; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Request Token obtained in the previous step.
+ /// </summary>
+ /// <remarks>
+ /// The Service Provider MAY declare this parameter as REQUIRED, or
+ /// accept requests to the User Authorization URL without it, in which
+ /// case it will prompt the User to enter it manually.
+ /// </remarks>
+ [MessagePart("oauth_token", IsRequired = false)]
+ internal string RequestToken { get; set; }
+
+ /// <summary>
+ /// Gets or sets a URL the Service Provider will use to redirect the User back
+ /// to the Consumer when Obtaining User Authorization is complete. Optional.
+ /// </summary>
+ [MessagePart("oauth_callback", IsRequired = false)]
+ internal Uri Callback { get; set; }
+ }
+}
diff --git a/src/DotNetOAuth/OAuth/Messages/UserAuthorizationResponse.cs b/src/DotNetOAuth/OAuth/Messages/UserAuthorizationResponse.cs
new file mode 100644
index 0000000..ab66dfe
--- /dev/null
+++ b/src/DotNetOAuth/OAuth/Messages/UserAuthorizationResponse.cs
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------
+// <copyright file="UserAuthorizationResponse.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.OAuth.Messages {
+ using System;
+ using DotNetOAuth.Messaging;
+
+ /// <summary>
+ /// A message used to redirect the user from a Service Provider to a Consumer's web site.
+ /// </summary>
+ /// <remarks>
+ /// The class is sealed because extra parameters are determined by the callback URI provided by the Consumer.
+ /// </remarks>
+ public sealed class UserAuthorizationResponse : MessageBase, ITokenContainingMessage {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UserAuthorizationResponse"/> class.
+ /// </summary>
+ /// <param name="consumer">The URI of the Consumer endpoint to send this message to.</param>
+ internal UserAuthorizationResponse(Uri consumer)
+ : base(MessageProtections.None, MessageTransport.Indirect, new MessageReceivingEndpoint(consumer, HttpDeliveryMethods.GetRequest)) {
+ }
+
+ /// <summary>
+ /// Gets or sets the Request or Access Token.
+ /// </summary>
+ string ITokenContainingMessage.Token {
+ get { return this.RequestToken; }
+ set { this.RequestToken = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the Request Token.
+ /// </summary>
+ [MessagePart("oauth_token", IsRequired = true)]
+ internal string RequestToken { get; set; }
+ }
+}