diff options
11 files changed, 245 insertions, 17 deletions
diff --git a/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs b/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs index db5dd24..f502f17 100644 --- a/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs +++ b/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs @@ -68,7 +68,13 @@ namespace DotNetOpenAuth.Messaging { /// Code Contract for the <see cref="IChannelBindingElement"/> interface. /// </summary> [ContractClassFor(typeof(IChannelBindingElement))] - internal class IChannelBindingElementContract : IChannelBindingElement { + internal abstract class IChannelBindingElementContract : IChannelBindingElement { + /// <summary> + /// Prevents a default instance of the <see cref="IChannelBindingElementContract"/> class from being created. + /// </summary> + private IChannelBindingElementContract() { + } + #region IChannelBindingElement Members /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/IMessage.cs b/src/DotNetOpenAuth/Messaging/IMessage.cs index 031e908..e91a160 100644 --- a/src/DotNetOpenAuth/Messaging/IMessage.cs +++ b/src/DotNetOpenAuth/Messaging/IMessage.cs @@ -51,7 +51,13 @@ namespace DotNetOpenAuth.Messaging { /// Code contract for the <see cref="IMessage"/> interface. /// </summary> [ContractClassFor(typeof(IMessage))] - internal sealed class IMessageContract : IMessage { + internal abstract class IMessageContract : IMessage { + /// <summary> + /// Prevents a default instance of the <see cref="IMessageContract"/> class from being created. + /// </summary> + private IMessageContract() { + } + /// <summary> /// Gets the version of the protocol or extension this message is prepared to implement. /// </summary> diff --git a/src/DotNetOpenAuth/Messaging/IMessageFactory.cs b/src/DotNetOpenAuth/Messaging/IMessageFactory.cs index 3718545..f9ddf3d 100644 --- a/src/DotNetOpenAuth/Messaging/IMessageFactory.cs +++ b/src/DotNetOpenAuth/Messaging/IMessageFactory.cs @@ -46,7 +46,13 @@ namespace DotNetOpenAuth.Messaging { /// Code contract for the <see cref="IMessageFactory"/> interface. /// </summary> [ContractClassFor(typeof(IMessageFactory))] - internal class IMessageFactoryContract : IMessageFactory { + internal abstract class IMessageFactoryContract : IMessageFactory { + /// <summary> + /// Prevents a default instance of the <see cref="IMessageFactoryContract"/> class from being created. + /// </summary> + private IMessageFactoryContract() { + } + #region IMessageFactory Members /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/IMessageWithBinaryData.cs b/src/DotNetOpenAuth/Messaging/IMessageWithBinaryData.cs new file mode 100644 index 0000000..f411cf5 --- /dev/null +++ b/src/DotNetOpenAuth/Messaging/IMessageWithBinaryData.cs @@ -0,0 +1,152 @@ +//----------------------------------------------------------------------- +// <copyright file="IMessageWithBinaryData.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Messaging { + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Text; + + /// <summary> + /// The interface that classes must implement to be serialized/deserialized + /// as protocol or extension messages that uses POST multi-part data for binary content. + /// </summary> + [ContractClass(typeof(IMessageWithBinaryDataContract))] + public interface IMessageWithBinaryData : IDirectedProtocolMessage { + /// <summary> + /// Gets the parts of the message that carry binary data. + /// </summary> + /// <value>A list of parts. Never null.</value> + IList<MultipartPostPart> BinaryData { get; } + + /// <summary> + /// Gets a value indicating whether this message should be sent as multi-part POST. + /// </summary> + bool SendAsMultipart { get; } + } + + /// <summary> + /// The contract class for the <see cref="IMessageWithBinaryData"/> interface. + /// </summary> + [ContractClassFor(typeof(IMessageWithBinaryData))] + internal sealed class IMessageWithBinaryDataContract : IMessageWithBinaryData { + #region IMessageWithBinaryData Members + + /// <summary> + /// Gets the parts of the message that carry binary data. + /// </summary> + /// <value>A list of parts. Never null.</value> + IList<MultipartPostPart> IMessageWithBinaryData.BinaryData { + get { + Contract.Ensures(Contract.Result<IList<MultipartPostPart>>() != null); + throw new NotImplementedException(); + } + } + + /// <summary> + /// Gets a value indicating whether this message should be sent as multi-part POST. + /// </summary> + bool IMessageWithBinaryData.SendAsMultipart { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IMessage Properties + + /// <summary> + /// Gets the version of the protocol or extension this message is prepared to implement. + /// </summary> + /// <value></value> + /// <remarks> + /// Implementations of this interface should ensure that this property never returns null. + /// </remarks> + Version IMessage.Version { + get { + Contract.Ensures(Contract.Result<Version>() != null); + return default(Version); // dummy return + } + } + + /// <summary> + /// Gets the extra, non-standard Protocol parameters included in the message. + /// </summary> + /// <value></value> + /// <remarks> + /// Implementations of this interface should ensure that this property never returns null. + /// </remarks> + IDictionary<string, string> IMessage.ExtraData { + get { + Contract.Ensures(Contract.Result<IDictionary<string, string>>() != null); + return default(IDictionary<string, string>); + } + } + + #endregion + + #region IDirectedProtocolMessage Members + + /// <summary> + /// Gets the preferred method of transport for the message. + /// </summary> + /// <remarks> + /// For indirect messages this will likely be GET+POST, which both can be simulated in the user agent: + /// the GET with a simple 301 Redirect, and the POST with an HTML form in the response with javascript + /// to automate submission. + /// </remarks> + HttpDeliveryMethods IDirectedProtocolMessage.HttpMethods { + get { throw new NotImplementedException(); } + } + + /// <summary> + /// Gets the URL of the intended receiver of this message. + /// </summary> + Uri IDirectedProtocolMessage.Recipient { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IProtocolMessage Members + + /// <summary> + /// Gets the level of protection this message requires. + /// </summary> + MessageProtections IProtocolMessage.RequiredProtection { + get { throw new NotImplementedException(); } + } + + /// <summary> + /// Gets a value indicating whether this is a direct or indirect message. + /// </summary> + MessageTransport IProtocolMessage.Transport { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IMessage methods + + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>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.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> + void IMessage.EnsureValidMessage() { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/Messaging/IProtocolMessageWithExtensions.cs b/src/DotNetOpenAuth/Messaging/IProtocolMessageWithExtensions.cs index c45bec9..44c4cbb 100644 --- a/src/DotNetOpenAuth/Messaging/IProtocolMessageWithExtensions.cs +++ b/src/DotNetOpenAuth/Messaging/IProtocolMessageWithExtensions.cs @@ -27,7 +27,7 @@ namespace DotNetOpenAuth.Messaging { /// Code contract for the <see cref="IProtocolMessageWithExtensions"/> interface. /// </summary> [ContractClassFor(typeof(IProtocolMessageWithExtensions))] - internal class IProtocolMessageWithExtensionsContract : IProtocolMessageWithExtensions { + internal abstract class IProtocolMessageWithExtensionsContract : IProtocolMessageWithExtensions { /// <summary> /// Prevents a default instance of the <see cref="IProtocolMessageWithExtensionsContract"/> class from being created. /// </summary> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs index b53be81..7df67ce 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs @@ -84,11 +84,11 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// Code contract class for the <see cref="IServiceProviderTokenManager"/> interface. /// </summary> [ContractClassFor(typeof(IServiceProviderTokenManager))] - internal class IServiceProviderTokenManagerContract : IServiceProviderTokenManager { + internal abstract class IServiceProviderTokenManagerContract : IServiceProviderTokenManager { /// <summary> - /// Initializes a new instance of the <see cref="IServiceProviderTokenManagerContract"/> class. + /// Prevents a default instance of the <see cref="IServiceProviderTokenManagerContract"/> class from being created. /// </summary> - internal IServiceProviderTokenManagerContract() { + private IServiceProviderTokenManagerContract() { } #region IServiceProviderTokenManager Members diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs index 532e4b0..459cd28 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs @@ -79,11 +79,11 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// The code contract class for the <see cref="ITokenManager"/> interface. /// </summary> [ContractClassFor(typeof(ITokenManager))] - internal class ITokenManagerContract : ITokenManager { + internal abstract class ITokenManagerContract : ITokenManager { /// <summary> - /// Initializes a new instance of the <see cref="ITokenManagerContract"/> class. + /// Prevents a default instance of the <see cref="ITokenManagerContract"/> class from being created. /// </summary> - internal ITokenManagerContract() { + private ITokenManagerContract() { } #region ITokenManager Members diff --git a/src/DotNetOpenAuth/OpenId/IIdentifierDiscoveryService.cs b/src/DotNetOpenAuth/OpenId/IIdentifierDiscoveryService.cs new file mode 100644 index 0000000..eb2bf98 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/IIdentifierDiscoveryService.cs @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------- +// <copyright file="IIdentifierDiscoveryService.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// <summary> + /// A module that provides discovery services for OpenID identifiers. + /// </summary> + [ContractClass(typeof(IIdentifierDiscoveryServiceContract))] + public interface IIdentifierDiscoveryService { + /// <summary> + /// Performs discovery on the specified identifier. + /// </summary> + /// <param name="identifier">The identifier to perform discovery on.</param> + /// <param name="requestHandler">The means to place outgoing HTTP requests.</param> + /// <param name="abortDiscoveryChain">if set to <c>true</c>, no further discovery services will be called for this identifier.</param> + /// <returns> + /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. + /// </returns> + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "By design")] + [Pure] + IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain); + } + + /// <summary> + /// Code contract for the <see cref="IIdentifierDiscoveryService"/> interface. + /// </summary> + [ContractClassFor(typeof(IIdentifierDiscoveryService))] + internal class IIdentifierDiscoveryServiceContract : IIdentifierDiscoveryService { + #region IDiscoveryService Members + + /// <summary> + /// Performs discovery on the specified identifier. + /// </summary> + /// <param name="identifier">The identifier to perform discovery on.</param> + /// <param name="requestHandler">The means to place outgoing HTTP requests.</param> + /// <param name="abortDiscoveryChain">if set to <c>true</c>, no further discovery services will be called for this identifier.</param> + /// <returns> + /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. + /// </returns> + IEnumerable<IdentifierDiscoveryResult> IIdentifierDiscoveryService.Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { + Contract.Requires<ArgumentNullException>(identifier != null); + Contract.Requires<ArgumentNullException>(requestHandler != null); + Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null); + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs b/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs index 96e947f..08e02ba 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs @@ -58,7 +58,7 @@ namespace DotNetOpenAuth.OpenId.Messages { /// Code contract class for the IOpenIdMessageExtension interface. /// </summary> [ContractClassFor(typeof(IOpenIdMessageExtension))] - internal class IOpenIdMessageExtensionContract : IOpenIdMessageExtension { + internal abstract class IOpenIdMessageExtensionContract : IOpenIdMessageExtension { /// <summary> /// Prevents a default instance of the <see cref="IOpenIdMessageExtensionContract"/> class from being created. /// </summary> diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs index 300a15f..1bfa0db 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs @@ -45,11 +45,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// Contract class for the <see cref="IRelyingPartyBehavior"/> interface. /// </summary> [ContractClassFor(typeof(IRelyingPartyBehavior))] - internal class IRelyingPartyBehaviorContract : IRelyingPartyBehavior { + internal abstract class IRelyingPartyBehaviorContract : IRelyingPartyBehavior { /// <summary> - /// Initializes a new instance of the <see cref="IRelyingPartyBehaviorContract"/> class. + /// Prevents a default instance of the <see cref="IRelyingPartyBehaviorContract"/> class from being created. /// </summary> - protected IRelyingPartyBehaviorContract() { + private IRelyingPartyBehaviorContract() { } #region IRelyingPartyBehavior Members diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs index e0e2b0b..3523f81 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs @@ -48,9 +48,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } bool IProviderEndpoint.IsExtensionSupported(System.Type extensionType) { - Contract.Requires<ArgumentNullException>(extensionType != null); - Contract.Requires<ArgumentException>(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType)); - ////ErrorUtilities.VerifyArgument(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType), string.Format(CultureInfo.CurrentCulture, OpenIdStrings.TypeMustImplementX, typeof(IOpenIdMessageExtension).FullName)); throw new System.NotImplementedException(); } |