summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-11-27 12:10:03 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2009-11-27 12:10:03 -0700
commit0ed1e01369d918ad828fa64728f89f9d2c675fdb (patch)
tree85ac9fb81153d6b8fb3774046f4fc28ab3f5df1f /src
parent1243c92a0172784f32938a2081f76463f90f102d (diff)
parent3d0b19ba07c1044b433d97e90ffe0489fee967dc (diff)
downloadDotNetOpenAuth-0ed1e01369d918ad828fa64728f89f9d2c675fdb.zip
DotNetOpenAuth-0ed1e01369d918ad828fa64728f89f9d2c675fdb.tar.gz
DotNetOpenAuth-0ed1e01369d918ad828fa64728f89f9d2c675fdb.tar.bz2
Merge branch 'master' into extensibleDiscovery
Conflicts: src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs3
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/DiffieHellmanTests.cs4
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd41
-rw-r--r--src/DotNetOpenAuth/Configuration/OAuthServiceProviderElement.cs15
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj2
-rw-r--r--src/DotNetOpenAuth/Logger.cs1
-rw-r--r--src/DotNetOpenAuth/Messaging/Bindings/INonceStore.cs9
-rw-r--r--src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs7
-rw-r--r--src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs7
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs13
-rw-r--r--src/DotNetOpenAuth/OAuth/ServiceProvider.cs36
-rw-r--r--src/DotNetOpenAuth/OpenId/Association.cs14
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs4
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs108
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs9
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdStrings.resx3
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs4
-rw-r--r--src/DotNetOpenAuth/Strings.Designer.cs11
-rw-r--r--src/DotNetOpenAuth/Strings.resx5
-rw-r--r--src/DotNetOpenAuth/Xrds/TypeElement.cs4
-rw-r--r--src/DotNetOpenAuth/Xrds/XrdsNode.cs1
22 files changed, 271 insertions, 37 deletions
diff --git a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs b/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
index 4373402..5967a03 100644
--- a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Test {
using System;
using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.Test.Mocks;
@@ -58,7 +59,7 @@ namespace DotNetOpenAuth.Test {
WebConsumer consumer = new WebConsumer(this.serviceDescription, consumerTokenManager) {
OAuthChannel = consumerChannel,
};
- ServiceProvider serviceProvider = new ServiceProvider(this.serviceDescription, serviceTokenManager) {
+ ServiceProvider serviceProvider = new ServiceProvider(this.serviceDescription, serviceTokenManager, new NonceMemoryStore()) {
OAuthChannel = serviceProviderChannel,
};
diff --git a/src/DotNetOpenAuth.Test/OpenId/DiffieHellmanTests.cs b/src/DotNetOpenAuth.Test/OpenId/DiffieHellmanTests.cs
index fbbea71..426e19a 100644
--- a/src/DotNetOpenAuth.Test/OpenId/DiffieHellmanTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/DiffieHellmanTests.cs
@@ -13,7 +13,7 @@ namespace DotNetOpenAuth.Test.OpenId {
using Org.Mentalis.Security.Cryptography;
[TestClass]
- public class DiffieHellmanTests {
+ public class DiffieHellmanTests : OpenIdTestBase {
[TestMethod]
public void Test() {
string s1 = Test1();
@@ -28,7 +28,9 @@ namespace DotNetOpenAuth.Test.OpenId {
try {
string line;
+ int lineNumber = 0;
while ((line = reader.ReadLine()) != null) {
+ TestContext.WriteLine("\tLine {0}", ++lineNumber);
string[] parts = line.Trim().Split(' ');
byte[] x = Convert.FromBase64String(parts[0]);
DiffieHellmanManaged dh = new DiffieHellmanManaged(AssociateDiffieHellmanRequest.DefaultMod, AssociateDiffieHellmanRequest.DefaultGen, x);
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
index 0bef2df..7d10b21 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd
@@ -293,6 +293,47 @@
<xs:attribute name="maxAuthenticationTime" type="xs:string" />
</xs:complexType>
</xs:element>
+ <xs:element name="oauth">
+ <xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="consumer">
+ <xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="security">
+ <xs:complexType>
+
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="serviceProvider">
+ <xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="security">
+ <xs:complexType>
+ <xs:attribute name="minimumRequiredOAuthVersion" default="V10">
+ <xs:simpleType>
+ <xs:restriction base="xs:NMTOKEN">
+ <xs:enumeration value="V10" />
+ <xs:enumeration value="V10a" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="maxAuthorizationTime" type="xs:string" default="0:05" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="store">
+ <xs:complexType>
+ <xs:attribute name="type" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
diff --git a/src/DotNetOpenAuth/Configuration/OAuthServiceProviderElement.cs b/src/DotNetOpenAuth/Configuration/OAuthServiceProviderElement.cs
index 5ff528d..8e910a0 100644
--- a/src/DotNetOpenAuth/Configuration/OAuthServiceProviderElement.cs
+++ b/src/DotNetOpenAuth/Configuration/OAuthServiceProviderElement.cs
@@ -6,12 +6,18 @@
namespace DotNetOpenAuth.Configuration {
using System.Configuration;
+ using DotNetOpenAuth.Messaging.Bindings;
/// <summary>
/// Represents the &lt;oauth/serviceProvider&gt; element in the host's .config file.
/// </summary>
internal class OAuthServiceProviderElement : ConfigurationElement {
/// <summary>
+ /// The name of the custom store sub-element.
+ /// </summary>
+ private const string StoreConfigName = "store";
+
+ /// <summary>
/// Gets the name of the security sub-element.
/// </summary>
private const string SecuritySettingsConfigName = "security";
@@ -23,6 +29,15 @@ namespace DotNetOpenAuth.Configuration {
}
/// <summary>
+ /// Gets or sets the type to use for storing application state.
+ /// </summary>
+ [ConfigurationProperty(StoreConfigName)]
+ public TypeConfigurationElement<INonceStore> ApplicationStore {
+ get { return (TypeConfigurationElement<INonceStore>)this[StoreConfigName] ?? new TypeConfigurationElement<INonceStore>(); }
+ set { this[StoreConfigName] = value; }
+ }
+
+ /// <summary>
/// Gets or sets the security settings.
/// </summary>
[ConfigurationProperty(SecuritySettingsConfigName)]
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index 95a7150..5246b96 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -75,7 +75,7 @@ http://opensource.org/licenses/ms-pl.html
</CodeContractsCustomRewriterAssembly>
<CodeContractsCustomRewriterClass>
</CodeContractsCustomRewriterClass>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsRuntimeCheckingLevel>ReleaseRequires</CodeContractsRuntimeCheckingLevel>
<CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
<CodeContractsBuildReferenceAssembly>True</CodeContractsBuildReferenceAssembly>
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
diff --git a/src/DotNetOpenAuth/Logger.cs b/src/DotNetOpenAuth/Logger.cs
index 1c1b8a5..a9dbef2 100644
--- a/src/DotNetOpenAuth/Logger.cs
+++ b/src/DotNetOpenAuth/Logger.cs
@@ -143,6 +143,7 @@ namespace DotNetOpenAuth {
/// <param name="name">A name that will be included in the log file.</param>
/// <returns>The <see cref="ILog"/> instance created with the given name.</returns>
internal static ILog CreateWithBanner(string name) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(name));
ILog log = Create(name);
log.Info(Util.LibraryVersion);
return log;
diff --git a/src/DotNetOpenAuth/Messaging/Bindings/INonceStore.cs b/src/DotNetOpenAuth/Messaging/Bindings/INonceStore.cs
index fff251a..6b6e2e1 100644
--- a/src/DotNetOpenAuth/Messaging/Bindings/INonceStore.cs
+++ b/src/DotNetOpenAuth/Messaging/Bindings/INonceStore.cs
@@ -19,11 +19,12 @@ namespace DotNetOpenAuth.Messaging.Bindings {
/// The context SHOULD be treated as case-sensitive.
/// The value will never be <c>null</c> but may be the empty string.</param>
/// <param name="nonce">A series of random characters.</param>
- /// <param name="timestamp">The timestamp that together with the nonce string make it unique.
+ /// <param name="timestampUtc">The UTC timestamp that together with the nonce string make it unique
+ /// within the given <paramref name="context"/>.
/// The timestamp may also be used by the data store to clear out old nonces.</param>
/// <returns>
- /// True if the nonce+timestamp (combination) was not previously in the database.
- /// False if the nonce was stored previously with the same timestamp.
+ /// True if the context+nonce+timestamp (combination) was not previously in the database.
+ /// False if the nonce was stored previously with the same timestamp and context.
/// </returns>
/// <remarks>
/// The nonce must be stored for no less than the maximum time window a message may
@@ -33,6 +34,6 @@ namespace DotNetOpenAuth.Messaging.Bindings {
/// property, accessible via the <see cref="DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Configuration"/>
/// property.
/// </remarks>
- bool StoreNonce(string context, string nonce, DateTime timestamp);
+ bool StoreNonce(string context, string nonce, DateTime timestampUtc);
}
}
diff --git a/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs b/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs
index 3d624a6..6e64acc 100644
--- a/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs
+++ b/src/DotNetOpenAuth/Messaging/Bindings/NonceMemoryStore.cs
@@ -47,6 +47,13 @@ namespace DotNetOpenAuth.Messaging.Bindings {
/// <summary>
/// Initializes a new instance of the <see cref="NonceMemoryStore"/> class.
/// </summary>
+ internal NonceMemoryStore()
+ : this(StandardExpirationBindingElement.MaximumMessageAge) {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NonceMemoryStore"/> class.
+ /// </summary>
/// <param name="maximumMessageAge">The maximum age a message can be before it is discarded.</param>
internal NonceMemoryStore(TimeSpan maximumMessageAge) {
this.maximumMessageAge = maximumMessageAge;
diff --git a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs
index c7ac581..e26a672 100644
--- a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs
+++ b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs
@@ -21,7 +21,10 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="locationUri">The URL of this endpoint.</param>
/// <param name="method">The HTTP method(s) allowed.</param>
public MessageReceivingEndpoint(string locationUri, HttpDeliveryMethods method)
- : this(new Uri(locationUri), method) { }
+ : this(new Uri(locationUri), method) {
+ Contract.Requires<ArgumentNullException>(locationUri != null);
+ Contract.Requires<ArgumentOutOfRangeException>(method != HttpDeliveryMethods.None);
+ }
/// <summary>
/// Initializes a new instance of the <see cref="MessageReceivingEndpoint"/> class.
@@ -30,7 +33,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="method">The HTTP method(s) allowed.</param>
public MessageReceivingEndpoint(Uri location, HttpDeliveryMethods method) {
Contract.Requires<ArgumentNullException>(location != null);
- Contract.Requires<ArgumentOutOfRangeException>(method != HttpDeliveryMethods.None, "method");
+ Contract.Requires<ArgumentOutOfRangeException>(method != HttpDeliveryMethods.None);
Contract.Requires<ArgumentOutOfRangeException>((method & HttpDeliveryMethods.HttpVerbMask) != 0, MessagingStrings.GetOrPostFlagsRequired);
this.Location = location;
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index ba68227..e1e3f59 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -326,6 +326,10 @@ namespace DotNetOpenAuth.Messaging {
/// The positions are NOT reset after copying is complete.
/// </remarks>
internal static int CopyTo(this Stream copyFrom, Stream copyTo) {
+ Contract.Requires<ArgumentNullException>(copyFrom != null);
+ Contract.Requires<ArgumentNullException>(copyTo != null);
+ Contract.Requires<ArgumentException>(copyFrom.CanRead, MessagingStrings.StreamUnreadable);
+ Contract.Requires<ArgumentException>(copyTo.CanWrite, MessagingStrings.StreamUnwritable);
return CopyTo(copyFrom, copyTo, int.MaxValue);
}
@@ -366,6 +370,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>A seekable stream with the same contents as the original.</returns>
internal static Stream CreateSnapshot(this Stream copyFrom) {
Contract.Requires<ArgumentNullException>(copyFrom != null);
+ Contract.Requires<ArgumentException>(copyFrom.CanRead);
MemoryStream copyTo = new MemoryStream(copyFrom.CanSeek ? (int)copyFrom.Length : 4 * 1024);
copyFrom.CopyTo(copyTo);
@@ -380,6 +385,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>The newly created instance.</returns>
internal static HttpWebRequest Clone(this HttpWebRequest request) {
Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentException>(request.RequestUri != null);
return Clone(request, request.RequestUri);
}
@@ -547,6 +553,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="second">The second dictionary in the comparison. May not be null.</param>
/// <returns>True if the arrays equal; false otherwise.</returns>
internal static bool AreEquivalent<TKey, TValue>(IDictionary<TKey, TValue> first, IDictionary<TKey, TValue> second) {
+ Contract.Requires<ArgumentNullException>(first != null);
+ Contract.Requires<ArgumentNullException>(second != null);
return AreEquivalent(first.ToArray(), second.ToArray());
}
@@ -752,6 +760,9 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="comparer">A comparison function to compare keys.</param>
/// <returns>An System.Linq.IOrderedEnumerable&lt;TElement&gt; whose elements are sorted according to a key.</returns>
internal static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Comparison<TKey> comparer) {
+ Contract.Requires<ArgumentNullException>(source != null);
+ Contract.Requires<ArgumentNullException>(comparer != null);
+ Contract.Requires<ArgumentNullException>(keySelector != null);
Contract.Ensures(Contract.Result<IOrderedEnumerable<TSource>>() != null);
return System.Linq.Enumerable.OrderBy<TSource, TKey>(source, keySelector, new ComparisonHelper<TKey>(comparer));
}
@@ -850,6 +861,8 @@ namespace DotNetOpenAuth.Messaging {
/// host actually having this configuration element present.
/// </remarks>
internal static string EscapeUriDataStringRfc3986(string value) {
+ Contract.Requires<ArgumentNullException>(value != null);
+
// Start with RFC 2396 escaping by calling the .NET method to do the work.
// This MAY sometimes exhibit RFC 3986 behavior (according to the documentation).
// If it does, the escaping we do that follows it will be a no-op since the
diff --git a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
index 5883273..e2c82bb 100644
--- a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
+++ b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OAuth {
using System;
using System.Collections.Generic;
+ using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Globalization;
@@ -36,6 +37,12 @@ namespace DotNetOpenAuth.OAuth {
/// </remarks>
public class ServiceProvider : IDisposable {
/// <summary>
+ /// The name of the key to use in the HttpApplication cache to store the
+ /// instance of <see cref="NonceMemoryStore"/> to use.
+ /// </summary>
+ private const string ApplicationStoreKey = "DotNetOpenAuth.OAuth.ServiceProvider.HttpApplicationStore";
+
+ /// <summary>
/// The length of the verifier code (in raw bytes before base64 encoding) to generate.
/// </summary>
private const int VerifierCodeLength = 5;
@@ -61,7 +68,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
- : this(serviceDescription, tokenManager, new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge), messageTypeProvider) {
+ : this(serviceDescription, tokenManager, DotNetOpenAuthSection.Configuration.OAuth.ServiceProvider.ApplicationStore.CreateInstance(HttpApplicationStore), messageTypeProvider) {
Contract.Requires<ArgumentNullException>(serviceDescription != null);
Contract.Requires<ArgumentNullException>(tokenManager != null);
Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
@@ -98,6 +105,33 @@ namespace DotNetOpenAuth.OAuth {
}
/// <summary>
+ /// Gets the standard state storage mechanism that uses ASP.NET's
+ /// HttpApplication state dictionary to store associations and nonces.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Advanced)]
+ public static INonceStore HttpApplicationStore {
+ get {
+ Contract.Ensures(Contract.Result<INonceStore>() != null);
+
+ HttpContext context = HttpContext.Current;
+ ErrorUtilities.VerifyOperation(context != null, Strings.StoreRequiredWhenNoHttpContextAvailable, typeof(INonceStore).Name);
+ var store = (INonceStore)context.Application[ApplicationStoreKey];
+ if (store == null) {
+ context.Application.Lock();
+ try {
+ if ((store = (INonceStore)context.Application[ApplicationStoreKey]) == null) {
+ context.Application[ApplicationStoreKey] = store = new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge);
+ }
+ } finally {
+ context.Application.UnLock();
+ }
+ }
+
+ return store;
+ }
+ }
+
+ /// <summary>
/// Gets the description of this Service Provider.
/// </summary>
public ServiceProviderDescription ServiceDescription { get; private set; }
diff --git a/src/DotNetOpenAuth/OpenId/Association.cs b/src/DotNetOpenAuth/OpenId/Association.cs
index d2c84cb..311ba58 100644
--- a/src/DotNetOpenAuth/OpenId/Association.cs
+++ b/src/DotNetOpenAuth/OpenId/Association.cs
@@ -54,7 +54,7 @@ namespace DotNetOpenAuth.OpenId {
public string Handle { get; private set; }
/// <summary>
- /// Gets the time when this <see cref="Association"/> will expire.
+ /// Gets the UTC time when this <see cref="Association"/> will expire.
/// </summary>
public DateTime Expires {
get { return this.Issued + this.TotalLifeLength; }
@@ -83,7 +83,7 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
- /// Gets or sets the time that this <see cref="Association"/> was first created.
+ /// Gets or sets the UTC time that this <see cref="Association"/> was first created.
/// </summary>
internal DateTime Issued { get; set; }
@@ -146,8 +146,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="handle">
/// The <see cref="Handle"/> property of the previous <see cref="Association"/> instance.
/// </param>
- /// <param name="expires">
- /// The value of the <see cref="Expires"/> property of the previous <see cref="Association"/> instance.
+ /// <param name="expiresUtc">
+ /// The UTC value of the <see cref="Expires"/> property of the previous <see cref="Association"/> instance.
/// </param>
/// <param name="privateData">
/// The byte array returned by a call to <see cref="SerializePrivateData"/> on the previous
@@ -158,13 +158,13 @@ namespace DotNetOpenAuth.OpenId {
/// from a custom association store's
/// <see cref="IAssociationStore&lt;TKey&gt;.GetAssociation(TKey, SecuritySettings)"/> method.
/// </returns>
- public static Association Deserialize(string handle, DateTime expires, byte[] privateData) {
+ public static Association Deserialize(string handle, DateTime expiresUtc, byte[] privateData) {
Contract.Requires<ArgumentNullException>(!String.IsNullOrEmpty(handle));
Contract.Requires<ArgumentNullException>(privateData != null);
Contract.Ensures(Contract.Result<Association>() != null);
- expires = expires.ToUniversalTimeSafe();
- TimeSpan remainingLifeLength = expires - DateTime.UtcNow;
+ expiresUtc = expiresUtc.ToUniversalTimeSafe();
+ TimeSpan remainingLifeLength = expiresUtc - DateTime.UtcNow;
byte[] secret = privateData; // the whole of privateData is the secret key for now.
// We figure out what derived type to instantiate based on the length of the secret.
try {
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs b/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs
index 13f9907..0a84266 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs
@@ -20,7 +20,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <summary>
/// The format of auto-generated aliases.
/// </summary>
- private readonly string aliasFormat = "alias{0}";
+ private const string AliasFormat = "alias{0}";
/// <summary>
/// Tracks extension Type URIs and aliases assigned to them.
@@ -68,6 +68,8 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="typeUris">The type URIs to create aliases for.</param>
/// <param name="preferredTypeUriToAliases">An optional dictionary of URI/alias pairs that suggest preferred aliases to use if available for certain type URIs.</param>
public void AssignAliases(IEnumerable<string> typeUris, IDictionary<string, string> preferredTypeUriToAliases) {
+ Contract.Requires<ArgumentNullException>(typeUris != null);
+
// First go through the actually used type URIs and see which ones have matching preferred aliases.
if (preferredTypeUriToAliases != null) {
foreach (string typeUri in typeUris) {
@@ -126,6 +128,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <returns>The Type URI.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the given alias does not have a matching TypeURI.</exception>
public string ResolveAlias(string alias) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(alias));
string typeUri = this.TryResolveAlias(alias);
if (typeUri == null) {
throw new ArgumentOutOfRangeException("alias");
@@ -175,7 +178,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
private string AssignNewAlias(string typeUri) {
Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
ErrorUtilities.VerifyInternal(!this.typeUriToAliasMap.ContainsKey(typeUri), "Oops! This type URI already has an alias!");
- string alias = string.Format(CultureInfo.InvariantCulture, this.aliasFormat, this.typeUriToAliasMap.Count + 1);
+ string alias = string.Format(CultureInfo.InvariantCulture, AliasFormat, this.typeUriToAliasMap.Count + 1);
this.typeUriToAliasMap.Add(typeUri, alias);
this.aliasToTypeUriMap.Add(alias, typeUri);
return alias;
diff --git a/src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs b/src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs
index 41c4e21..86e80ba 100644
--- a/src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs
+++ b/src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs
@@ -16,8 +16,8 @@ namespace DotNetOpenAuth.OpenId.Interop {
using DotNetOpenAuth.OpenId.RelyingParty;
/// <summary>
- /// The COM interface describing the DotNetOpenId functionality available to
- /// COM client relying parties.
+ /// The COM interface describing the DotNetOpenAuth functionality available to
+ /// COM client OpenID relying parties.
/// </summary>
[Guid("56BD3DB0-EE0D-4191-ADFC-1F3705CD2636")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
diff --git a/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs b/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs
index 95080e6..57233ac 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/IOpenIdMessageExtension.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -19,6 +20,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// [<see cref="SerializableAttribute"/>] to allow serializing state servers
/// to cache messages, particularly responses.
/// </remarks>
+ [ContractClass(typeof(IOpenIdMessageExtensionContract))]
public interface IOpenIdMessageExtension : IExtensionMessage {
/// <summary>
/// Gets the TypeURI the extension uses in the OpenID protocol and in XRDS advertisements.
@@ -51,4 +53,110 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// </value>
bool IsSignedByRemoteParty { get; set; }
}
+
+ /// <summary>
+ /// Code contract class for the IOpenIdMessageExtension interface.
+ /// </summary>
+ [ContractClassFor(typeof(IOpenIdMessageExtension))]
+ internal class IOpenIdMessageExtensionContract : IOpenIdMessageExtension {
+ /// <summary>
+ /// Prevents a default instance of the <see cref="IOpenIdMessageExtensionContract"/> class from being created.
+ /// </summary>
+ private IOpenIdMessageExtensionContract() {
+ }
+
+ #region IOpenIdMessageExtension Members
+
+ /// <summary>
+ /// Gets the TypeURI the extension uses in the OpenID protocol and in XRDS advertisements.
+ /// </summary>
+ string IOpenIdMessageExtension.TypeUri {
+ get {
+ Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Gets the additional TypeURIs that are supported by this extension, in preferred order.
+ /// May be empty if none other than <see cref="IOpenIdMessageExtension.TypeUri"/> is supported, but
+ /// should not be null.
+ /// </summary>
+ /// <remarks>
+ /// Useful for reading in messages with an older version of an extension.
+ /// The value in the <see cref="IOpenIdMessageExtension.TypeUri"/> property is always checked before
+ /// trying this list.
+ /// If you do support multiple versions of an extension using this method,
+ /// consider adding a CreateResponse method to your request extension class
+ /// so that the response can have the context it needs to remain compatible
+ /// given the version of the extension in the request message.
+ /// The <see cref="Extensions.SimpleRegistration.ClaimsRequest.CreateResponse"/> for an example.
+ /// </remarks>
+ IEnumerable<string> IOpenIdMessageExtension.AdditionalSupportedTypeUris {
+ get {
+ Contract.Ensures(Contract.Result<IEnumerable<string>>() != null);
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this extension was
+ /// signed by the sender.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if this instance is signed by the sender; otherwise, <c>false</c>.
+ /// </value>
+ bool IOpenIdMessageExtension.IsSignedByRemoteParty {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ #endregion
+
+ #region IMessage Members
+
+ /// <summary>
+ /// Gets the version of the protocol or extension this message is prepared to implement.
+ /// </summary>
+ /// <remarks>
+ /// Implementations of this interface should ensure that this property never returns null.
+ /// </remarks>
+ Version IMessage.Version {
+ get {
+ Contract.Ensures(Contract.Result<Version>() != null);
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Gets the extra, non-standard Protocol parameters included in the message.
+ /// </summary>
+ /// <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);
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <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/OpenId/OpenIdStrings.Designer.cs b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
index 05daed0..33a16f8 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
+++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
@@ -632,15 +632,6 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
- /// Looks up a localized string similar to No current HttpContext was detected, so an {0} instance must be explicitly provided or specified in the .config file. Call the constructor overload that takes an {0}..
- /// </summary>
- internal static string StoreRequiredWhenNoHttpContextAvailable {
- get {
- return ResourceManager.GetString("StoreRequiredWhenNoHttpContextAvailable", resourceCulture);
- }
- }
-
- /// <summary>
/// Looks up a localized string similar to The type must implement {0}..
/// </summary>
internal static string TypeMustImplementX {
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
index 919d873..c5f506d 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
+++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
@@ -244,9 +244,6 @@ Discovered endpoint info:
<data name="XriResolutionFailed" xml:space="preserve">
<value>XRI resolution failed.</value>
</data>
- <data name="StoreRequiredWhenNoHttpContextAvailable" xml:space="preserve">
- <value>No current HttpContext was detected, so an {0} instance must be explicitly provided or specified in the .config file. Call the constructor overload that takes an {0}.</value>
- </data>
<data name="AttributeAlreadyAdded" xml:space="preserve">
<value>An attribute with type URI '{0}' has already been added.</value>
</data>
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
index 8d6b14a..76b0f10 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
@@ -41,7 +41,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// The name of the key to use in the HttpApplication cache to store the
/// instance of <see cref="StandardRelyingPartyApplicationStore"/> to use.
/// </summary>
- private const string ApplicationStoreKey = "DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.ApplicationStore";
+ private const string ApplicationStoreKey = "DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.HttpApplicationStore";
/// <summary>
/// Backing store for the <see cref="Behaviors"/> property.
@@ -138,7 +138,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
Contract.Ensures(Contract.Result<IRelyingPartyApplicationStore>() != null);
HttpContext context = HttpContext.Current;
- ErrorUtilities.VerifyOperation(context != null, OpenIdStrings.StoreRequiredWhenNoHttpContextAvailable, typeof(IRelyingPartyApplicationStore).Name);
+ ErrorUtilities.VerifyOperation(context != null, Strings.StoreRequiredWhenNoHttpContextAvailable, typeof(IRelyingPartyApplicationStore).Name);
var store = (IRelyingPartyApplicationStore)context.Application[ApplicationStoreKey];
if (store == null) {
context.Application.Lock();
diff --git a/src/DotNetOpenAuth/Strings.Designer.cs b/src/DotNetOpenAuth/Strings.Designer.cs
index 43fec22..38c89f7 100644
--- a/src/DotNetOpenAuth/Strings.Designer.cs
+++ b/src/DotNetOpenAuth/Strings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:2.0.50727.4918
+// Runtime Version:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -70,6 +70,15 @@ namespace DotNetOpenAuth {
}
/// <summary>
+ /// Looks up a localized string similar to No current HttpContext was detected, so an {0} instance must be explicitly provided or specified in the .config file. Call the constructor overload that takes an {0}..
+ /// </summary>
+ internal static string StoreRequiredWhenNoHttpContextAvailable {
+ get {
+ return ResourceManager.GetString("StoreRequiredWhenNoHttpContextAvailable", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to The configuration XAML reference to {0} requires a current HttpContext to resolve..
/// </summary>
internal static string ConfigurationXamlReferenceRequiresHttpContext {
diff --git a/src/DotNetOpenAuth/Strings.resx b/src/DotNetOpenAuth/Strings.resx
index bbfa162..a7f080d 100644
--- a/src/DotNetOpenAuth/Strings.resx
+++ b/src/DotNetOpenAuth/Strings.resx
@@ -120,7 +120,10 @@
<data name="ConfigurationTypeMustBePublic" xml:space="preserve">
<value>The configuration-specified type {0} must be public, and is not.</value>
</data>
+ <data name="StoreRequiredWhenNoHttpContextAvailable" xml:space="preserve">
+ <value>No current HttpContext was detected, so an {0} instance must be explicitly provided or specified in the .config file. Call the constructor overload that takes an {0}.</value>
+ </data>
<data name="ConfigurationXamlReferenceRequiresHttpContext" xml:space="preserve">
<value>The configuration XAML reference to {0} requires a current HttpContext to resolve.</value>
</data>
-</root> \ No newline at end of file
+</root>
diff --git a/src/DotNetOpenAuth/Xrds/TypeElement.cs b/src/DotNetOpenAuth/Xrds/TypeElement.cs
index f6c2217..c413629 100644
--- a/src/DotNetOpenAuth/Xrds/TypeElement.cs
+++ b/src/DotNetOpenAuth/Xrds/TypeElement.cs
@@ -5,6 +5,8 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Xrds {
+ using System;
+ using System.Diagnostics.Contracts;
using System.Xml.XPath;
/// <summary>
@@ -18,6 +20,8 @@ namespace DotNetOpenAuth.Xrds {
/// <param name="parent">The parent.</param>
public TypeElement(XPathNavigator typeElement, ServiceElement parent) :
base(typeElement, parent) {
+ Contract.Requires<ArgumentNullException>(typeElement != null);
+ Contract.Requires<ArgumentNullException>(parent != null);
}
/// <summary>
diff --git a/src/DotNetOpenAuth/Xrds/XrdsNode.cs b/src/DotNetOpenAuth/Xrds/XrdsNode.cs
index 5e7d7e7..f8fa0af 100644
--- a/src/DotNetOpenAuth/Xrds/XrdsNode.cs
+++ b/src/DotNetOpenAuth/Xrds/XrdsNode.cs
@@ -45,6 +45,7 @@ namespace DotNetOpenAuth.Xrds {
/// <param name="document">The document's root node, which this instance represents.</param>
protected XrdsNode(XPathNavigator document) {
Contract.Requires<ArgumentNullException>(document != null);
+ Contract.Requires<ArgumentException>(document.NameTable != null);
this.Node = document;
this.XmlNamespaceResolver = new XmlNamespaceManager(document.NameTable);