//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OAuth.Messages { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OAuth.ChannelElements; /// /// A base class for all signed OAuth messages. /// public class SignedMessageBase : MessageBase, ITamperResistantOAuthMessage, IExpiringProtocolMessage, IReplayProtectedProtocolMessage { /// /// The reference date and time for calculating time stamps. /// private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); /// /// The number of seconds since 1/1/1970, consistent with the OAuth timestamp requirement. /// [MessagePart("oauth_timestamp", IsRequired = true)] private long timestamp; /// /// Initializes a new instance of the class. /// /// A value indicating whether this message requires a direct or indirect transport. /// The URI that a directed message will be delivered to. /// The OAuth version. internal SignedMessageBase(MessageTransport transport, MessageReceivingEndpoint recipient, Version version) : base(MessageProtections.All, transport, recipient, version) { ITamperResistantOAuthMessage self = (ITamperResistantOAuthMessage)this; HttpDeliveryMethods methods = ((IDirectedProtocolMessage)this).HttpMethods; self.HttpMethod = MessagingUtilities.GetHttpVerb(methods); } #region ITamperResistantOAuthMessage Members /// /// Gets or sets the signature method used to sign the request. /// string ITamperResistantOAuthMessage.SignatureMethod { get { return this.SignatureMethod; } set { this.SignatureMethod = value; } } /// /// Gets or sets the Token Secret used to sign the message. /// string ITamperResistantOAuthMessage.TokenSecret { get { return this.TokenSecret; } set { this.TokenSecret = value; } } /// /// Gets or sets the Consumer key. /// [MessagePart("oauth_consumer_key", IsRequired = true)] public string ConsumerKey { get; set; } /// /// Gets or sets the Consumer Secret used to sign the message. /// string ITamperResistantOAuthMessage.ConsumerSecret { get { return this.ConsumerSecret; } set { this.ConsumerSecret = value; } } /// /// Gets or sets the HTTP method that will be used to transmit the message. /// string ITamperResistantOAuthMessage.HttpMethod { get { return this.HttpMethod; } set { this.HttpMethod = value; } } /// /// Gets or sets the URI to the Service Provider endpoint to send this message to. /// Uri ITamperResistantOAuthMessage.Recipient { get { return this.Recipient; } set { this.Recipient = value; } } #endregion #region ITamperResistantProtocolMessage Members /// /// Gets or sets the message signature. /// string ITamperResistantProtocolMessage.Signature { get { return this.Signature; } set { this.Signature = value; } } #endregion #region IExpiringProtocolMessage Members /// /// Gets or sets the OAuth timestamp of the message. /// DateTime IExpiringProtocolMessage.UtcCreationDate { get { return epoch + TimeSpan.FromSeconds(this.timestamp); } set { this.timestamp = (long)(value - epoch).TotalSeconds; } } #endregion #region IReplayProtectedProtocolMessage Members /// /// Gets the context within which the nonce must be unique. /// /// The consumer key. string IReplayProtectedProtocolMessage.NonceContext { get { return this.ConsumerKey; } } /// /// Gets or sets the message nonce used for replay detection. /// [MessagePart("oauth_nonce", IsRequired = true)] string IReplayProtectedProtocolMessage.Nonce { get; set; } #endregion #region IMessageOriginalPayload Members /// /// Gets or sets the original message parts, before any normalization or default values were assigned. /// IDictionary IMessageOriginalPayload.OriginalPayload { get { return this.OriginalPayload; } set { this.OriginalPayload = value; } } /// /// Gets or sets the original message parts, before any normalization or default values were assigned. /// [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "By design")] protected IDictionary OriginalPayload { get; set; } #endregion /// /// Gets or sets the signature method used to sign the request. /// [MessagePart("oauth_signature_method", IsRequired = true)] protected string SignatureMethod { get; set; } /// /// Gets or sets the Token Secret used to sign the message. /// protected string TokenSecret { get; set; } /// /// Gets or sets the Consumer Secret used to sign the message. /// protected string ConsumerSecret { get; set; } /// /// Gets or sets the HTTP method that will be used to transmit the message. /// protected string HttpMethod { get; set; } /// /// Gets or sets the message signature. /// [MessagePart("oauth_signature", IsRequired = true)] protected string Signature { get; set; } /// /// Gets or sets the version of the protocol this message was created with. /// [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Accessed via reflection.")] [MessagePart("oauth_version", IsRequired = false)] private string OAuthVersion { get { return Protocol.Lookup(Version).PublishedVersion; } set { if (value != this.OAuthVersion) { throw new ArgumentOutOfRangeException("value"); } } } } }