diff options
Diffstat (limited to 'src/DotNetOpenAuth')
-rw-r--r-- | src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs | 6 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Messaging/ErrorUtilities.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Messaging/MessageSerializer.cs | 11 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/Identifier.cs | 63 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs | 7 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/Realm.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/UriIdentifier.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/XriIdentifier.cs | 11 | ||||
-rw-r--r-- | src/DotNetOpenAuth/UriUtil.cs | 12 |
12 files changed, 105 insertions, 17 deletions
diff --git a/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs b/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs index b65f92d..56c7389 100644 --- a/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs +++ b/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs @@ -54,7 +54,7 @@ namespace DotNetOpenAuth.Configuration { /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>. /// </returns> protected override object GetElementKey(ConfigurationElement element) { - Contract.Assert(element != null); // this should be Contract.Requires in base class. + Contract.Assume(element != null); // this should be Contract.Requires in base class. return ((AssociationTypeElement)element).AssociationType; } } diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs index b38c882..f535c38 100644 --- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs +++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs @@ -33,7 +33,7 @@ namespace DotNetOpenAuth.Configuration { /// Initializes a new instance of the <see cref="DotNetOpenAuthSection"/> class. /// </summary> internal DotNetOpenAuthSection() { - Contract.Assert(this.SectionInformation != null); + Contract.Assume(this.SectionInformation != null); this.SectionInformation.AllowLocation = false; } diff --git a/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs b/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs index 1c3062f..88a1615 100644 --- a/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs +++ b/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs @@ -38,7 +38,9 @@ namespace DotNetOpenAuth.Configuration { internal IEnumerable<Regex> KeysAsRegexs { get { foreach (HostNameElement element in this) { - yield return new Regex(element.Name); + if (element.Name != null) { + yield return new Regex(element.Name); + } } } } @@ -61,7 +63,7 @@ namespace DotNetOpenAuth.Configuration { /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>. /// </returns> protected override object GetElementKey(ConfigurationElement element) { - Contract.Assert(element != null); // this should be Contract.Requires in base class. + Contract.Assume(element != null); // this should be Contract.Requires in base class. return ((HostNameElement)element).Name; } } diff --git a/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs b/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs index 3cd17f3..eb3c817 100644 --- a/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs +++ b/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs @@ -95,7 +95,7 @@ namespace DotNetOpenAuth.Configuration { settings.MaximumHashBitLength = this.MaximumHashBitLength; settings.ProtectDownlevelReplayAttacks = this.ProtectDownlevelReplayAttacks; foreach (AssociationTypeElement element in this.AssociationLifetimes) { - Contract.Assert(element != null); + Contract.Assume(element != null); settings.AssociationLifetimes.Add(element.AssociationType, element.MaximumLifetime); } return settings; diff --git a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs index 8c001c4..0b9aa17 100644 --- a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs @@ -292,7 +292,7 @@ namespace DotNetOpenAuth.Messaging { /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception> /// <exception cref="ArgumentException">Thrown if <paramref name="value"/> has zero length.</exception> internal static void VerifyNonZeroLength(string value, string paramName) { - Contract.Requires(!string.IsNullOrEmpty(value) || (value != null && value.Length > 0)); + Contract.Requires((value != null && value.Length > 0) || !string.IsNullOrEmpty(value)); VerifyArgumentNotNull(value, paramName); if (value.Length == 0) { throw new ArgumentException(MessagingStrings.UnexpectedEmptyString, paramName); diff --git a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs index 873c7bf..77c4f6b 100644 --- a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs +++ b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs @@ -34,6 +34,7 @@ namespace DotNetOpenAuth.Messaging { private MessageSerializer(Type messageType) { Contract.Requires(messageType != null); Contract.Requires(typeof(IMessage).IsAssignableFrom(messageType)); + Contract.Ensures(this.messageType != null); ErrorUtilities.VerifyArgumentNamed( typeof(IMessage).IsAssignableFrom(messageType), @@ -79,7 +80,7 @@ namespace DotNetOpenAuth.Messaging { foreach (var pair in messageDictionary) { MessagePart partDescription; if (messageDescription.Mapping.TryGetValue(pair.Key, out partDescription)) { - Contract.Assert(partDescription != null); + Contract.Assume(partDescription != null); if (partDescription.IsRequired || partDescription.IsNondefaultValueSet(message)) { result.Add(pair.Key, pair.Value); } @@ -117,5 +118,13 @@ namespace DotNetOpenAuth.Messaging { } message.EnsureValidMessage(); } + + /// <summary> + /// Verifies conditions that should be true for any valid state of this object. + /// </summary> + [ContractInvariantMethod] + protected void ObjectInvariant() { + Contract.Invariant(this.messageType != null); + } } } diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs index d1f09ce..8f3235b 100644 --- a/src/DotNetOpenAuth/OpenId/Identifier.cs +++ b/src/DotNetOpenAuth/OpenId/Identifier.cs @@ -19,6 +19,7 @@ namespace DotNetOpenAuth.OpenId { [Serializable] [ContractVerification(true)] [Pure] + [ContractClass(typeof(IdentifierContract))] public abstract class Identifier { /// <summary> /// Initializes a new instance of the <see cref="Identifier"/> class. @@ -49,6 +50,7 @@ namespace DotNetOpenAuth.OpenId { [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", Justification = "Not all identifiers are URIs.")] [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "Our named alternate is Parse.")] public static implicit operator Identifier(string identifier) { + Contract.Requires(identifier == null || identifier.Length > 0); if (identifier == null) { return null; } @@ -76,6 +78,7 @@ namespace DotNetOpenAuth.OpenId { /// <returns>The result of the conversion.</returns> [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "We have a Parse function.")] public static implicit operator string(Identifier identifier) { + Contract.Ensures((identifier == null && Contract.Result<string>() == null) || (identifier != null && Contract.Result<string>() != null)); if (identifier == null) { return null; } @@ -90,7 +93,7 @@ namespace DotNetOpenAuth.OpenId { /// <returns>An <see cref="Identifier"/> instance for the given value.</returns> [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Some of these identifiers are not properly formatted to be Uris at this stage.")] public static Identifier Parse(string identifier) { - Contract.Requires(!string.IsNullOrEmpty(identifier)); + Contract.Requires((identifier != null && identifier.Length > 0) || !string.IsNullOrEmpty(identifier)); ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier"); if (XriIdentifier.IsValidXri(identifier)) { return new XriIdentifier(identifier); @@ -108,6 +111,7 @@ namespace DotNetOpenAuth.OpenId { /// True if the operation was successful. False if the string was not a valid OpenId Identifier. /// </returns> public static bool TryParse(string value, out Identifier result) { + Contract.Requires(!string.IsNullOrEmpty(value)); if (IsValid(value)) { result = Parse(value); return true; @@ -214,4 +218,61 @@ namespace DotNetOpenAuth.OpenId { /// </returns> internal abstract bool TryRequireSsl(out Identifier secureIdentifier); } + + /// <summary> + /// Code Contract for the <see cref="Identifier"/> class. + /// </summary> + [ContractClassFor(typeof(Identifier))] + internal abstract class IdentifierContract : Identifier { + /// <summary> + /// Initializes a new instance of the <see cref="IdentifierContract"/> class. + /// </summary> + private IdentifierContract() + : base(false) { + } + + /// <summary> + /// Performs discovery on the Identifier. + /// </summary> + /// <param name="requestHandler">The web request handler to use for discovery.</param> + /// <returns> + /// An initialized structure containing the discovered provider endpoint information. + /// </returns> + internal override IEnumerable<ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler) { + Contract.Requires(requestHandler != null); + Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null); + throw new NotImplementedException(); + } + + /// <summary> + /// Returns an <see cref="Identifier"/> that has no URI fragment. + /// Quietly returns the original <see cref="Identifier"/> if it is not + /// a <see cref="UriIdentifier"/> or no fragment exists. + /// </summary> + /// <returns> + /// A new <see cref="Identifier"/> instance if there was a + /// fragment to remove, otherwise this same instance.. + /// </returns> + internal override Identifier TrimFragment() { + Contract.Ensures(Contract.Result<Identifier>() != null); + throw new NotImplementedException(); + } + + /// <summary> + /// Converts a given identifier to its secure equivalent. + /// UriIdentifiers originally created with an implied HTTP scheme change to HTTPS. + /// Discovery is made to require SSL for the entire resolution process. + /// </summary> + /// <param name="secureIdentifier">The newly created secure identifier. + /// If the conversion fails, <paramref name="secureIdentifier"/> retains + /// <i>this</i> identifiers identity, but will never discover any endpoints.</param> + /// <returns> + /// True if the secure conversion was successful. + /// False if the Identifier was originally created with an explicit HTTP scheme. + /// </returns> + internal override bool TryRequireSsl(out Identifier secureIdentifier) { + Contract.Ensures(Contract.ValueAtReturn(out secureIdentifier) != null); + throw new NotImplementedException(); + } + } } diff --git a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs index 8ce377a..cbc8e7d 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs @@ -10,6 +10,7 @@ namespace DotNetOpenAuth.OpenId { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Xrds; + using System.Diagnostics.Contracts; /// <summary> /// Adds OpenID-specific extension methods to the XrdsDocument class. @@ -62,6 +63,9 @@ namespace DotNetOpenAuth.OpenId { /// <param name="userSuppliedIdentifier">The user-supplied i-name that was used to discover this XRDS document.</param> /// <returns>A sequence of OpenID Providers that can assert ownership of the canonical ID given in this document.</returns> internal static IEnumerable<ServiceEndpoint> CreateServiceEndpoints(this XrdsDocument xrds, XriIdentifier userSuppliedIdentifier) { + Contract.Requires(xrds != null); + Contract.Requires(userSuppliedIdentifier != null); + Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null); var endpoints = new List<ServiceEndpoint>(); endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); @@ -82,6 +86,9 @@ namespace DotNetOpenAuth.OpenId { /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user.</param> /// <returns>A sequence of the providers that can offer directed identity services.</returns> private static IEnumerable<ServiceEndpoint> GenerateOPIdentifierServiceEndpoints(this XrdsDocument xrds, Identifier opIdentifier) { + Contract.Requires(xrds != null); + Contract.Requires(opIdentifier != null); + Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null); return from service in xrds.FindOPIdentifierServices() from uri in service.UriElements let protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris) diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs index 83a2189..dbbfd43 100644 --- a/src/DotNetOpenAuth/OpenId/Realm.cs +++ b/src/DotNetOpenAuth/OpenId/Realm.cs @@ -382,7 +382,7 @@ namespace DotNetOpenAuth.OpenId { /// Verifies conditions that should be true for any valid state of this object. /// </summary> [ContractInvariantMethod] - protected void ObjectInvariant() { + private void ObjectInvariant() { Contract.Invariant(this.uri != null); Contract.Invariant(this.uri.AbsoluteUri != null); } diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs index 6f5ff7c..41d5831 100644 --- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs @@ -312,7 +312,7 @@ namespace DotNetOpenAuth.OpenId { /// Verifies conditions that should be true for any valid state of this object. /// </summary> [ContractInvariantMethod] - protected void ObjectInvariant() { + private void ObjectInvariant() { Contract.Invariant(this.Uri != null); Contract.Invariant(this.Uri.AbsoluteUri != null); } diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs index 20fa1d5..a978ae9 100644 --- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs @@ -60,6 +60,7 @@ namespace DotNetOpenAuth.OpenId { /// <param name="xri">The string value of the XRI.</param> internal XriIdentifier(string xri) : this(xri, false) { + Contract.Requires((xri != null && xri.Length > 0) || !string.IsNullOrEmpty(xri)); } /// <summary> @@ -72,7 +73,7 @@ namespace DotNetOpenAuth.OpenId { /// </param> internal XriIdentifier(string xri, bool requireSsl) : base(requireSsl) { - Contract.Requires(!string.IsNullOrEmpty(xri)); + Contract.Requires((xri != null && xri.Length > 0) || !string.IsNullOrEmpty(xri)); ErrorUtilities.VerifyFormat(IsValidXri(xri), OpenIdStrings.InvalidXri, xri); Contract.Assume(xri != null); // Proven by IsValidXri this.xriResolverProxy = XriResolverProxyTemplate; @@ -153,7 +154,7 @@ namespace DotNetOpenAuth.OpenId { /// <c>true</c> if the given string constitutes a valid XRI; otherwise, <c>false</c>. /// </returns> internal static bool IsValidXri(string xri) { - Contract.Requires(!string.IsNullOrEmpty(xri)); + Contract.Requires((xri != null && xri.Length > 0) || !string.IsNullOrEmpty(xri)); ErrorUtilities.VerifyNonZeroLength(xri, "xri"); xri = xri.Trim(); @@ -182,6 +183,8 @@ namespace DotNetOpenAuth.OpenId { /// <param name="userSuppliedIdentifier">The user supplied identifier, which may differ from this XRI instance due to multiple discovery steps.</param> /// <returns>A list of service endpoints offered for this identifier.</returns> internal IEnumerable<ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler, XriIdentifier userSuppliedIdentifier) { + Contract.Requires(requestHandler != null); + Contract.Requires(userSuppliedIdentifier != null); return this.DownloadXrds(requestHandler).CreateServiceEndpoints(userSuppliedIdentifier); } @@ -223,7 +226,7 @@ namespace DotNetOpenAuth.OpenId { /// Verifies conditions that should be true for any valid state of this object. /// </summary> [ContractInvariantMethod] - protected void ObjectInvariant() { + private void ObjectInvariant() { Contract.Invariant(this.xriResolverProxy != null); Contract.Invariant(this.canonicalXri != null); } @@ -251,6 +254,8 @@ namespace DotNetOpenAuth.OpenId { /// <param name="requestHandler">The request handler.</param> /// <returns>The XRDS document.</returns> private XrdsDocument DownloadXrds(IDirectWebRequestHandler requestHandler) { + Contract.Requires(requestHandler != null); + Contract.Ensures(Contract.Result<XrdsDocument>() != null); XrdsDocument doc; using (var xrdsResponse = Yadis.Request(requestHandler, this.XrdsUrl, this.IsDiscoverySecureEndToEnd)) { doc = new XrdsDocument(XmlReader.Create(xrdsResponse.ResponseStream)); diff --git a/src/DotNetOpenAuth/UriUtil.cs b/src/DotNetOpenAuth/UriUtil.cs index 4790ec6..d04491d 100644 --- a/src/DotNetOpenAuth/UriUtil.cs +++ b/src/DotNetOpenAuth/UriUtil.cs @@ -28,15 +28,16 @@ namespace DotNetOpenAuth { /// <returns> /// True if the URI contains an OAuth message. /// </returns> + [ContractVerification(false)] // bugs/limitations in CC static analysis internal static bool QueryStringContainPrefixedParameters(this Uri uri, string prefix) { - Contract.Requires(!string.IsNullOrEmpty(prefix)); + Contract.Requires(prefix != null && prefix.Length > 0); ErrorUtilities.VerifyNonZeroLength(prefix, "prefix"); if (uri == null) { return false; } NameValueCollection nvc = HttpUtility.ParseQueryString(uri.Query); - Contract.Assert(nvc != null); // BCL + Contract.Assume(nvc != null); // BCL return nvc.Keys.OfType<string>().Any(key => key.StartsWith(prefix, StringComparison.Ordinal)); } @@ -99,10 +100,13 @@ namespace DotNetOpenAuth { } if (page != null && !designMode) { - Contract.Assert(page.Request != null); + Contract.Assume(page.Request != null); // Validate new value by trying to construct a Realm object based on it. - new Uri(page.Request.Url, page.ResolveUrl(value)); // throws an exception on failure. + string relativeUrl = page.ResolveUrl(value); + Contract.Assume(page.Request.Url != null); + Contract.Assume(relativeUrl != null); + new Uri(page.Request.Url, relativeUrl); // throws an exception on failure. } else { // We can't fully test it, but it should start with either ~/ or a protocol. if (Regex.IsMatch(value, @"^https?://")) { |