//-----------------------------------------------------------------------
//
// 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");
}
}
}
}
}