//-----------------------------------------------------------------------
//
// Copyright (c) Andrew Arnott. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOAuth.Messages {
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using DotNetOAuth.ChannelElements;
using DotNetOAuth.Messaging;
using DotNetOAuth.Messaging.Reflection;
///
/// A base class for all OAuth messages.
///
internal abstract class MessageBase : IOAuthDirectedMessage {
///
/// A store for extra name/value data pairs that are attached to this message.
///
private Dictionary extraData = new Dictionary();
///
/// Gets a value indicating whether signing this message is required.
///
private MessageProtection protectionRequired;
///
/// Gets a value indicating whether this is a direct or indirect message.
///
private MessageTransport transport;
///
/// The URI to the remote endpoint to send this message to.
///
private MessageReceivingEndpoint recipient;
#if DEBUG
///
/// Initializes static members of the class.
///
static MessageBase() {
LowSecurityMode = true;
}
#endif
///
/// Initializes a new instance of the class.
///
/// The level of protection the message requires.
/// A value indicating whether this message requires a direct or indirect transport.
protected MessageBase(MessageProtection protectionRequired, MessageTransport transport) {
this.protectionRequired = protectionRequired;
this.transport = transport;
}
///
/// Initializes a new instance of the class.
///
/// The level of protection the message requires.
/// A value indicating whether this message requires a direct or indirect transport.
/// The URI that a directed message will be delivered to.
protected MessageBase(MessageProtection protectionRequired, MessageTransport transport, MessageReceivingEndpoint recipient) {
if (recipient == null) {
throw new ArgumentNullException("recipient");
}
this.protectionRequired = protectionRequired;
this.transport = transport;
this.recipient = recipient;
}
#region IProtocolMessage Properties
///
/// Gets the version of the protocol this message is prepared to implement.
///
Version IProtocolMessage.ProtocolVersion {
get { return new Version(1, 0); }
}
///
/// Gets the level of protection this message requires.
///
MessageProtection IProtocolMessage.RequiredProtection {
get { return this.protectionRequired; }
}
///
/// Gets a value indicating whether this is a direct or indirect message.
///
MessageTransport IProtocolMessage.Transport {
get { return this.transport; }
}
///
/// Gets the dictionary of additional name/value fields tacked on to this message.
///
IDictionary IProtocolMessage.ExtraData {
get { return this.extraData; }
}
#endregion
#region IDirectedProtocolMessage Members
///
/// Gets the URI to the Service Provider endpoint to send this message to.
///
Uri IDirectedProtocolMessage.Recipient {
get { return this.recipient.Location; }
}
#endregion
#region IOAuthDirectedMessage Properties
///
/// Gets the preferred method of transport for the message.
///
HttpDeliveryMethod IOAuthDirectedMessage.HttpMethods {
get { return this.recipient != null ? this.recipient.AllowedMethods : HttpDeliveryMethod.None; }
}
///
/// Gets or sets the URI to the Service Provider endpoint to send this message to.
///
Uri IOAuthDirectedMessage.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();
}
}
}
#endregion
///
/// Gets or sets a value indicating whether security sensitive strings are
/// emitted from the ToString() method.
///
internal static bool LowSecurityMode { get; set; }
#region IProtocolMessage Methods
///
/// Checks the message state for conformity to the protocol specification
/// and throws an exception if the message is invalid.
///
void IProtocolMessage.EnsureValidMessage() {
this.EnsureValidMessage();
}
#endregion
///
/// Returns a human-friendly string describing the message and all serializable properties.
///
/// The string representation of this object.
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();
}
///
/// Checks the message state for conformity to the protocol specification
/// and throws an exception if the message is invalid.
///
protected virtual void EnsureValidMessage() { }
}
}