//-----------------------------------------------------------------------
//
// Copyright (c) Andrew Arnott. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
///
/// A common base class for OpenID request messages and indirect responses (since they are ultimately requests).
///
[DebuggerDisplay("OpenID {Version} {Mode}")]
[Serializable]
internal class RequestBase : IDirectedProtocolMessage {
///
/// The openid.ns parameter in the message.
///
/// "http://specs.openid.net/auth/2.0"
///
/// This particular value MUST be present for the request to be a valid OpenID Authentication 2.0 request. Future versions of the specification may define different values in order to allow message recipients to properly interpret the request.
///
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Read by reflection.")]
[MessagePart("openid.ns", IsRequired = true, AllowEmpty = false, MinVersion = "2.0")]
#pragma warning disable 0414 // read by reflection
private readonly string OpenIdNamespace = Protocol.OpenId2Namespace;
#pragma warning restore 0414
///
/// Backing store for the property.
///
private readonly Dictionary extraData = new Dictionary();
///
/// Backing store for the property.
///
private bool incoming;
///
/// Initializes a new instance of the class.
///
/// The OpenID version this message must comply with.
/// The OpenID Provider endpoint.
/// The value for the openid.mode parameter.
/// A value indicating whether the message will be transmitted directly or indirectly.
protected RequestBase(Version version, Uri providerEndpoint, string mode, MessageTransport transport) {
Requires.NotNull(providerEndpoint, "providerEndpoint");
Requires.NotNullOrEmpty(mode, "mode");
this.Recipient = providerEndpoint;
this.Mode = mode;
this.Transport = transport;
this.Version = version;
}
///
/// Gets the value of the openid.mode parameter.
///
[MessagePart("openid.mode", IsRequired = true, AllowEmpty = false)]
public string Mode { get; private set; }
#region IDirectedProtocolMessage Members
///
/// Gets the preferred method of transport for the message.
///
///
/// For direct messages this is the OpenID mandated POST.
/// For indirect messages both GET and POST are allowed.
///
HttpDeliveryMethods IDirectedProtocolMessage.HttpMethods {
get {
// OpenID 2.0 section 5.1.1
HttpDeliveryMethods methods = HttpDeliveryMethods.PostRequest;
if (this.Transport == MessageTransport.Indirect) {
methods |= HttpDeliveryMethods.GetRequest;
}
return methods;
}
}
///
/// Gets the recipient of the message.
///
/// The OP endpoint, or the RP return_to.
public Uri Recipient {
get;
private set;
}
#endregion
#region IProtocolMessage Properties
///
/// Gets the version of the protocol this message is prepared to implement.
///
/// Version 2.0
public Version Version { get; private set; }
///
/// Gets the level of protection this message requires.
///
///
public virtual MessageProtections RequiredProtection {
get { return MessageProtections.None; }
}
///
/// Gets a value indicating whether this is a direct or indirect message.
///
///
public MessageTransport Transport { get; private set; }
///
/// Gets the extra parameters included in the message.
///
/// An empty dictionary.
public IDictionary ExtraData {
get { return this.extraData; }
}
#endregion
///
/// Gets a value indicating whether this message was deserialized as an incoming message.
///
protected internal bool Incoming {
get { return this.incoming; }
}
///
/// Gets the protocol used by this message.
///
protected Protocol Protocol {
get { return Protocol.Lookup(this.Version); }
}
#region IProtocolMessage Methods
///
/// Checks the message state for conformity to the protocol specification
/// and throws an exception if the message is invalid.
///
///
/// Some messages have required fields, or combinations of fields that must relate to each other
/// in specialized ways. After deserializing a message, this method checks the state of the
/// message to see if it conforms to the protocol.
/// Note that this property should not check signatures or perform any state checks
/// outside this scope of this particular message.
///
/// Thrown if the message is invalid.
public virtual void EnsureValidMessage() {
}
#endregion
///
/// Sets a flag indicating that this message is received (as opposed to sent).
///
internal void SetAsIncoming() {
this.incoming = true;
}
///
/// Gets some string from a given version of the OpenID protocol.
///
/// The protocol version to use for lookup.
/// A function that can retrieve the desired protocol constant.
/// The value of the constant.
///
/// This method can be used by a constructor to throw an
/// instead of a .
///
protected static string GetProtocolConstant(Version protocolVersion, Func mode) {
Requires.NotNull(protocolVersion, "protocolVersion");
return mode(Protocol.Lookup(protocolVersion));
}
}
}