diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2011-05-28 08:46:07 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2011-05-28 08:51:19 -0700 |
commit | 049482bbc34e9ffabe3a735e7a00f5f3c5fbab10 (patch) | |
tree | edef69cfb18ccf7bf0fbe2429c918b66f4b3ff5b | |
parent | 6cab4fb3502bad297f221f25cb5c3cc232d700f0 (diff) | |
download | DotNetOpenAuth-049482bbc34e9ffabe3a735e7a00f5f3c5fbab10.zip DotNetOpenAuth-049482bbc34e9ffabe3a735e7a00f5f3c5fbab10.tar.gz DotNetOpenAuth-049482bbc34e9ffabe3a735e7a00f5f3c5fbab10.tar.bz2 |
FxCop fixes.
63 files changed, 690 insertions, 541 deletions
diff --git a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs index f0608d5..69757be 100644 --- a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs @@ -98,7 +98,7 @@ namespace RelyingPartyLogic { // NEVER issue an auto-approval to a client that would end up getting an access token immediately // (without a client secret), as that would allow ANY client to spoof an approved client's identity // and obtain unauthorized access to user data. - if (authorizationRequest.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) { + if (EndUserAuthorizationRequest.ResponseType == EndUserAuthorizationResponseTypes.AuthorizationCode) { // Never issue auto-approval if the client secret is blank, since that too makes it easy to spoof // a client's identity and obtain unauthorized access. var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == authorizationRequest.ClientIdentifier); diff --git a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs index e2e4325..d2583a2 100644 --- a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs +++ b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs @@ -53,7 +53,7 @@ // NEVER issue an auto-approval to a client that would end up getting an access token immediately // (without a client secret), as that would allow ANY client to spoof an approved client's identity // and obtain unauthorized access to user data. - if (authorizationRequest.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) { + if (EndUserAuthorizationRequest.ResponseType == EndUserAuthorizationResponseTypes.AuthorizationCode) { // Never issue auto-approval if the client secret is blank, since that too makes it easy to spoof // a client's identity and obtain unauthorized access. var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == authorizationRequest.ClientIdentifier); diff --git a/samples/OAuthClient/SampleWcf2.aspx.cs b/samples/OAuthClient/SampleWcf2.aspx.cs index 058ba47..78b46bc 100644 --- a/samples/OAuthClient/SampleWcf2.aspx.cs +++ b/samples/OAuthClient/SampleWcf2.aspx.cs @@ -1,137 +1,137 @@ -namespace OAuthClient { - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - using System.Net; - using System.ServiceModel; - using System.ServiceModel.Channels; - using System.ServiceModel.Security; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using DotNetOpenAuth.OAuth2; - - using SampleResourceServer; - - public partial class SampleWcf2 : System.Web.UI.Page { - /// <summary> - /// The OAuth 2.0 client object to use to obtain authorization and authorize outgoing HTTP requests. - /// </summary> - private static readonly WebServerClient Client; - - /// <summary> - /// The details about the sample OAuth-enabled WCF service that this sample client calls into. - /// </summary> - private static AuthorizationServerDescription authServerDescription = new AuthorizationServerDescription { - TokenEndpoint = new Uri("http://localhost:50172/OAuth/Token"), - AuthorizationEndpoint = new Uri("http://localhost:50172/OAuth/Authorize"), - }; - - /// <summary> - /// Initializes static members of the <see cref="SampleWcf2"/> class. - /// </summary> - static SampleWcf2() { - Client = new WebServerClient(authServerDescription, "sampleconsumer", "samplesecret"); - } - - /// <summary> - /// Gets or sets the authorization details for the logged in user. - /// </summary> - /// <value>The authorization details.</value> - /// <remarks> - /// Because this is a sample, we simply store the authorization information in memory with the user session. - /// A real web app should store at least the access and refresh tokens in this object in a database associated with the user. - /// </remarks> - private static IAuthorizationState Authorization { - get { return (AuthorizationState)HttpContext.Current.Session["Authorization"]; } - set { HttpContext.Current.Session["Authorization"] = value; } - } - - protected void Page_Load(object sender, EventArgs e) { - if (!IsPostBack) { - // Check to see if we're receiving a end user authorization response. - var authorization = Client.ProcessUserAuthorization(); - if (authorization != null) { - // We are receiving an authorization response. Store it and associate it with this user. - Authorization = authorization; - Response.Redirect(Request.Path); // get rid of the /?code= parameter - } - } - - if (Authorization != null) { - // Indicate to the user that we have already obtained authorization on some of these. - foreach (var li in this.scopeList.Items.OfType<ListItem>().Where(li => Authorization.Scope.Contains(li.Value))) { - li.Selected = true; - } - this.authorizationLabel.Text = "Authorization received!"; - if (Authorization.AccessTokenExpirationUtc.HasValue) { +namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+ using System.Net;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.OAuth2;
+
+ using SampleResourceServer;
+
+ public partial class SampleWcf2 : System.Web.UI.Page {
+ /// <summary>
+ /// The OAuth 2.0 client object to use to obtain authorization and authorize outgoing HTTP requests.
+ /// </summary>
+ private static readonly WebServerClient Client;
+
+ /// <summary>
+ /// The details about the sample OAuth-enabled WCF service that this sample client calls into.
+ /// </summary>
+ private static AuthorizationServerDescription authServerDescription = new AuthorizationServerDescription {
+ TokenEndpoint = new Uri("http://localhost:50172/OAuth/Token"),
+ AuthorizationEndpoint = new Uri("http://localhost:50172/OAuth/Authorize"),
+ };
+
+ /// <summary>
+ /// Initializes static members of the <see cref="SampleWcf2"/> class.
+ /// </summary>
+ static SampleWcf2() {
+ Client = new WebServerClient(authServerDescription, "sampleconsumer", "samplesecret");
+ }
+
+ /// <summary>
+ /// Gets or sets the authorization details for the logged in user.
+ /// </summary>
+ /// <value>The authorization details.</value>
+ /// <remarks>
+ /// Because this is a sample, we simply store the authorization information in memory with the user session.
+ /// A real web app should store at least the access and refresh tokens in this object in a database associated with the user.
+ /// </remarks>
+ private static IAuthorizationState Authorization {
+ get { return (AuthorizationState)HttpContext.Current.Session["Authorization"]; }
+ set { HttpContext.Current.Session["Authorization"] = value; }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!IsPostBack) {
+ // Check to see if we're receiving a end user authorization response.
+ var authorization = Client.ProcessUserAuthorization();
+ if (authorization != null) {
+ // We are receiving an authorization response. Store it and associate it with this user.
+ Authorization = authorization;
+ Response.Redirect(Request.Path); // get rid of the /?code= parameter
+ }
+ }
+
+ if (Authorization != null) {
+ // Indicate to the user that we have already obtained authorization on some of these.
+ foreach (var li in this.scopeList.Items.OfType<ListItem>().Where(li => Authorization.Scope.Contains(li.Value))) {
+ li.Selected = true;
+ }
+ this.authorizationLabel.Text = "Authorization received!";
+ if (Authorization.AccessTokenExpirationUtc.HasValue) {
TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
- this.authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " (access token expires in {0} minutes)", Math.Round(timeLeft.TotalMinutes, 1)); - } - } - - this.getNameButton.Enabled = this.getAgeButton.Enabled = this.getFavoriteSites.Enabled = Authorization != null; - } - - protected void getAuthorizationButton_Click(object sender, EventArgs e) { - string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>() - where item.Selected - select item.Value).ToArray(); - - Client.RequestUserAuthorization(scopes); - } - - protected void getNameButton_Click(object sender, EventArgs e) { - try { - this.nameLabel.Text = CallService(client => client.GetName()); - } catch (SecurityAccessDeniedException) { - this.nameLabel.Text = "Access denied!"; - } - } - - protected void getAgeButton_Click(object sender, EventArgs e) { - try { - int? age = CallService(client => client.GetAge()); - this.ageLabel.Text = age.HasValue ? age.Value.ToString(CultureInfo.CurrentCulture) : "not available"; - } catch (SecurityAccessDeniedException) { - this.ageLabel.Text = "Access denied!"; - } - } - - protected void getFavoriteSites_Click(object sender, EventArgs e) { - try { - string[] favoriteSites = CallService(client => client.GetFavoriteSites()); - this.favoriteSitesLabel.Text = string.Join(", ", favoriteSites); - } catch (SecurityAccessDeniedException) { - this.favoriteSitesLabel.Text = "Access denied!"; - } - } - - private T CallService<T>(Func<DataApiClient, T> predicate) { - if (Authorization == null) { - throw new InvalidOperationException("No access token!"); - } - - var wcfClient = new DataApiClient(); - - // Refresh the access token if it expires and if its lifetime is too short to be of use. - if (Authorization.AccessTokenExpirationUtc.HasValue) { - if (Client.RefreshToken(Authorization, TimeSpan.FromSeconds(30))) { + this.authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " (access token expires in {0} minutes)", Math.Round(timeLeft.TotalMinutes, 1));
+ }
+ }
+
+ this.getNameButton.Enabled = this.getAgeButton.Enabled = this.getFavoriteSites.Enabled = Authorization != null;
+ }
+
+ protected void getAuthorizationButton_Click(object sender, EventArgs e) {
+ string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
+ where item.Selected
+ select item.Value).ToArray();
+
+ Client.RequestUserAuthorization(scopes);
+ }
+
+ protected void getNameButton_Click(object sender, EventArgs e) {
+ try {
+ this.nameLabel.Text = CallService(client => client.GetName());
+ } catch (SecurityAccessDeniedException) {
+ this.nameLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getAgeButton_Click(object sender, EventArgs e) {
+ try {
+ int? age = CallService(client => client.GetAge());
+ this.ageLabel.Text = age.HasValue ? age.Value.ToString(CultureInfo.CurrentCulture) : "not available";
+ } catch (SecurityAccessDeniedException) {
+ this.ageLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getFavoriteSites_Click(object sender, EventArgs e) {
+ try {
+ string[] favoriteSites = CallService(client => client.GetFavoriteSites());
+ this.favoriteSitesLabel.Text = string.Join(", ", favoriteSites);
+ } catch (SecurityAccessDeniedException) {
+ this.favoriteSitesLabel.Text = "Access denied!";
+ }
+ }
+
+ private T CallService<T>(Func<DataApiClient, T> predicate) {
+ if (Authorization == null) {
+ throw new InvalidOperationException("No access token!");
+ }
+
+ var wcfClient = new DataApiClient();
+
+ // Refresh the access token if it expires and if its lifetime is too short to be of use.
+ if (Authorization.AccessTokenExpirationUtc.HasValue) {
+ if (Client.RefreshToken(Authorization, TimeSpan.FromSeconds(30))) {
TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
- this.authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " - just renewed for {0} more minutes)", Math.Round(timeLeft.TotalMinutes, 1)); - } - } - - var httpRequest = (HttpWebRequest)WebRequest.Create(wcfClient.Endpoint.Address.Uri); - Client.AuthorizeRequest(httpRequest, Authorization.AccessToken); - - var httpDetails = new HttpRequestMessageProperty(); - httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization]; - using (var scope = new OperationContextScope(wcfClient.InnerChannel)) { - OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails; - return predicate(wcfClient); - } - } - } + this.authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " - just renewed for {0} more minutes)", Math.Round(timeLeft.TotalMinutes, 1));
+ }
+ }
+
+ var httpRequest = (HttpWebRequest)WebRequest.Create(wcfClient.Endpoint.Address.Uri);
+ ClientBase.AuthorizeRequest(httpRequest, Authorization.AccessToken);
+
+ var httpDetails = new HttpRequestMessageProperty();
+ httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization];
+ using (var scope = new OperationContextScope(wcfClient.InnerChannel)) {
+ OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails;
+ return predicate(wcfClient);
+ }
+ }
+ }
}
\ No newline at end of file diff --git a/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs index d07cf32..07743e1 100644 --- a/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs +++ b/src/DotNetOpenAuth.Test/Messaging/MessageSerializerTests.cs @@ -65,7 +65,7 @@ namespace DotNetOpenAuth.Test.Messaging { var ms = new MemoryStream(); var writer = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.UTF8); - serializer.Serialize(this.MessageDescriptions.GetAccessor(message), writer); + MessageSerializer.Serialize(this.MessageDescriptions.GetAccessor(message), writer); writer.Flush(); string actual = Encoding.UTF8.GetString(ms.ToArray()); @@ -75,7 +75,7 @@ namespace DotNetOpenAuth.Test.Messaging { ms.Position = 0; var deserialized = new Mocks.TestDirectedMessage(); var reader = JsonReaderWriterFactory.CreateJsonReader(ms, XmlDictionaryReaderQuotas.Max); - serializer.Deserialize(this.MessageDescriptions.GetAccessor(deserialized), reader); + MessageSerializer.Deserialize(this.MessageDescriptions.GetAccessor(deserialized), reader); Assert.AreEqual(message.Age, deserialized.Age); Assert.AreEqual(message.EmptyMember, deserialized.EmptyMember); Assert.AreEqual(message.Location, deserialized.Location); @@ -86,7 +86,7 @@ namespace DotNetOpenAuth.Test.Messaging { [TestCase, ExpectedException(typeof(ArgumentNullException))] public void DeserializeNull() { var serializer = MessageSerializer.Get(typeof(Mocks.TestMessage)); - serializer.Deserialize(null, null); + MessageSerializer.Deserialize(null, null); } [TestCase] diff --git a/src/DotNetOpenAuth/CodeAnalysisDictionary.xml b/src/DotNetOpenAuth/CodeAnalysisDictionary.xml new file mode 100644 index 0000000..8c90df3 --- /dev/null +++ b/src/DotNetOpenAuth/CodeAnalysisDictionary.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8" ?> +<Dictionary> + <Words> + <!-- + This is a list of case-insensitive words that exist in the dictionary + but you do not want to be recognized by IdentifiersShouldBeSpelledCorrectly. + Do not add deprecated terms to this list, instead add these to the + <Deprecated> section below. + --> + <Unrecognized> + <!--<Word>cb</Word>--> + </Unrecognized> + <!-- + This is a list of case-insensitive words that do not exist in the dictionary + but you still want to be considered as recognized by + IdentifiersShouldBeSpelledCorrectly. Do not add compound words (e.g. 'FileName') + to this list as this will cause CompoundWordsShouldBeBeCasedCorrectly to fire on + usages of the compound word stating that they should be changed to their discrete equivalent + (for example 'FileName' -> 'Filename'). + --> + <Recognized> + <Word>OAuth</Word> + <!--<Word>cryptoKeyStore</Word> + <Word>containingMessage</Word> + <Word>httpRequestInfo</Word> + <Word>faultedMessage</Word> + <Word>keyStore</Word> + <Word>authorizationServer</Word> + <Word>bytesToSign</Word> + <Word>clientCallback</Word>--> + </Recognized> + <Deprecated> + <!-- + This is a list of deprecated terms with their preferred alternates and is + used by UsePreferredTerms. The deprecated terms are case-insensitive, + however, make sure to pascal-case the preferred alternates. If a word + does not have a preferred alternate, simply leave it blank. + --> + <!--<Term PreferredAlternate="EnterpriseServices">complus</Term>--> + </Deprecated> + <Compound> + <!-- + This is a list of discrete terms with their compound alternates and is used by + CompoundWordsShouldBeCasedCorrectly. These are words that exist in the + dictionary as discrete terms, however, should actually be cased as compound words. + For example, 'Filename' exists in the dictionary and hence the spelling rules will + not see it as unrecognized but its actual preferred usage is 'FileName'; adding it + below causes CompoundWordsShouldBeCasedCorrectly to fire. The discrete terms are + case-insensitive, however, be sure to pascal-case the compound alternates. + Any discrete terms added below automatically get added to the list of discrete + exceptions to prevent CompoundWordsShouldBeCasedCorrectly from firing both on the + compound word (for example 'WhiteSpace') and its discrete alternate (for example + 'Whitespace'). + --> + <Term CompoundAlternate="OAuth">oauth</Term> + <!--<Term CompoundAlternate="DataBind">databind</Term>--> + </Compound> + <DiscreteExceptions> + <!-- + This is a list of case-insensitive exceptions to the CompoundWordsShouldBeCasedCorrectly + discrete term check. As this check works solely on the basis of whether two consecutive + tokens exists in the dictionary, it can have a high false positive rate. For example, + 'onset' exists in the dictionary but the user probably intended it to be 'OnSet'. + Adding this word below prevents this rule from firing telling the user to change 'OnSet' + to 'Onset'. + --> + <Term>oauth</Term> + <!--<Term>onset</Term>--> + </DiscreteExceptions> + </Words> +</Dictionary>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 41d2f2e..0c3d87f 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -860,6 +860,7 @@ http://opensource.org/licenses/ms-pl.html <ProductName>Windows Installer 3.1</ProductName> <Install>true</Install> </BootstrapperPackage> + <CodeAnalysisDictionary Include="CodeAnalysisDictionary.xml" /> <Content Include="DotNetOpenAuth.ico" /> </ItemGroup> <ItemGroup> diff --git a/src/DotNetOpenAuth/GlobalSuppressions.cs b/src/DotNetOpenAuth/GlobalSuppressions.cs index 8539422..2bc6c04 100644 --- a/src/DotNetOpenAuth/GlobalSuppressions.cs +++ b/src/DotNetOpenAuth/GlobalSuppressions.cs @@ -67,3 +67,4 @@ using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "iframe", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] [assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "Sig", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] [assembly: SuppressMessage("Microsoft.Naming", "CA1701:ResourceStringCompoundWordsShouldBeCasedCorrectly", MessageId = "DSig", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OAuth2.ChannelElements")] diff --git a/src/DotNetOpenAuth/Messaging/BinaryDataBagFormatter.cs b/src/DotNetOpenAuth/Messaging/BinaryDataBagFormatter.cs index bfae707..591adc3 100644 --- a/src/DotNetOpenAuth/Messaging/BinaryDataBagFormatter.cs +++ b/src/DotNetOpenAuth/Messaging/BinaryDataBagFormatter.cs @@ -44,7 +44,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="decodeOnceOnly">The nonce store to use to ensure that this instance is only decoded once.</param> protected internal BinaryDataBagFormatter(ICryptoKeyStore cryptoKeyStore = null, string bucket = null, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? minimumAge = null, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) : base(cryptoKeyStore, bucket, signed, encrypted, compressed, minimumAge, maximumAge, decodeOnceOnly) { - Contract.Requires<ArgumentException>((cryptoKeyStore != null && bucket != null) || (!signed && !encrypted), "A secret is required when signing or encrypting is required."); + Contract.Requires<ArgumentException>((cryptoKeyStore != null && bucket != null) || (!signed && !encrypted)); } /// <summary> @@ -53,9 +53,10 @@ namespace DotNetOpenAuth.Messaging { /// <param name="message">The message.</param> /// <returns>The buffer containing the serialized data.</returns> protected override byte[] SerializeCore(T message) { - var stream = new MemoryStream(); - message.Serialize(stream); - return stream.ToArray(); + using (var stream = new MemoryStream()) { + message.Serialize(stream); + return stream.ToArray(); + } } /// <summary> @@ -64,8 +65,9 @@ namespace DotNetOpenAuth.Messaging { /// <param name="message">The message instance to initialize with data from the buffer.</param> /// <param name="data">The data buffer.</param> protected override void DeserializeCore(T message, byte[] data) { - var stream = new MemoryStream(data); - message.Deserialize(stream); + using (var stream = new MemoryStream(data)) { + message.Deserialize(stream); + } // Perform basic validation on message that the MessageSerializer would have normally performed. var messageDescription = MessageDescriptions.Get(message); diff --git a/src/DotNetOpenAuth/Messaging/Bindings/AsymmetricCryptoKeyStoreWrapper.cs b/src/DotNetOpenAuth/Messaging/Bindings/AsymmetricCryptoKeyStoreWrapper.cs index 20010f4..0f2ac05 100644 --- a/src/DotNetOpenAuth/Messaging/Bindings/AsymmetricCryptoKeyStoreWrapper.cs +++ b/src/DotNetOpenAuth/Messaging/Bindings/AsymmetricCryptoKeyStoreWrapper.cs @@ -40,8 +40,8 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// <param name="dataStore">The data store.</param> /// <param name="asymmetricCrypto">The asymmetric protection to apply to symmetric keys. Must include the private key.</param> public AsymmetricCryptoKeyStoreWrapper(ICryptoKeyStore dataStore, RSACryptoServiceProvider asymmetricCrypto) { - Contract.Requires<ArgumentNullException>(dataStore != null, "dataStore"); - Contract.Requires<ArgumentNullException>(asymmetricCrypto != null, "asymmetricCrypto"); + Contract.Requires<ArgumentNullException>(dataStore != null); + Contract.Requires<ArgumentNullException>(asymmetricCrypto != null); Contract.Requires<ArgumentException>(!asymmetricCrypto.PublicOnly); this.dataStore = dataStore; this.asymmetricCrypto = asymmetricCrypto; @@ -78,6 +78,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// <param name="bucket">The name of the bucket to store the key in. Case sensitive.</param> /// <param name="handle">The handle to the key, unique within the bucket. Case sensitive.</param> /// <param name="decryptedCryptoKey">The key to store.</param> + [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "2#", Justification = "Helps readability because multiple keys are involved.")] public void StoreKey(string bucket, string handle, CryptoKey decryptedCryptoKey) { byte[] encryptedKey = this.asymmetricCrypto.Encrypt(decryptedCryptoKey.Key, true); var encryptedCryptoKey = new CryptoKey(encryptedKey, decryptedCryptoKey.ExpiresUtc); @@ -105,6 +106,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// <returns> /// The decrypted key. /// </returns> + [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "2#", Justification = "Helps readability because multiple keys are involved.")] private CryptoKey Decrypt(string bucket, string handle, CryptoKey encryptedCryptoKey) { if (encryptedCryptoKey == null) { return null; diff --git a/src/DotNetOpenAuth/Messaging/Bindings/CryptoKey.cs b/src/DotNetOpenAuth/Messaging/Bindings/CryptoKey.cs index bfb4518..cd10199 100644 --- a/src/DotNetOpenAuth/Messaging/Bindings/CryptoKey.cs +++ b/src/DotNetOpenAuth/Messaging/Bindings/CryptoKey.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Linq; using System.Text; @@ -32,7 +33,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// <param name="key">The cryptographic key.</param> /// <param name="expiresUtc">The expires UTC.</param> public CryptoKey(byte[] key, DateTime expiresUtc) { - Contract.Requires<ArgumentNullException>(key != null, "key"); + Contract.Requires<ArgumentNullException>(key != null); Contract.Requires<ArgumentException>(expiresUtc.Kind == DateTimeKind.Utc); this.key = key; this.expiresUtc = expiresUtc; @@ -41,6 +42,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// <summary> /// Gets the key. /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "It's a buffer")] public byte[] Key { get { Contract.Ensures(Contract.Result<byte[]>() != null); diff --git a/src/DotNetOpenAuth/Messaging/Bindings/CryptoKeyCollisionException.cs b/src/DotNetOpenAuth/Messaging/Bindings/CryptoKeyCollisionException.cs index e7dbf46..11634ac 100644 --- a/src/DotNetOpenAuth/Messaging/Bindings/CryptoKeyCollisionException.cs +++ b/src/DotNetOpenAuth/Messaging/Bindings/CryptoKeyCollisionException.cs @@ -6,12 +6,14 @@ namespace DotNetOpenAuth.Messaging.Bindings { using System; + using System.Diagnostics.CodeAnalysis; using System.Security.Permissions; /// <summary> /// Thrown by a hosting application or web site when a cryptographic key is created with a /// bucket and handle that conflicts with a previously stored and unexpired key. /// </summary> + [SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "Specialized exception has no need of a message parameter.")] [Serializable] public class CryptoKeyCollisionException : ArgumentException { /// <summary> @@ -23,16 +25,8 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// <summary> /// Initializes a new instance of the <see cref="CryptoKeyCollisionException"/> class. /// </summary> - /// <param name="message">A message describing the specific error the occurred or was detected.</param> - public CryptoKeyCollisionException(string message) : base(message) { - } - - /// <summary> - /// Initializes a new instance of the <see cref="CryptoKeyCollisionException"/> class. - /// </summary> - /// <param name="message">A message describing the specific error the occurred or was detected.</param> /// <param name="inner">The inner exception to include.</param> - public CryptoKeyCollisionException(string message, Exception inner) : base(message, inner) { + public CryptoKeyCollisionException(Exception inner) : base(null, inner) { } /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/Bindings/ExpiredMessageException.cs b/src/DotNetOpenAuth/Messaging/Bindings/ExpiredMessageException.cs index 31b053e..cfe7f6c 100644 --- a/src/DotNetOpenAuth/Messaging/Bindings/ExpiredMessageException.cs +++ b/src/DotNetOpenAuth/Messaging/Bindings/ExpiredMessageException.cs @@ -22,7 +22,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { public ExpiredMessageException(DateTime utcExpirationDate, IProtocolMessage faultedMessage) : base(string.Format(CultureInfo.CurrentCulture, MessagingStrings.ExpiredMessage, utcExpirationDate.ToLocalTime(), DateTime.Now), faultedMessage) { Contract.Requires<ArgumentException>(utcExpirationDate.Kind == DateTimeKind.Utc); - Contract.Requires<ArgumentNullException>(faultedMessage != null, "faultedMessage"); + Contract.Requires<ArgumentNullException>(faultedMessage != null); } /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/Bindings/ICryptoKeyStore.cs b/src/DotNetOpenAuth/Messaging/Bindings/ICryptoKeyStore.cs index 28d76a3..815c488 100644 --- a/src/DotNetOpenAuth/Messaging/Bindings/ICryptoKeyStore.cs +++ b/src/DotNetOpenAuth/Messaging/Bindings/ICryptoKeyStore.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Linq; using System.Text; @@ -37,6 +38,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { /// </summary> /// <param name="bucket">The bucket name. Case sensitive.</param> /// <returns>A sequence of handles and keys, ordered by descending <see cref="CryptoKey.ExpiresUtc"/>.</returns> + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Important for scalability")] IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket); /// <summary> @@ -98,7 +100,7 @@ namespace DotNetOpenAuth.Messaging.Bindings { void ICryptoKeyStore.StoreKey(string bucket, string handle, CryptoKey key) { Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(bucket)); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle)); - Contract.Requires<ArgumentNullException>(key != null, "key"); + Contract.Requires<ArgumentNullException>(key != null); throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth/Messaging/Channel.cs b/src/DotNetOpenAuth/Messaging/Channel.cs index 84d080c..ded5662 100644 --- a/src/DotNetOpenAuth/Messaging/Channel.cs +++ b/src/DotNetOpenAuth/Messaging/Channel.cs @@ -55,6 +55,7 @@ namespace DotNetOpenAuth.Messaging { /// <summary> /// The content-type for plain text. /// </summary> + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "PlainText", Justification = "Not 'Plaintext' in the crypographic sense.")] protected internal const string PlainTextEncoded = "text/plain"; /// <summary> @@ -768,7 +769,7 @@ namespace DotNetOpenAuth.Messaging { protected virtual OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) { Contract.Requires<ArgumentNullException>(message != null); Contract.Requires<ArgumentException>(message.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient); - Contract.Requires<ArgumentException>((message.HttpMethods & (HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.PostRequest)) != 0, "Neither GET nor POST are allowed for this message."); + Contract.Requires<ArgumentException>((message.HttpMethods & (HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.PostRequest)) != 0); Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null); Contract.Assert(message != null && message.Recipient != null); @@ -923,18 +924,20 @@ namespace DotNetOpenAuth.Messaging { /// </summary> /// <param name="message">The message to serialize.</param> /// <returns>A JSON string.</returns> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "This Dispose is safe.")] protected virtual string SerializeAsJson(IMessage message) { - Contract.Requires<ArgumentNullException>(message != null, "message"); + Contract.Requires<ArgumentNullException>(message != null); MessageDictionary messageDictionary = this.MessageDescriptions.GetAccessor(message); - var memoryStream = new MemoryStream(); - var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(memoryStream, Encoding.UTF8); - var serializer = MessageSerializer.Get(message.GetType()); - serializer.Serialize(messageDictionary, jsonWriter); - jsonWriter.Flush(); - - string json = Encoding.UTF8.GetString(memoryStream.ToArray()); - return json; + using (var memoryStream = new MemoryStream()) { + using (var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(memoryStream, Encoding.UTF8)) { + MessageSerializer.Serialize(messageDictionary, jsonWriter); + jsonWriter.Flush(); + } + + string json = Encoding.UTF8.GetString(memoryStream.ToArray()); + return json; + } } /// <summary> @@ -946,8 +949,9 @@ namespace DotNetOpenAuth.Messaging { Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(json)); var dictionary = new Dictionary<string, string>(); - var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), this.XmlDictionaryReaderQuotas); - MessageSerializer.DeserializeJsonAsFlatDictionary(dictionary, jsonReader); + using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), this.XmlDictionaryReaderQuotas)) { + MessageSerializer.DeserializeJsonAsFlatDictionary(dictionary, jsonReader); + } return dictionary; } diff --git a/src/DotNetOpenAuth/Messaging/DataBag.cs b/src/DotNetOpenAuth/Messaging/DataBag.cs index f9c60c2..17a7bda 100644 --- a/src/DotNetOpenAuth/Messaging/DataBag.cs +++ b/src/DotNetOpenAuth/Messaging/DataBag.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.Messaging { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; /// <summary> @@ -102,6 +103,7 @@ namespace DotNetOpenAuth.Messaging { /// <remarks> /// This ensures that one token cannot be misused as another kind of token. /// </remarks> + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Accessed by reflection")] [MessagePart("t", IsRequired = true, AllowEmpty = false)] private Type BagType { get { return this.GetType(); } diff --git a/src/DotNetOpenAuth/Messaging/DataBagFormatterBase.cs b/src/DotNetOpenAuth/Messaging/DataBagFormatterBase.cs index 3b6dcd7..9cb63e6 100644 --- a/src/DotNetOpenAuth/Messaging/DataBagFormatterBase.cs +++ b/src/DotNetOpenAuth/Messaging/DataBagFormatterBase.cs @@ -58,11 +58,6 @@ namespace DotNetOpenAuth.Messaging { private readonly RSACryptoServiceProvider asymmetricEncrypting; /// <summary> - /// The hashing algorithm to use for asymmetric signatures. - /// </summary> - private readonly HashAlgorithm hasherForAsymmetricSigning; - - /// <summary> /// A value indicating whether the data in this instance will be protected against tampering. /// </summary> private readonly bool signed; @@ -99,7 +94,6 @@ namespace DotNetOpenAuth.Messaging { : this(signingKey != null, encryptingKey != null, compressed, maximumAge, decodeOnceOnly) { this.asymmetricSigning = signingKey; this.asymmetricEncrypting = encryptingKey; - this.hasherForAsymmetricSigning = new SHA1CryptoServiceProvider(); } /// <summary> @@ -116,7 +110,7 @@ namespace DotNetOpenAuth.Messaging { protected DataBagFormatterBase(ICryptoKeyStore cryptoKeyStore = null, string bucket = null, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? minimumAge = null, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) : this(signed, encrypted, compressed, maximumAge, decodeOnceOnly) { Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(bucket) || cryptoKeyStore == null); - Contract.Requires<ArgumentException>(cryptoKeyStore != null || (!signed && !encrypted), "A secret is required when signing or encrypting is required."); + Contract.Requires<ArgumentException>(cryptoKeyStore != null || (!signed && !encrypted)); this.cryptoKeyStore = cryptoKeyStore; this.cryptoKeyBucket = bucket; @@ -134,8 +128,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="maximumAge">The maximum age of a token that can be decoded; useful only when <paramref name="decodeOnceOnly"/> is <c>true</c>.</param> /// <param name="decodeOnceOnly">The nonce store to use to ensure that this instance is only decoded once.</param> private DataBagFormatterBase(bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) { - Contract.Requires<ArgumentException>(signed || decodeOnceOnly == null, "A signature must be applied if this data is meant to be decoded only once."); - Contract.Requires<ArgumentException>(maximumAge.HasValue || decodeOnceOnly == null, "A maximum age must be given if a message can only be decoded once."); + Contract.Requires<ArgumentException>(signed || decodeOnceOnly == null); + Contract.Requires<ArgumentException>(maximumAge.HasValue || decodeOnceOnly == null); this.signed = signed; this.maximumAge = maximumAge; @@ -172,22 +166,23 @@ namespace DotNetOpenAuth.Messaging { } int capacity = this.signed ? 4 + message.Signature.Length + 4 + encoded.Length : encoded.Length; - var finalStream = new MemoryStream(capacity); - var writer = new BinaryWriter(finalStream); - if (this.signed) { - writer.WriteBuffer(message.Signature); - } + using (var finalStream = new MemoryStream(capacity)) { + var writer = new BinaryWriter(finalStream); + if (this.signed) { + writer.WriteBuffer(message.Signature); + } - writer.WriteBuffer(encoded); - writer.Flush(); + writer.WriteBuffer(encoded); + writer.Flush(); - string payload = MessagingUtilities.ConvertToBase64WebSafeString(finalStream.ToArray()); - string result = payload; - if (symmetricSecretHandle != null && (this.signed || this.encrypted)) { - result = MessagingUtilities.CombineKeyHandleAndPayload(symmetricSecretHandle, payload); - } + string payload = MessagingUtilities.ConvertToBase64WebSafeString(finalStream.ToArray()); + string result = payload; + if (symmetricSecretHandle != null && (this.signed || this.encrypted)) { + result = MessagingUtilities.CombineKeyHandleAndPayload(symmetricSecretHandle, payload); + } - return result; + return result; + } } /// <summary> @@ -209,10 +204,11 @@ namespace DotNetOpenAuth.Messaging { byte[] signature = null; if (this.signed) { - var dataStream = new MemoryStream(data); - var dataReader = new BinaryReader(dataStream); - signature = dataReader.ReadBuffer(); - data = dataReader.ReadBuffer(); + using (var dataStream = new MemoryStream(data)) { + var dataReader = new BinaryReader(dataStream); + signature = dataReader.ReadBuffer(); + data = dataReader.ReadBuffer(); + } // Verify that the verification code was issued by message authorization server. ErrorUtilities.VerifyProtocol(this.IsSignatureValid(data, signature, symmetricSecretHandle), MessagingStrings.SignatureInvalid); @@ -276,11 +272,13 @@ namespace DotNetOpenAuth.Messaging { /// <c>true</c> if the signature is valid; otherwise, <c>false</c>. /// </returns> private bool IsSignatureValid(byte[] signedData, byte[] signature, string symmetricSecretHandle) { - Contract.Requires<ArgumentNullException>(signedData != null, "message"); - Contract.Requires<ArgumentNullException>(signature != null, "signature"); + Contract.Requires<ArgumentNullException>(signedData != null); + Contract.Requires<ArgumentNullException>(signature != null); if (this.asymmetricSigning != null) { - return this.asymmetricSigning.VerifyData(signedData, this.hasherForAsymmetricSigning, signature); + using (var hasher = new SHA1CryptoServiceProvider()) { + return this.asymmetricSigning.VerifyData(signedData, hasher, signature); + } } else { return MessagingUtilities.AreEquivalentConstantTime(signature, this.CalculateSignature(signedData, symmetricSecretHandle)); } @@ -295,17 +293,20 @@ namespace DotNetOpenAuth.Messaging { /// The calculated signature. /// </returns> private byte[] CalculateSignature(byte[] bytesToSign, string symmetricSecretHandle) { - Contract.Requires<ArgumentNullException>(bytesToSign != null, "bytesToSign"); + Contract.Requires<ArgumentNullException>(bytesToSign != null); Contract.Requires<InvalidOperationException>(this.asymmetricSigning != null || this.cryptoKeyStore != null); Contract.Ensures(Contract.Result<byte[]>() != null); if (this.asymmetricSigning != null) { - return this.asymmetricSigning.SignData(bytesToSign, this.hasherForAsymmetricSigning); + using (var hasher = new SHA1CryptoServiceProvider()) { + return this.asymmetricSigning.SignData(bytesToSign, hasher); + } } else { var key = this.cryptoKeyStore.GetKey(this.cryptoKeyBucket, symmetricSecretHandle); ErrorUtilities.VerifyProtocol(key != null, "Missing decryption key."); - var symmetricHasher = new HMACSHA256(key.Key); - return symmetricHasher.ComputeHash(bytesToSign); + using (var symmetricHasher = new HMACSHA256(key.Key)) { + return symmetricHasher.ComputeHash(bytesToSign); + } } } diff --git a/src/DotNetOpenAuth/Messaging/IDataBagFormatter.cs b/src/DotNetOpenAuth/Messaging/IDataBagFormatter.cs index 529c331..c7dcc42 100644 --- a/src/DotNetOpenAuth/Messaging/IDataBagFormatter.cs +++ b/src/DotNetOpenAuth/Messaging/IDataBagFormatter.cs @@ -50,7 +50,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="message">The message to serialize. Must not be null.</param> /// <returns>A non-null, non-empty value.</returns> string IDataBagFormatter<T>.Serialize(T message) { - Contract.Requires<ArgumentNullException>(message != null, "message"); + Contract.Requires<ArgumentNullException>(message != null); Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>())); throw new System.NotImplementedException(); @@ -63,7 +63,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="data">The serialized form of the <see cref="DataBag"/> to deserialize. Must not be null or empty.</param> /// <returns>The deserialized value. Never null.</returns> T IDataBagFormatter<T>.Deserialize(IProtocolMessage containingMessage, string data) { - Contract.Requires<ArgumentNullException>(containingMessage != null, "containingMessage"); + Contract.Requires<ArgumentNullException>(containingMessage != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(data)); Contract.Ensures(Contract.Result<T>() != null); diff --git a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs index 0ad3da5..77a206c 100644 --- a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs +++ b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs @@ -59,8 +59,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="messageDictionary">The message dictionary to fill with the JSON-deserialized data.</param> /// <param name="reader">The JSON reader.</param> internal static void DeserializeJsonAsFlatDictionary(IDictionary<string, string> messageDictionary, XmlDictionaryReader reader) { - Contract.Requires<ArgumentNullException>(messageDictionary != null, "messageDictionary"); - Contract.Requires<ArgumentNullException>(reader != null, "reader"); + Contract.Requires<ArgumentNullException>(messageDictionary != null); + Contract.Requires<ArgumentNullException>(reader != null); reader.Read(); // one extra one to skip the root node. while (reader.Read()) { @@ -77,38 +77,6 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> - /// Reads the data from a message instance and returns a series of name=value pairs for the fields that must be included in the message. - /// </summary> - /// <param name="messageDictionary">The message to be serialized.</param> - /// <returns>The dictionary of values to send for the message.</returns> - [Pure] - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Parallel design with Deserialize method.")] - internal IDictionary<string, string> Serialize(MessageDictionary messageDictionary) { - Contract.Requires<ArgumentNullException>(messageDictionary != null); - Contract.Ensures(Contract.Result<IDictionary<string, string>>() != null); - - // Rather than hand back the whole message dictionary (which - // includes keys with blank values), create a new dictionary - // that only has required keys, and optional keys whose - // values are not empty (or default). - var result = new Dictionary<string, string>(); - foreach (var pair in messageDictionary) { - MessagePart partDescription; - if (messageDictionary.Description.Mapping.TryGetValue(pair.Key, out partDescription)) { - Contract.Assume(partDescription != null); - if (partDescription.IsRequired || partDescription.IsNondefaultValueSet(messageDictionary.Message)) { - result.Add(pair.Key, pair.Value); - } - } else { - // This is extra data. We always write it out. - result.Add(pair.Key, pair.Value); - } - } - - return result; - } - - /// <summary> /// Reads the data from a message instance and writes a XML/JSON encoding of it. /// </summary> /// <param name="messageDictionary">The message to be serialized.</param> @@ -118,9 +86,9 @@ namespace DotNetOpenAuth.Messaging { /// to create the <see cref="XmlDictionaryWriter"/> instance capable of emitting JSON. /// </remarks> [Pure] - internal void Serialize(MessageDictionary messageDictionary, XmlDictionaryWriter writer) { + internal static void Serialize(MessageDictionary messageDictionary, XmlDictionaryWriter writer) { Contract.Requires<ArgumentNullException>(messageDictionary != null); - Contract.Requires<ArgumentNullException>(writer != null, "writer"); + Contract.Requires<ArgumentNullException>(writer != null); writer.WriteStartElement("root"); writer.WriteAttributeString("type", "object"); @@ -155,6 +123,59 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> + /// Reads XML/JSON into a message dictionary. + /// </summary> + /// <param name="messageDictionary">The message to deserialize into.</param> + /// <param name="reader">The XML/JSON to read into the message.</param> + /// <exception cref="ProtocolException">Thrown when protocol rules are broken by the incoming message.</exception> + /// <remarks> + /// Use <see cref="System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.IO.Stream, System.Xml.XmlDictionaryReaderQuotas)"/> + /// to create the <see cref="XmlDictionaryReader"/> instance capable of reading JSON. + /// </remarks> + internal static void Deserialize(MessageDictionary messageDictionary, XmlDictionaryReader reader) { + Contract.Requires<ArgumentNullException>(messageDictionary != null); + Contract.Requires<ArgumentNullException>(reader != null); + + DeserializeJsonAsFlatDictionary(messageDictionary, reader); + + // Make sure all the required parts are present and valid. + messageDictionary.Description.EnsureMessagePartsPassBasicValidation(messageDictionary); + messageDictionary.Message.EnsureValidMessage(); + } + + /// <summary> + /// Reads the data from a message instance and returns a series of name=value pairs for the fields that must be included in the message. + /// </summary> + /// <param name="messageDictionary">The message to be serialized.</param> + /// <returns>The dictionary of values to send for the message.</returns> + [Pure] + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Parallel design with Deserialize method.")] + internal IDictionary<string, string> Serialize(MessageDictionary messageDictionary) { + Contract.Requires<ArgumentNullException>(messageDictionary != null); + Contract.Ensures(Contract.Result<IDictionary<string, string>>() != null); + + // Rather than hand back the whole message dictionary (which + // includes keys with blank values), create a new dictionary + // that only has required keys, and optional keys whose + // values are not empty (or default). + var result = new Dictionary<string, string>(); + foreach (var pair in messageDictionary) { + MessagePart partDescription; + if (messageDictionary.Description.Mapping.TryGetValue(pair.Key, out partDescription)) { + Contract.Assume(partDescription != null); + if (partDescription.IsRequired || partDescription.IsNondefaultValueSet(messageDictionary.Message)) { + result.Add(pair.Key, pair.Value); + } + } else { + // This is extra data. We always write it out. + result.Add(pair.Key, pair.Value); + } + } + + return result; + } + + /// <summary> /// Reads name=value pairs into a message. /// </summary> /// <param name="fields">The name=value pairs that were read in from the transport.</param> @@ -186,27 +207,6 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> - /// Reads XML/JSON into a message dictionary. - /// </summary> - /// <param name="messageDictionary">The message to deserialize into.</param> - /// <param name="reader">The XML/JSON to read into the message.</param> - /// <exception cref="ProtocolException">Thrown when protocol rules are broken by the incoming message.</exception> - /// <remarks> - /// Use <see cref="System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.IO.Stream, System.Xml.XmlDictionaryReaderQuotas)"/> - /// to create the <see cref="XmlDictionaryReader"/> instance capable of reading JSON. - /// </remarks> - internal void Deserialize(MessageDictionary messageDictionary, XmlDictionaryReader reader) { - Contract.Requires<ArgumentNullException>(messageDictionary != null); - Contract.Requires<ArgumentNullException>(reader != null, "reader"); - - DeserializeJsonAsFlatDictionary(messageDictionary, reader); - - // Make sure all the required parts are present and valid. - messageDictionary.Description.EnsureMessagePartsPassBasicValidation(messageDictionary); - messageDictionary.Message.EnsureValidMessage(); - } - - /// <summary> /// Determines whether the specified type is numeric. /// </summary> /// <param name="type">The type to test.</param> diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs index b43ba27..27d500d 100644 --- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs @@ -27,6 +27,7 @@ namespace DotNetOpenAuth.Messaging { /// <summary> /// A grab-bag of utility methods useful for the channel stack of the protocol. /// </summary> + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Utility class touches lots of surface area")] public static class MessagingUtilities { /// <summary> /// The cryptographically strong random data generator used for creating secrets. @@ -271,8 +272,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="collection">The collection to add to.</param> /// <param name="values">The values to add to the collection.</param> public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> values) { - Contract.Requires<ArgumentNullException>(collection != null, "collection"); - Contract.Requires<ArgumentNullException>(values != null, "values"); + Contract.Requires<ArgumentNullException>(collection != null); + Contract.Requires<ArgumentNullException>(values != null); foreach (var value in values) { collection.Add(value); @@ -286,7 +287,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="collection">The collection to modify.</param> /// <param name="values">The new values to fill the collection.</param> internal static void ResetContents<T>(this ICollection<T> collection, IEnumerable<T> values) { - Contract.Requires<ArgumentNullException>(collection != null, "collection"); + Contract.Requires<ArgumentNullException>(collection != null); collection.Clear(); if (values != null) { @@ -301,8 +302,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="messageDescription">The message description whose parts should be removed from the URL.</param> /// <returns>A cleaned URL.</returns> internal static Uri StripMessagePartsFromQueryString(this Uri uri, MessageDescription messageDescription) { - Contract.Requires<ArgumentNullException>(uri != null, "uri"); - Contract.Requires<ArgumentNullException>(messageDescription != null, "messageDescription"); + Contract.Requires<ArgumentNullException>(uri != null); + Contract.Requires<ArgumentNullException>(messageDescription != null); NameValueCollection queryArgs = HttpUtility.ParseQueryString(uri.Query); var matchingKeys = queryArgs.Keys.OfType<string>().Where(key => messageDescription.Mapping.ContainsKey(key)).ToList(); @@ -379,7 +380,7 @@ namespace DotNetOpenAuth.Messaging { /// <returns>A value prepared for an HTTP header.</returns> internal static string AssembleAuthorizationHeader(string scheme, IEnumerable<KeyValuePair<string, string>> fields) { Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(scheme)); - Contract.Requires<ArgumentNullException>(fields != null, "fields"); + Contract.Requires<ArgumentNullException>(fields != null); var authorization = new StringBuilder(); authorization.Append(scheme); @@ -450,7 +451,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="handle">The crypto key handle.</param> /// <param name="dataBlob">The encrypted/signed data.</param> internal static void ExtractKeyHandleAndPayload(IProtocolMessage containingMessage, string messagePart, string keyHandleAndBlob, out string handle, out string dataBlob) { - Contract.Requires<ArgumentNullException>(containingMessage != null, "containingMessage"); + Contract.Requires<ArgumentNullException>(containingMessage != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(messagePart)); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(keyHandleAndBlob)); @@ -520,8 +521,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="encoding">The encoding to use when converting the string to a byte array.</param> /// <returns>A base64 encoded string.</returns> internal static string ComputeHash(this HashAlgorithm algorithm, string value, Encoding encoding = null) { - Contract.Requires<ArgumentNullException>(algorithm != null, "algorithm"); - Contract.Requires<ArgumentNullException>(value != null, "value"); + Contract.Requires<ArgumentNullException>(algorithm != null); + Contract.Requires<ArgumentNullException>(value != null); Contract.Ensures(Contract.Result<string>() != null); encoding = encoding ?? Encoding.UTF8; @@ -539,8 +540,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="encoding">The encoding to use when converting the string to a byte array.</param> /// <returns>A base64 encoded string.</returns> internal static string ComputeHash(this HashAlgorithm algorithm, IDictionary<string, string> data, Encoding encoding = null) { - Contract.Requires<ArgumentNullException>(algorithm != null, "algorithm"); - Contract.Requires<ArgumentNullException>(data != null, "data"); + Contract.Requires<ArgumentNullException>(algorithm != null); + Contract.Requires<ArgumentNullException>(data != null); Contract.Ensures(Contract.Result<string>() != null); // Assemble the dictionary to sign, taking care to remove the signature itself @@ -560,8 +561,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="encoding">The encoding to use when converting the string to a byte array.</param> /// <returns>A base64 encoded string.</returns> internal static string ComputeHash(this HashAlgorithm algorithm, IEnumerable<KeyValuePair<string, string>> sortedData, Encoding encoding = null) { - Contract.Requires<ArgumentNullException>(algorithm != null, "algorithm"); - Contract.Requires<ArgumentNullException>(sortedData != null, "sortedData"); + Contract.Requires<ArgumentNullException>(algorithm != null); + Contract.Requires<ArgumentNullException>(sortedData != null); Contract.Ensures(Contract.Result<string>() != null); return ComputeHash(algorithm, CreateQueryString(sortedData), encoding); @@ -574,19 +575,20 @@ namespace DotNetOpenAuth.Messaging { /// <param name="key">The symmetric secret to use to encrypt the buffer. Allowed values are 128, 192, or 256 bytes in length.</param> /// <returns>The encrypted buffer</returns> internal static byte[] Encrypt(byte[] buffer, byte[] key) { - SymmetricAlgorithm crypto = CreateSymmetricAlgorithm(key); - - var ms = new MemoryStream(); - var binaryWriter = new BinaryWriter(ms); - binaryWriter.Write((byte)1); // version of encryption algorithm - binaryWriter.Write(crypto.IV); - binaryWriter.Flush(); - - var cryptoStream = new CryptoStream(ms, crypto.CreateEncryptor(), CryptoStreamMode.Write); - cryptoStream.Write(buffer, 0, buffer.Length); - cryptoStream.FlushFinalBlock(); - - return ms.ToArray(); + using (SymmetricAlgorithm crypto = CreateSymmetricAlgorithm(key)) { + using (var ms = new MemoryStream()) { + var binaryWriter = new BinaryWriter(ms); + binaryWriter.Write((byte)1); // version of encryption algorithm + binaryWriter.Write(crypto.IV); + binaryWriter.Flush(); + + var cryptoStream = new CryptoStream(ms, crypto.CreateEncryptor(), CryptoStreamMode.Write); + cryptoStream.Write(buffer, 0, buffer.Length); + cryptoStream.FlushFinalBlock(); + + return ms.ToArray(); + } + } } /// <summary> @@ -595,28 +597,30 @@ namespace DotNetOpenAuth.Messaging { /// <param name="buffer">The buffer to decrypt.</param> /// <param name="key">The symmetric secret to use to decrypt the buffer. Allowed values are 128, 192, and 256.</param> /// <returns>The encrypted buffer</returns> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "This Dispose is safe.")] internal static byte[] Decrypt(byte[] buffer, byte[] key) { - SymmetricAlgorithm crypto = CreateSymmetricAlgorithm(key); - - var ms = new MemoryStream(buffer); - var binaryReader = new BinaryReader(ms); - int algorithmVersion = binaryReader.ReadByte(); - ErrorUtilities.VerifyProtocol(algorithmVersion == 1, MessagingStrings.UnsupportedEncryptionAlgorithm); - crypto.IV = binaryReader.ReadBytes(crypto.IV.Length); - - // Allocate space for the decrypted buffer. We don't know how long it will be yet, - // but it will never be larger than the encrypted buffer. - var decryptedBuffer = new byte[buffer.Length]; - int actualDecryptedLength; + using (SymmetricAlgorithm crypto = CreateSymmetricAlgorithm(key)) { + using (var ms = new MemoryStream(buffer)) { + var binaryReader = new BinaryReader(ms); + int algorithmVersion = binaryReader.ReadByte(); + ErrorUtilities.VerifyProtocol(algorithmVersion == 1, MessagingStrings.UnsupportedEncryptionAlgorithm); + crypto.IV = binaryReader.ReadBytes(crypto.IV.Length); + + // Allocate space for the decrypted buffer. We don't know how long it will be yet, + // but it will never be larger than the encrypted buffer. + var decryptedBuffer = new byte[buffer.Length]; + int actualDecryptedLength; + + using (var cryptoStream = new CryptoStream(ms, crypto.CreateDecryptor(), CryptoStreamMode.Read)) { + actualDecryptedLength = cryptoStream.Read(decryptedBuffer, 0, decryptedBuffer.Length); + } - using (var cryptoStream = new CryptoStream(ms, crypto.CreateDecryptor(), CryptoStreamMode.Read)) { - actualDecryptedLength = cryptoStream.Read(decryptedBuffer, 0, decryptedBuffer.Length); + // Create a new buffer with only the decrypted data. + var finalDecryptedBuffer = new byte[actualDecryptedLength]; + Array.Copy(decryptedBuffer, finalDecryptedBuffer, actualDecryptedLength); + return finalDecryptedBuffer; + } } - - // Create a new buffer with only the decrypted data. - var finalDecryptedBuffer = new byte[actualDecryptedLength]; - Array.Copy(decryptedBuffer, finalDecryptedBuffer, actualDecryptedLength); - return finalDecryptedBuffer; } /// <summary> @@ -650,30 +654,31 @@ namespace DotNetOpenAuth.Messaging { /// <param name="buffer">The buffer to encrypt.</param> /// <returns>The encrypted data.</returns> internal static byte[] EncryptWithRandomSymmetricKey(this RSACryptoServiceProvider crypto, byte[] buffer) { - Contract.Requires<ArgumentNullException>(crypto != null, "crypto"); - Contract.Requires<ArgumentNullException>(buffer != null, "buffer"); + Contract.Requires<ArgumentNullException>(crypto != null); + Contract.Requires<ArgumentNullException>(buffer != null); - var symmetricCrypto = new RijndaelManaged { - Mode = CipherMode.CBC, - }; + using (var symmetricCrypto = new RijndaelManaged()) { + symmetricCrypto.Mode = CipherMode.CBC; - var encryptedStream = new MemoryStream(); - var encryptedStreamWriter = new BinaryWriter(encryptedStream); + using (var encryptedStream = new MemoryStream()) { + var encryptedStreamWriter = new BinaryWriter(encryptedStream); - byte[] prequel = new byte[symmetricCrypto.Key.Length + symmetricCrypto.IV.Length]; - Array.Copy(symmetricCrypto.Key, prequel, symmetricCrypto.Key.Length); - Array.Copy(symmetricCrypto.IV, 0, prequel, symmetricCrypto.Key.Length, symmetricCrypto.IV.Length); - byte[] encryptedPrequel = crypto.Encrypt(prequel, false); + byte[] prequel = new byte[symmetricCrypto.Key.Length + symmetricCrypto.IV.Length]; + Array.Copy(symmetricCrypto.Key, prequel, symmetricCrypto.Key.Length); + Array.Copy(symmetricCrypto.IV, 0, prequel, symmetricCrypto.Key.Length, symmetricCrypto.IV.Length); + byte[] encryptedPrequel = crypto.Encrypt(prequel, false); - encryptedStreamWriter.Write(encryptedPrequel.Length); - encryptedStreamWriter.Write(encryptedPrequel); - encryptedStreamWriter.Flush(); + encryptedStreamWriter.Write(encryptedPrequel.Length); + encryptedStreamWriter.Write(encryptedPrequel); + encryptedStreamWriter.Flush(); - var cryptoStream = new CryptoStream(encryptedStream, symmetricCrypto.CreateEncryptor(), CryptoStreamMode.Write); - cryptoStream.Write(buffer, 0, buffer.Length); - cryptoStream.FlushFinalBlock(); + var cryptoStream = new CryptoStream(encryptedStream, symmetricCrypto.CreateEncryptor(), CryptoStreamMode.Write); + cryptoStream.Write(buffer, 0, buffer.Length); + cryptoStream.FlushFinalBlock(); - return encryptedStream.ToArray(); + return encryptedStream.ToArray(); + } + } } /// <summary> @@ -682,40 +687,42 @@ namespace DotNetOpenAuth.Messaging { /// <param name="crypto">The asymmetric encryption provider to use for decryption.</param> /// <param name="buffer">The buffer to decrypt.</param> /// <returns>The decrypted data.</returns> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "This Dispose is safe.")] internal static byte[] DecryptWithRandomSymmetricKey(this RSACryptoServiceProvider crypto, byte[] buffer) { - Contract.Requires<ArgumentNullException>(crypto != null, "crypto"); - Contract.Requires<ArgumentNullException>(buffer != null, "buffer"); + Contract.Requires<ArgumentNullException>(crypto != null); + Contract.Requires<ArgumentNullException>(buffer != null); - var encryptedStream = new MemoryStream(buffer); - var encryptedStreamReader = new BinaryReader(encryptedStream); + using (var encryptedStream = new MemoryStream(buffer)) { + var encryptedStreamReader = new BinaryReader(encryptedStream); - byte[] encryptedPrequel = encryptedStreamReader.ReadBytes(encryptedStreamReader.ReadInt32()); - byte[] prequel = crypto.Decrypt(encryptedPrequel, false); + byte[] encryptedPrequel = encryptedStreamReader.ReadBytes(encryptedStreamReader.ReadInt32()); + byte[] prequel = crypto.Decrypt(encryptedPrequel, false); - var symmetricCrypto = new RijndaelManaged { - Mode = CipherMode.CBC, - }; + using (var symmetricCrypto = new RijndaelManaged()) { + symmetricCrypto.Mode = CipherMode.CBC; - byte[] symmetricKey = new byte[symmetricCrypto.Key.Length]; - byte[] symmetricIV = new byte[symmetricCrypto.IV.Length]; - Array.Copy(prequel, symmetricKey, symmetricKey.Length); - Array.Copy(prequel, symmetricKey.Length, symmetricIV, 0, symmetricIV.Length); - symmetricCrypto.Key = symmetricKey; - symmetricCrypto.IV = symmetricIV; + byte[] symmetricKey = new byte[symmetricCrypto.Key.Length]; + byte[] symmetricIV = new byte[symmetricCrypto.IV.Length]; + Array.Copy(prequel, symmetricKey, symmetricKey.Length); + Array.Copy(prequel, symmetricKey.Length, symmetricIV, 0, symmetricIV.Length); + symmetricCrypto.Key = symmetricKey; + symmetricCrypto.IV = symmetricIV; - // Allocate space for the decrypted buffer. We don't know how long it will be yet, - // but it will never be larger than the encrypted buffer. - var decryptedBuffer = new byte[encryptedStream.Length - encryptedStream.Position]; - int actualDecryptedLength; + // Allocate space for the decrypted buffer. We don't know how long it will be yet, + // but it will never be larger than the encrypted buffer. + var decryptedBuffer = new byte[encryptedStream.Length - encryptedStream.Position]; + int actualDecryptedLength; - using (var cryptoStream = new CryptoStream(encryptedStream, symmetricCrypto.CreateDecryptor(), CryptoStreamMode.Read)) { - actualDecryptedLength = cryptoStream.Read(decryptedBuffer, 0, decryptedBuffer.Length); - } + using (var cryptoStream = new CryptoStream(encryptedStream, symmetricCrypto.CreateDecryptor(), CryptoStreamMode.Read)) { + actualDecryptedLength = cryptoStream.Read(decryptedBuffer, 0, decryptedBuffer.Length); + } - // Create a new buffer with only the decrypted data. - var finalDecryptedBuffer = new byte[actualDecryptedLength]; - Array.Copy(decryptedBuffer, finalDecryptedBuffer, actualDecryptedLength); - return finalDecryptedBuffer; + // Create a new buffer with only the decrypted data. + var finalDecryptedBuffer = new byte[actualDecryptedLength]; + Array.Copy(decryptedBuffer, finalDecryptedBuffer, actualDecryptedLength); + return finalDecryptedBuffer; + } + } } /// <summary> @@ -729,7 +736,7 @@ namespace DotNetOpenAuth.Messaging { /// A key-value pair whose key is the secret's handle and whose value is the cryptographic key. /// </returns> internal static KeyValuePair<string, CryptoKey> GetCurrentKey(this ICryptoKeyStore cryptoKeyStore, string bucket, TimeSpan minimumRemainingLife, int keySize = 256) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(bucket)); Contract.Requires<ArgumentException>(keySize % 8 == 0); @@ -762,13 +769,18 @@ namespace DotNetOpenAuth.Messaging { /// </summary> /// <param name="buffer">The buffer to compress.</param> /// <returns>The compressed data.</returns> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "This Dispose is safe.")] internal static byte[] Compress(byte[] buffer) { - var ms = new MemoryStream(); - using (var compressingStream = new DeflateStream(ms, CompressionMode.Compress, true)) { - compressingStream.Write(buffer, 0, buffer.Length); - } + Contract.Requires<ArgumentNullException>(buffer != null); + Contract.Ensures(Contract.Result<byte[]>() != null); + + using (var ms = new MemoryStream()) { + using (var compressingStream = new DeflateStream(ms, CompressionMode.Compress, true)) { + compressingStream.Write(buffer, 0, buffer.Length); + } - return ms.ToArray(); + return ms.ToArray(); + } } /// <summary> @@ -777,13 +789,18 @@ namespace DotNetOpenAuth.Messaging { /// <param name="buffer">The buffer to decompress.</param> /// <returns>The decompressed data.</returns> internal static byte[] Decompress(byte[] buffer) { - var compressedDataStream = new MemoryStream(buffer); - var decompressedDataStream = new MemoryStream(); - using (var decompressingStream = new DeflateStream(compressedDataStream, CompressionMode.Decompress, true)) { - decompressingStream.CopyTo(decompressedDataStream); - } + Contract.Requires<ArgumentNullException>(buffer != null); + Contract.Ensures(Contract.Result<byte[]>() != null); + + using (var compressedDataStream = new MemoryStream(buffer)) { + using (var decompressedDataStream = new MemoryStream()) { + using (var decompressingStream = new DeflateStream(compressedDataStream, CompressionMode.Decompress, true)) { + decompressingStream.CopyTo(decompressedDataStream); + } - return decompressedDataStream.ToArray(); + return decompressedDataStream.ToArray(); + } + } } /// <summary> @@ -1387,7 +1404,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="sequence">The sequence.</param> /// <returns>A dictionary.</returns> internal static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> sequence) { - Contract.Requires<ArgumentNullException>(sequence != null, "sequence"); + Contract.Requires<ArgumentNullException>(sequence != null); return sequence.ToDictionary(pair => pair.Key, pair => pair.Value); } @@ -1500,8 +1517,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="writer">The binary writer.</param> /// <param name="buffer">The buffer.</param> internal static void WriteBuffer(this BinaryWriter writer, byte[] buffer) { - Contract.Requires<ArgumentNullException>(writer != null, "writer"); - Contract.Requires<ArgumentNullException>(buffer != null, "buffer"); + Contract.Requires<ArgumentNullException>(writer != null); + Contract.Requires<ArgumentNullException>(buffer != null); writer.Write(buffer.Length); writer.Write(buffer, 0, buffer.Length); } @@ -1512,7 +1529,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="reader">The binary reader positioned at the buffer length.</param> /// <returns>The read buffer.</returns> internal static byte[] ReadBuffer(this BinaryReader reader) { - Contract.Requires<ArgumentNullException>(reader != null, "reader"); + Contract.Requires<ArgumentNullException>(reader != null); int length = reader.ReadInt32(); byte[] buffer = new byte[length]; ErrorUtilities.VerifyProtocol(reader.Read(buffer, 0, length) == length, "Unexpected buffer length."); @@ -1627,10 +1644,20 @@ namespace DotNetOpenAuth.Messaging { /// <param name="key">The symmetric key to use for encryption/decryption.</param> /// <returns>A symmetric algorithm.</returns> private static SymmetricAlgorithm CreateSymmetricAlgorithm(byte[] key) { - return new RijndaelManaged { - Mode = CipherMode.CBC, - Key = key, - }; + SymmetricAlgorithm result = null; + try { + result = new RijndaelManaged(); + result.Mode = CipherMode.CBC; + result.Key = key; + return result; + } catch { + IDisposable disposableResult = result; + if (disposableResult != null) { + disposableResult.Dispose(); + } + + throw; + } } /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs index aa7f5b7..e5cbff8 100644 --- a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs +++ b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs @@ -318,8 +318,8 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// <param name="toValue">The function to convert a string to the custom type.</param> [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "toString", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "toValue", Justification = "Code contracts")] private static void Map<T>(Func<T, string> toString, Func<T, string> toOriginalString, Func<string, T> toValue) { - Contract.Requires<ArgumentNullException>(toString != null, "toString"); - Contract.Requires<ArgumentNullException>(toValue != null, "toValue"); + Contract.Requires<ArgumentNullException>(toString != null); + Contract.Requires<ArgumentNullException>(toValue != null); if (toOriginalString == null) { toOriginalString = toString; diff --git a/src/DotNetOpenAuth/Messaging/StandardMessageFactory.cs b/src/DotNetOpenAuth/Messaging/StandardMessageFactory.cs index 530077a..b28ce74 100644 --- a/src/DotNetOpenAuth/Messaging/StandardMessageFactory.cs +++ b/src/DotNetOpenAuth/Messaging/StandardMessageFactory.cs @@ -144,7 +144,7 @@ namespace DotNetOpenAuth.Messaging { var matches = this.requestMessageTypes.Keys .Where(message => message.CheckMessagePartsPassBasicValidation(fields)) - .OrderByDescending(message => this.CountInCommon(message.Mapping.Keys, fields.Keys)) + .OrderByDescending(message => CountInCommon(message.Mapping.Keys, fields.Keys)) .ThenByDescending(message => message.Mapping.Count) .CacheGeneratedResults(); var match = matches.FirstOrDefault(); @@ -181,7 +181,7 @@ namespace DotNetOpenAuth.Messaging { let ctors = this.FindMatchingResponseConstructors(message, request.GetType()) where ctors.Any() orderby GetDerivationDistance(ctors.First().GetParameters()[0].ParameterType, request.GetType()), - this.CountInCommon(message.Mapping.Keys, fields.Keys) descending, + CountInCommon(message.Mapping.Keys, fields.Keys) descending, message.Mapping.Count descending select message).CacheGeneratedResults(); var match = matches.FirstOrDefault(); @@ -247,8 +247,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="derivedType">The concrete class that implements the <paramref name="assignableType"/>.</param> /// <returns>The distance between the two types. 0 if the types are equivalent, 1 if the type immediately derives from or implements the base type, or progressively higher integers.</returns> private static int GetDerivationDistance(Type assignableType, Type derivedType) { - Contract.Requires<ArgumentNullException>(assignableType != null, "assignableType"); - Contract.Requires<ArgumentNullException>(derivedType != null, "derivedType"); + Contract.Requires<ArgumentNullException>(assignableType != null); + Contract.Requires<ArgumentNullException>(derivedType != null); Contract.Requires<ArgumentException>(assignableType.IsAssignableFrom(derivedType)); // If this is the two types are equivalent... @@ -268,6 +268,21 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> + /// Counts how many strings are in the intersection of two collections. + /// </summary> + /// <param name="collection1">The first collection.</param> + /// <param name="collection2">The second collection.</param> + /// <param name="comparison">The string comparison method to use.</param> + /// <returns>A non-negative integer no greater than the count of elements in the smallest collection.</returns> + private static int CountInCommon(ICollection<string> collection1, ICollection<string> collection2, StringComparison comparison = StringComparison.Ordinal) { + Contract.Requires<ArgumentNullException>(collection1 != null); + Contract.Requires<ArgumentNullException>(collection2 != null); + Contract.Ensures(Contract.Result<int>() >= 0 && Contract.Result<int>() <= Math.Min(collection1.Count, collection2.Count)); + + return collection1.Count(value1 => collection2.Any(value2 => string.Equals(value1, value2, comparison))); + } + + /// <summary> /// Finds constructors for response messages that take a given request message type. /// </summary> /// <param name="messageDescription">The message description.</param> @@ -279,20 +294,5 @@ namespace DotNetOpenAuth.Messaging { return this.responseMessageTypes[messageDescription].Where(pair => pair.Key.IsAssignableFrom(requestType)).Select(pair => pair.Value); } - - /// <summary> - /// Counts how many strings are in the intersection of two collections. - /// </summary> - /// <param name="collection1">The first collection.</param> - /// <param name="collection2">The second collection.</param> - /// <param name="comparison">The string comparison method to use.</param> - /// <returns>A non-negative integer no greater than the count of elements in the smallest collection.</returns> - private int CountInCommon(ICollection<string> collection1, ICollection<string> collection2, StringComparison comparison = StringComparison.Ordinal) { - Contract.Requires<ArgumentNullException>(collection1 != null, "collection1"); - Contract.Requires<ArgumentNullException>(collection2 != null, "collection2"); - Contract.Ensures(Contract.Result<int>() >= 0 && Contract.Result<int>() <= Math.Min(collection1.Count, collection2.Count)); - - return collection1.Count(value1 => collection2.Any(value2 => string.Equals(value1, value2, comparison))); - } } } diff --git a/src/DotNetOpenAuth/Messaging/StandardMessageFactoryChannel.cs b/src/DotNetOpenAuth/Messaging/StandardMessageFactoryChannel.cs index 147b420..1fc3608 100644 --- a/src/DotNetOpenAuth/Messaging/StandardMessageFactoryChannel.cs +++ b/src/DotNetOpenAuth/Messaging/StandardMessageFactoryChannel.cs @@ -34,8 +34,8 @@ namespace DotNetOpenAuth.Messaging { /// <param name="bindingElements">The binding elements to apply to the channel.</param> protected StandardMessageFactoryChannel(ICollection<Type> messageTypes, ICollection<Version> versions, params IChannelBindingElement[] bindingElements) : base(new StandardMessageFactory(), bindingElements) { - Contract.Requires<ArgumentNullException>(messageTypes != null, "messageTypes"); - Contract.Requires<ArgumentNullException>(versions != null, "versions"); + Contract.Requires<ArgumentNullException>(messageTypes != null); + Contract.Requires<ArgumentNullException>(versions != null); this.messageTypes = messageTypes; this.versions = versions; @@ -54,7 +54,7 @@ namespace DotNetOpenAuth.Messaging { /// <summary> /// Gets or sets the message descriptions. /// </summary> - internal override MessageDescriptionCollection MessageDescriptions { + internal sealed override MessageDescriptionCollection MessageDescriptions { get { return base.MessageDescriptions; } @@ -73,7 +73,7 @@ namespace DotNetOpenAuth.Messaging { /// Gets or sets a tool that can figure out what kind of message is being received /// so it can be deserialized. /// </summary> - protected override IMessageFactory MessageFactory { + protected sealed override IMessageFactory MessageFactory { get { return (StandardMessageFactory)base.MessageFactory; } @@ -93,7 +93,7 @@ namespace DotNetOpenAuth.Messaging { /// <returns>The generated/retrieved message descriptions.</returns> private static IEnumerable<MessageDescription> GetMessageDescriptions(ICollection<Type> messageTypes, ICollection<Version> versions, MessageDescriptionCollection descriptionsCache) { - Contract.Requires<ArgumentNullException>(messageTypes != null, "messageTypes"); + Contract.Requires<ArgumentNullException>(messageTypes != null); Contract.Requires<ArgumentNullException>(descriptionsCache != null); Contract.Ensures(Contract.Result<IEnumerable<MessageDescription>>() != null); diff --git a/src/DotNetOpenAuth/Messaging/UriStyleMessageFormatter.cs b/src/DotNetOpenAuth/Messaging/UriStyleMessageFormatter.cs index 8c66128..9bffc3d 100644 --- a/src/DotNetOpenAuth/Messaging/UriStyleMessageFormatter.cs +++ b/src/DotNetOpenAuth/Messaging/UriStyleMessageFormatter.cs @@ -46,7 +46,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="decodeOnceOnly">The nonce store to use to ensure that this instance is only decoded once.</param> protected internal UriStyleMessageFormatter(ICryptoKeyStore cryptoKeyStore = null, string bucket = null, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? minimumAge = null, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) : base(cryptoKeyStore, bucket, signed, encrypted, compressed, minimumAge, maximumAge, decodeOnceOnly) { - Contract.Requires<ArgumentException>((cryptoKeyStore != null && !String.IsNullOrEmpty(bucket)) || (!signed && !encrypted), "A secret is required when signing or encrypting is required."); + Contract.Requires<ArgumentException>((cryptoKeyStore != null && !String.IsNullOrEmpty(bucket)) || (!signed && !encrypted)); } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs index 4b5aebe..76b5149 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs @@ -42,7 +42,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { securitySettings, new OAuthConsumerMessageFactory()) { Contract.Requires<ArgumentNullException>(tokenManager != null); - Contract.Requires<ArgumentNullException>(securitySettings != null, "securitySettings"); + Contract.Requires<ArgumentNullException>(securitySettings != null); Contract.Requires<ArgumentNullException>(signingBindingElement != null); Contract.Requires<ArgumentException>(signingBindingElement.SignatureCallback == null, OAuthStrings.SigningElementAlreadyAssociatedWithChannel); } @@ -63,7 +63,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { securitySettings, new OAuthServiceProviderMessageFactory(tokenManager)) { Contract.Requires<ArgumentNullException>(tokenManager != null); - Contract.Requires<ArgumentNullException>(securitySettings != null, "securitySettings"); + Contract.Requires<ArgumentNullException>(securitySettings != null); Contract.Requires<ArgumentNullException>(signingBindingElement != null); Contract.Requires<ArgumentException>(signingBindingElement.SignatureCallback == null, OAuthStrings.SigningElementAlreadyAssociatedWithChannel); } @@ -82,7 +82,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, SecuritySettings securitySettings, IMessageFactory messageTypeProvider) : base(messageTypeProvider, InitializeBindingElements(signingBindingElement, store, tokenManager, securitySettings)) { Contract.Requires<ArgumentNullException>(tokenManager != null); - Contract.Requires<ArgumentNullException>(securitySettings != null, "securitySettings"); + Contract.Requires<ArgumentNullException>(securitySettings != null); Contract.Requires<ArgumentNullException>(signingBindingElement != null); Contract.Requires<ArgumentException>(signingBindingElement.SignatureCallback == null, OAuthStrings.SigningElementAlreadyAssociatedWithChannel); diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs index 83954bf..82ecb0a 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs @@ -28,10 +28,10 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <summary> /// Initializes a new instance of the <see cref="OAuthPrincipal"/> class. /// </summary> - /// <param name="username">The username.</param> + /// <param name="userName">The username.</param> /// <param name="roles">The roles this user belongs to.</param> - public OAuthPrincipal(string username, string[] roles) - : this(new OAuthIdentity(username), roles) { + public OAuthPrincipal(string userName, string[] roles) + : this(new OAuthIdentity(userName), roles) { } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs index bfebd8b..f53aa1b 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs @@ -38,7 +38,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contract"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")] internal TokenHandlingBindingElement(IServiceProviderTokenManager tokenManager, ServiceProviderSecuritySettings securitySettings) { Contract.Requires<ArgumentNullException>(tokenManager != null); - Contract.Requires<ArgumentNullException>(securitySettings != null, "securitySettings"); + Contract.Requires<ArgumentNullException>(securitySettings != null); this.tokenManager = tokenManager; this.securitySettings = securitySettings; diff --git a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs index 82334ef..ea8be94 100644 --- a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs @@ -24,7 +24,7 @@ namespace DotNetOpenAuth.OAuth2 { /// </summary> /// <param name="authorizationServer">The authorization server.</param> public AuthorizationServer(IAuthorizationServer authorizationServer) { - Contract.Requires<ArgumentNullException>(authorizationServer != null, "authorizationServer"); + Contract.Requires<ArgumentNullException>(authorizationServer != null); this.OAuthChannel = new OAuth2AuthorizationServerChannel(authorizationServer); } @@ -70,13 +70,13 @@ namespace DotNetOpenAuth.OAuth2 { /// Approves an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client. /// </summary> /// <param name="authorizationRequest">The authorization request to approve.</param> - /// <param name="username">The username of the account that approved the request (or whose data will be accessed by the client).</param> + /// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param> /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param> /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param> - public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) { - Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest"); + public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) { + Contract.Requires<ArgumentNullException>(authorizationRequest != null); - var response = this.PrepareApproveAuthorizationRequest(authorizationRequest, username, scopes, callback); + var response = this.PrepareApproveAuthorizationRequest(authorizationRequest, userName, scopes, callback); this.Channel.Send(response); } @@ -87,7 +87,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="authorizationRequest">The authorization request to disapprove.</param> /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param> public void RejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) { - Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest"); + Contract.Requires<ArgumentNullException>(authorizationRequest != null); var response = this.PrepareRejectAuthorizationRequest(authorizationRequest, callback); this.Channel.Send(response); @@ -117,7 +117,7 @@ namespace DotNetOpenAuth.OAuth2 { /// asymmetric key for signing and encrypting the access token. If this is not true, use the <see cref="ReadAccessTokenRequest"/> method instead. /// </remarks> public bool TryPrepareAccessTokenResponse(HttpRequestInfo httpRequestInfo, out IDirectResponseProtocolMessage response) { - Contract.Requires<ArgumentNullException>(httpRequestInfo != null, "httpRequestInfo"); + Contract.Requires<ArgumentNullException>(httpRequestInfo != null); Contract.Ensures(Contract.Result<bool>() == (Contract.ValueAtReturn<IDirectResponseProtocolMessage>(out response) != null)); var request = this.ReadAccessTokenRequest(httpRequestInfo); @@ -157,7 +157,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param> /// <returns>The authorization response message to send to the Client.</returns> public EndUserAuthorizationFailedResponse PrepareRejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) { - Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest"); + Contract.Requires<ArgumentNullException>(authorizationRequest != null); Contract.Ensures(Contract.Result<EndUserAuthorizationFailedResponse>() != null); if (callback == null) { @@ -172,13 +172,13 @@ namespace DotNetOpenAuth.OAuth2 { /// Approves an authorization request. /// </summary> /// <param name="authorizationRequest">The authorization request to approve.</param> - /// <param name="username">The username of the account that approved the request (or whose data will be accessed by the client).</param> + /// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param> /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param> /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param> /// <returns>The authorization response message to send to the Client.</returns> - public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) { - Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest"); - Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(username)); + public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) { + Contract.Requires<ArgumentNullException>(authorizationRequest != null); + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(userName)); Contract.Ensures(Contract.Result<EndUserAuthorizationSuccessResponseBase>() != null); if (callback == null) { @@ -187,19 +187,19 @@ namespace DotNetOpenAuth.OAuth2 { var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier); EndUserAuthorizationSuccessResponseBase response; - switch (authorizationRequest.ResponseType) { - case EndUserAuthorizationResponseType.AccessToken: + switch (EndUserAuthorizationRequest.ResponseType) { + case EndUserAuthorizationResponseTypes.AccessToken: response = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest); break; - case EndUserAuthorizationResponseType.Both: - case EndUserAuthorizationResponseType.AuthorizationCode: + case EndUserAuthorizationResponseTypes.Both: + case EndUserAuthorizationResponseTypes.AuthorizationCode: response = new EndUserAuthorizationSuccessAuthCodeResponse(callback, authorizationRequest); break; default: throw ErrorUtilities.ThrowInternal("Unexpected response type."); } - response.AuthorizingUsername = username; + response.AuthorizingUsername = userName; // Customize the approved scope if the authorization server has decided to do so. if (scopes != null) { @@ -218,8 +218,8 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="includeRefreshToken">If set to <c>true</c>, the response will include a long-lived refresh token.</param> /// <returns>The response message to send to the client.</returns> public virtual IDirectResponseProtocolMessage PrepareAccessTokenResponse(AccessTokenRequestBase request, RSACryptoServiceProvider accessTokenEncryptingPublicKey, TimeSpan? accessTokenLifetime = null, bool includeRefreshToken = true) { - Contract.Requires<ArgumentNullException>(request != null, "request"); - Contract.Requires<ArgumentNullException>(accessTokenEncryptingPublicKey != null, "accessTokenEncryptingPublicKey"); + Contract.Requires<ArgumentNullException>(request != null); + Contract.Requires<ArgumentNullException>(accessTokenEncryptingPublicKey != null); var tokenRequest = (ITokenCarryingRequest)request; using (var crypto = this.AuthorizationServerServices.CreateAccessTokenSigningCryptoServiceProvider()) { @@ -249,7 +249,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <returns>The URL to redirect to. Never <c>null</c>.</returns> /// <exception cref="ProtocolException">Thrown if no callback URL could be determined.</exception> protected Uri GetCallback(EndUserAuthorizationRequest authorizationRequest) { - Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest"); + Contract.Requires<ArgumentNullException>(authorizationRequest != null); Contract.Ensures(Contract.Result<Uri>() != null); var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier); diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs index 015bf53..932db73 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs @@ -28,7 +28,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// <param name="authorization">The authorization to be described by the access token.</param> /// <param name="lifetime">The lifetime of the access token.</param> internal AccessToken(IAuthorizationDescription authorization, TimeSpan? lifetime) { - Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); + Contract.Requires<ArgumentNullException>(authorization != null); this.ClientIdentifier = authorization.ClientIdentifier; this.UtcCreationDate = authorization.UtcIssued; diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs index 6067541..237b1cd 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs @@ -23,11 +23,6 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { internal const string AuthorizationCodeKeyBucket = "https://localhost/dnoa/oauth_authorization_code"; /// <summary> - /// The hash algorithm used on the callback URI. - /// </summary> - private readonly HashAlgorithm hasher = new SHA256Managed(); - - /// <summary> /// Initializes a new instance of the <see cref="AuthorizationCode"/> class. /// </summary> public AuthorizationCode() { @@ -42,10 +37,10 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// <param name="username">The name on the account that authorized access.</param> internal AuthorizationCode(string clientIdentifier, Uri callback, IEnumerable<string> scopes, string username) { Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(clientIdentifier)); - Contract.Requires<ArgumentNullException>(callback != null, "callback"); + Contract.Requires<ArgumentNullException>(callback != null); this.ClientIdentifier = clientIdentifier; - this.CallbackHash = this.CalculateCallbackHash(callback); + this.CallbackHash = CalculateCallbackHash(callback); this.Scope.ResetContents(scopes); this.User = username; } @@ -62,7 +57,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// <param name="authorizationServer">The authorization server that will be serializing/deserializing this authorization code. Must not be null.</param> /// <returns>A DataBag formatter.</returns> internal static IDataBagFormatter<AuthorizationCode> CreateFormatter(IAuthorizationServer authorizationServer) { - Contract.Requires<ArgumentNullException>(authorizationServer != null, "authorizationServer"); + Contract.Requires<ArgumentNullException>(authorizationServer != null); Contract.Ensures(Contract.Result<IDataBagFormatter<AuthorizationCode>>() != null); return new UriStyleMessageFormatter<AuthorizationCode>( @@ -85,7 +80,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// </remarks> /// <exception cref="ProtocolException">Thrown when the callback URLs do not match.</exception> internal void VerifyCallback(Uri callback) { - ErrorUtilities.VerifyProtocol(MessagingUtilities.AreEquivalent(this.CallbackHash, this.CalculateCallbackHash(callback)), Protocol.redirect_uri_mismatch); + ErrorUtilities.VerifyProtocol(MessagingUtilities.AreEquivalent(this.CallbackHash, CalculateCallbackHash(callback)), Protocol.redirect_uri_mismatch); } /// <summary> @@ -95,8 +90,10 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// <returns> /// A base64 encoding of the hash of the URL. /// </returns> - private byte[] CalculateCallbackHash(Uri callback) { - return this.hasher.ComputeHash(Encoding.UTF8.GetBytes(callback.AbsoluteUri)); + private static byte[] CalculateCallbackHash(Uri callback) { + using (var hasher = new SHA256Managed()) { + return hasher.ComputeHash(Encoding.UTF8.GetBytes(callback.AbsoluteUri)); + } } } } diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs index 760dbb4..33986c7 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs @@ -30,14 +30,14 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// The <paramref name="value"/> in string form, ready for message transport. /// </returns> public string Encode(object value) { - var responseType = (EndUserAuthorizationResponseType)value; + var responseType = (EndUserAuthorizationResponseTypes)value; switch (responseType) { - case EndUserAuthorizationResponseType.Both: + case EndUserAuthorizationResponseTypes.Both: return Protocol.ResponseTypes.CodeAndToken; - case EndUserAuthorizationResponseType.AccessToken: + case EndUserAuthorizationResponseTypes.AccessToken: return Protocol.ResponseTypes.Token; - case EndUserAuthorizationResponseType.AuthorizationCode: + case EndUserAuthorizationResponseTypes.AuthorizationCode: return Protocol.ResponseTypes.Code; default: throw ErrorUtilities.ThrowFormat(MessagingStrings.UnexpectedMessagePartValue, Protocol.response_type, value); @@ -55,11 +55,11 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { public object Decode(string value) { switch (value) { case Protocol.ResponseTypes.CodeAndToken: - return EndUserAuthorizationResponseType.Both; + return EndUserAuthorizationResponseTypes.Both; case Protocol.ResponseTypes.Token: - return EndUserAuthorizationResponseType.AccessToken; + return EndUserAuthorizationResponseTypes.AccessToken; case Protocol.ResponseTypes.Code: - return EndUserAuthorizationResponseType.AuthorizationCode; + return EndUserAuthorizationResponseTypes.AuthorizationCode; default: throw ErrorUtilities.ThrowFormat(MessagingStrings.UnexpectedMessagePartValue, Protocol.response_type, value); } diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs index 5ecf01c..0e648d4 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs @@ -22,7 +22,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// <param name="authorizationServer">The authorization server.</param> protected internal OAuth2AuthorizationServerChannel(IAuthorizationServer authorizationServer) : base(InitializeBindingElements(authorizationServer)) { - Contract.Requires<ArgumentNullException>(authorizationServer != null, "authorizationServer"); + Contract.Requires<ArgumentNullException>(authorizationServer != null); this.AuthorizationServer = authorizationServer; } @@ -94,7 +94,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// An array of binding elements used to initialize the channel. /// </returns> private static IChannelBindingElement[] InitializeBindingElements(IAuthorizationServer authorizationServer) { - Contract.Requires<ArgumentNullException>(authorizationServer != null, "authorizationServer"); + Contract.Requires<ArgumentNullException>(authorizationServer != null); var bindingElements = new List<IChannelBindingElement>(); bindingElements.Add(new AuthServerAllFlowsBindingElement()); diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/RefreshToken.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/RefreshToken.cs index 4662719..9fe54c5 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/RefreshToken.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/RefreshToken.cs @@ -31,7 +31,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// </summary> /// <param name="authorization">The authorization this refresh token should describe.</param> internal RefreshToken(IAuthorizationDescription authorization) { - Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); + Contract.Requires<ArgumentNullException>(authorization != null); this.ClientIdentifier = authorization.ClientIdentifier; this.UtcCreationDate = authorization.UtcIssued; @@ -47,7 +47,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// A DataBag formatter. Never null. /// </returns> internal static IDataBagFormatter<RefreshToken> CreateFormatter(ICryptoKeyStore cryptoKeyStore) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); Contract.Ensures(Contract.Result<IDataBagFormatter<RefreshToken>>() != null); return new UriStyleMessageFormatter<RefreshToken>(cryptoKeyStore, RefreshTokenKeyBucket, signed: true, encrypted: true); diff --git a/src/DotNetOpenAuth/OAuth2/ClientBase.cs b/src/DotNetOpenAuth/OAuth2/ClientBase.cs index 48c9913..045fdf2 100644 --- a/src/DotNetOpenAuth/OAuth2/ClientBase.cs +++ b/src/DotNetOpenAuth/OAuth2/ClientBase.cs @@ -62,7 +62,7 @@ namespace DotNetOpenAuth.OAuth2 { /// </summary> /// <param name="request">The request for protected resources from the service provider.</param> /// <param name="accessToken">The access token previously obtained from the Authorization Server.</param> - public void AuthorizeRequest(HttpWebRequest request, string accessToken) { + public static void AuthorizeRequest(HttpWebRequest request, string accessToken) { Contract.Requires<ArgumentNullException>(request != null); Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(accessToken)); @@ -86,7 +86,7 @@ namespace DotNetOpenAuth.OAuth2 { this.RefreshToken(authorization); } - this.AuthorizeRequest(request, authorization.AccessToken); + AuthorizeRequest(request, authorization.AccessToken); } /// <summary> @@ -96,7 +96,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="skipIfUsefulLifeExceeds">If given, the access token will <em>not</em> be refreshed if its remaining lifetime exceeds this value.</param> /// <returns>A value indicating whether the access token was actually renewed; <c>true</c> if it was renewed, or <c>false</c> if it still had useful life remaining.</returns> public bool RefreshToken(IAuthorizationState authorization, TimeSpan? skipIfUsefulLifeExceeds = null) { - Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); + Contract.Requires<ArgumentNullException>(authorization != null); Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(authorization.RefreshToken)); if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue) { @@ -138,9 +138,9 @@ namespace DotNetOpenAuth.OAuth2 { /// </summary> /// <param name="authorizationState">The authorization state maintained by the client.</param> /// <param name="accessTokenSuccess">The access token containing response message.</param> - internal void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, AccessTokenSuccessResponse accessTokenSuccess) { - Contract.Requires<ArgumentNullException>(authorizationState != null, "authorizationState"); - Contract.Requires<ArgumentNullException>(accessTokenSuccess != null, "accessTokenSuccess"); + internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, AccessTokenSuccessResponse accessTokenSuccess) { + Contract.Requires<ArgumentNullException>(authorizationState != null); + Contract.Requires<ArgumentNullException>(accessTokenSuccess != null); authorizationState.AccessToken = accessTokenSuccess.AccessToken; authorizationState.RefreshToken = accessTokenSuccess.RefreshToken; @@ -165,9 +165,9 @@ namespace DotNetOpenAuth.OAuth2 { /// </summary> /// <param name="authorizationState">The authorization state maintained by the client.</param> /// <param name="accessTokenSuccess">The access token containing response message.</param> - internal void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess) { - Contract.Requires<ArgumentNullException>(authorizationState != null, "authorizationState"); - Contract.Requires<ArgumentNullException>(accessTokenSuccess != null, "accessTokenSuccess"); + internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess) { + Contract.Requires<ArgumentNullException>(authorizationState != null); + Contract.Requires<ArgumentNullException>(accessTokenSuccess != null); authorizationState.AccessToken = accessTokenSuccess.AccessToken; authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime; @@ -192,8 +192,8 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="authorizationState">The authorization state to update.</param> /// <param name="authorizationSuccess">The authorization success message obtained from the authorization server.</param> internal void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAuthCodeResponse authorizationSuccess) { - Contract.Requires<ArgumentNullException>(authorizationState != null, "authorizationState"); - Contract.Requires<ArgumentNullException>(authorizationSuccess != null, "authorizationSuccess"); + Contract.Requires<ArgumentNullException>(authorizationState != null); + Contract.Requires<ArgumentNullException>(authorizationSuccess != null); var accessTokenRequest = new AccessTokenAuthorizationCodeRequest(this.AuthorizationServer) { ClientIdentifier = this.ClientIdentifier, @@ -205,7 +205,7 @@ namespace DotNetOpenAuth.OAuth2 { var accessTokenSuccess = accessTokenResponse as AccessTokenSuccessResponse; var failedAccessTokenResponse = accessTokenResponse as AccessTokenFailedResponse; if (accessTokenSuccess != null) { - this.UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess); + UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess); } else { authorizationState.Delete(); string error = failedAccessTokenResponse != null ? failedAccessTokenResponse.Error : "(unknown)"; @@ -218,8 +218,8 @@ namespace DotNetOpenAuth.OAuth2 { /// </summary> /// <param name="authorization">The authorization to measure.</param> /// <returns>A fractional number no greater than 1. Could be negative if the access token has already expired.</returns> - private double ProportionalLifeRemaining(IAuthorizationState authorization) { - Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); + private static double ProportionalLifeRemaining(IAuthorizationState authorization) { + Contract.Requires<ArgumentNullException>(authorization != null); Contract.Requires<ArgumentException>(authorization.AccessTokenIssueDateUtc.HasValue); Contract.Requires<ArgumentException>(authorization.AccessTokenExpirationUtc.HasValue); diff --git a/src/DotNetOpenAuth/OAuth2/IAccessTokenAnalyzer.cs b/src/DotNetOpenAuth/OAuth2/IAccessTokenAnalyzer.cs index ed6cd63..74b8ebb 100644 --- a/src/DotNetOpenAuth/OAuth2/IAccessTokenAnalyzer.cs +++ b/src/DotNetOpenAuth/OAuth2/IAccessTokenAnalyzer.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OAuth2 { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Linq; using System.Text; @@ -26,6 +27,8 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="user">The user whose data is accessible with this access token.</param> /// <param name="scope">The scope of access authorized by this access token.</param> /// <returns>A value indicating whether this access token is valid.</returns> + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")] + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "Try pattern")] bool TryValidateAccessToken(IDirectedProtocolMessage message, string accessToken, out string user, out HashSet<string> scope); } @@ -51,7 +54,7 @@ namespace DotNetOpenAuth.OAuth2 { /// A value indicating whether this access token is valid. /// </returns> bool IAccessTokenAnalyzer.TryValidateAccessToken(IDirectedProtocolMessage message, string accessToken, out string user, out HashSet<string> scope) { - Contract.Requires<ArgumentNullException>(message != null, "message"); + Contract.Requires<ArgumentNullException>(message != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(accessToken)); Contract.Ensures(Contract.Result<bool>() == (Contract.ValueAtReturn<string>(out user) != null)); diff --git a/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs index d35373b..67fad8b 100644 --- a/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs +++ b/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs @@ -164,7 +164,7 @@ namespace DotNetOpenAuth.OAuth2 { /// account or piece of hardware in which the tokens were stored. </para> /// </remarks> bool IAuthorizationServer.IsAuthorizationValid(IAuthorizationDescription authorization) { - Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); + Contract.Requires<ArgumentNullException>(authorization != null); throw new NotImplementedException(); } } diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs index 28739a0..3c7202e 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs @@ -34,7 +34,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { internal AccessTokenAuthorizationCodeRequest(AuthorizationServerDescription authorizationServer) : this(authorizationServer.TokenEndpoint, authorizationServer.Version) { - Contract.Requires<ArgumentNullException>(authorizationServer != null, "authorizationServer"); + Contract.Requires<ArgumentNullException>(authorizationServer != null); } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs index 8708ca2..fc11831 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs @@ -35,7 +35,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <param name="request">The authorization request from the user agent on behalf of the client.</param> internal EndUserAuthorizationFailedResponse(Uri clientCallback, EndUserAuthorizationRequest request) : base(((IProtocolMessage)request).Version, MessageTransport.Indirect, clientCallback) { - Contract.Requires<ArgumentNullException>(request != null, "request"); + Contract.Requires<ArgumentNullException>(request != null); ((IMessageWithClientState)this).ClientState = request.ClientState; } diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs index 11d39d1..fa270ee 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationRequest.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using DotNetOpenAuth.Configuration; using DotNetOpenAuth.Messaging; @@ -46,11 +47,11 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <summary> /// Gets the grant type that the client expects of the authorization server. /// </summary> - /// <value>Always <see cref="EndUserAuthorizationResponseType.AuthorizationCode"/>. Other response types are not supported.</value> + /// <value>Always <see cref="EndUserAuthorizationResponseTypes.AuthorizationCode"/>. Other response types are not supported.</value> [MessagePart(Protocol.response_type, IsRequired = true, Encoder = typeof(EndUserAuthorizationResponseTypeEncoder))] - public EndUserAuthorizationResponseType ResponseType + public static EndUserAuthorizationResponseTypes ResponseType { - get { return EndUserAuthorizationResponseType.AuthorizationCode; } + get { return EndUserAuthorizationResponseTypes.AuthorizationCode; } } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs index 3afcae5..814f625 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationResponseType.cs @@ -12,7 +12,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// after the user has granted authorized access. /// </summary> [Flags] - public enum EndUserAuthorizationResponseType { + public enum EndUserAuthorizationResponseTypes { /// <summary> /// An access token should be returned immediately. /// </summary> diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs index 025cf84..46bbc87 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs @@ -38,8 +38,8 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <param name="request">The authorization request from the user agent on behalf of the client.</param> internal EndUserAuthorizationSuccessAccessTokenResponse(Uri clientCallback, EndUserAuthorizationRequest request) : base(clientCallback, request) { - Contract.Requires<ArgumentNullException>(clientCallback != null, "clientCallback"); - Contract.Requires<ArgumentNullException>(request != null, "request"); + Contract.Requires<ArgumentNullException>(clientCallback != null); + Contract.Requires<ArgumentNullException>(request != null); ((IMessageWithClientState)this).ClientState = request.ClientState; } diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs index d3748a9..6302304 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs @@ -35,8 +35,8 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <param name="request">The authorization request from the user agent on behalf of the client.</param> internal EndUserAuthorizationSuccessAuthCodeResponse(Uri clientCallback, EndUserAuthorizationRequest request) : base(clientCallback, request) { - Contract.Requires<ArgumentNullException>(clientCallback != null, "clientCallback"); - Contract.Requires<ArgumentNullException>(request != null, "request"); + Contract.Requires<ArgumentNullException>(clientCallback != null); + Contract.Requires<ArgumentNullException>(request != null); ((IMessageWithClientState)this).ClientState = request.ClientState; } diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs index f89dc9b..9b308c8 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs @@ -38,8 +38,8 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <param name="request">The authorization request from the user agent on behalf of the client.</param> internal EndUserAuthorizationSuccessResponseBase(Uri clientCallback, EndUserAuthorizationRequest request) : base(request, clientCallback) { - Contract.Requires<ArgumentNullException>(clientCallback != null, "clientCallback"); - Contract.Requires<ArgumentNullException>(request != null, "request"); + Contract.Requires<ArgumentNullException>(clientCallback != null); + Contract.Requires<ArgumentNullException>(request != null); ((IMessageWithClientState)this).ClientState = request.ClientState; this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer); } diff --git a/src/DotNetOpenAuth/OAuth2/Messages/MessageBase.cs b/src/DotNetOpenAuth/OAuth2/Messages/MessageBase.cs index 3233360..e390d6e 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/MessageBase.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/MessageBase.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using DotNetOpenAuth.Messaging; @@ -87,7 +88,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// Implementations of this interface should ensure that this property never returns null. /// </remarks> Version IMessage.Version { - get { return this.version; } + get { return this.Version; } } /// <summary> @@ -110,7 +111,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// </summary> /// <value><see cref="MessageProtections.None"/></value> MessageProtections IProtocolMessage.RequiredProtection { - get { return MessageProtections.None; } + get { return RequiredProtection; } } /// <summary> @@ -118,7 +119,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// </summary> /// <value></value> MessageTransport IProtocolMessage.Transport { - get { return this.messageTransport; } + get { return this.Transport; } } #endregion @@ -152,12 +153,33 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// Gets the originating request message that caused this response to be formed. /// </summary> IDirectedProtocolMessage IDirectResponseProtocolMessage.OriginatingRequest { - get { return this.originatingRequest; } + get { return this.OriginatingRequest; } } #endregion /// <summary> + /// Gets the level of protection this message requires. + /// </summary> + protected static MessageProtections RequiredProtection { + get { return MessageProtections.None; } + } + + /// <summary> + /// Gets a value indicating whether this is a direct or indirect message. + /// </summary> + protected MessageTransport Transport { + get { return this.messageTransport; } + } + + /// <summary> + /// Gets the version of the protocol or extension this message is prepared to implement. + /// </summary> + protected Version Version { + get { return this.version; } + } + + /// <summary> /// Gets or sets the preferred method of transport for the message. /// </summary> /// <remarks> @@ -168,6 +190,13 @@ namespace DotNetOpenAuth.OAuth2.Messages { protected HttpDeliveryMethods HttpMethods { get; set; } /// <summary> + /// Gets the originating request message that caused this response to be formed. + /// </summary> + protected IDirectedProtocolMessage OriginatingRequest { + get { return this.originatingRequest; } + } + + /// <summary> /// Gets the URL of the intended receiver of this message. /// </summary> protected Uri Recipient { get; private set; } diff --git a/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs index 0f12a8c..34da922 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/UnauthorizedResponse.cs @@ -23,7 +23,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <param name="version">The protocol version.</param> internal UnauthorizedResponse(ProtocolException exception, Version version = null) : base(version ?? Protocol.Default.Version) { - Contract.Requires<ArgumentNullException>(exception != null, "exception"); + Contract.Requires<ArgumentNullException>(exception != null); this.ErrorMessage = exception.Message; } @@ -43,7 +43,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <param name="exception">The exception.</param> internal UnauthorizedResponse(IDirectedProtocolMessage request, ProtocolException exception) : this(request) { - Contract.Requires<ArgumentNullException>(exception != null, "exception"); + Contract.Requires<ArgumentNullException>(exception != null); this.ErrorMessage = exception.Message; } diff --git a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs index 64a6d0c..74d5791 100644 --- a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs +++ b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs @@ -81,7 +81,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="scopes">The scopes to serialize.</param> /// <returns>A space-delimited list.</returns> public static string JoinScopes(HashSet<string> scopes) { - Contract.Requires<ArgumentNullException>(scopes != null, "scopes"); + Contract.Requires<ArgumentNullException>(scopes != null); return string.Join(" ", scopes.ToArray()); } diff --git a/src/DotNetOpenAuth/OAuth2/ResourceServer.cs b/src/DotNetOpenAuth/OAuth2/ResourceServer.cs index af9dcfd..a5baef0 100644 --- a/src/DotNetOpenAuth/OAuth2/ResourceServer.cs +++ b/src/DotNetOpenAuth/OAuth2/ResourceServer.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OAuth2 { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Linq; using System.Net; @@ -28,7 +29,7 @@ namespace DotNetOpenAuth.OAuth2 { /// </summary> /// <param name="accessTokenAnalyzer">The access token analyzer.</param> public ResourceServer(IAccessTokenAnalyzer accessTokenAnalyzer) { - Contract.Requires<ArgumentNullException>(accessTokenAnalyzer != null, "accessTokenAnalyzer"); + Contract.Requires<ArgumentNullException>(accessTokenAnalyzer != null); this.AccessTokenAnalyzer = accessTokenAnalyzer; this.Channel = new OAuth2ResourceServerChannel(); @@ -49,29 +50,33 @@ namespace DotNetOpenAuth.OAuth2 { /// <summary> /// Discovers what access the client should have considering the access token in the current request. /// </summary> - /// <param name="username">The name on the account the client has access to.</param> + /// <param name="userName">The name on the account the client has access to.</param> /// <param name="scope">The set of operations the client is authorized for.</param> /// <returns>An error to return to the client if access is not authorized; <c>null</c> if access is granted.</returns> - public OutgoingWebResponse VerifyAccess(out string username, out HashSet<string> scope) { - return this.VerifyAccess(this.Channel.GetRequestFromContext(), out username, out scope); + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#", Justification = "Try pattern")] + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")] + public OutgoingWebResponse VerifyAccess(out string userName, out HashSet<string> scope) { + return this.VerifyAccess(this.Channel.GetRequestFromContext(), out userName, out scope); } /// <summary> /// Discovers what access the client should have considering the access token in the current request. /// </summary> /// <param name="httpRequestInfo">The HTTP request info.</param> - /// <param name="username">The name on the account the client has access to.</param> + /// <param name="userName">The name on the account the client has access to.</param> /// <param name="scope">The set of operations the client is authorized for.</param> /// <returns> /// An error to return to the client if access is not authorized; <c>null</c> if access is granted. /// </returns> - public virtual OutgoingWebResponse VerifyAccess(HttpRequestInfo httpRequestInfo, out string username, out HashSet<string> scope) { - Contract.Requires<ArgumentNullException>(httpRequestInfo != null, "httpRequestInfo"); + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")] + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "Try pattern")] + public virtual OutgoingWebResponse VerifyAccess(HttpRequestInfo httpRequestInfo, out string userName, out HashSet<string> scope) { + Contract.Requires<ArgumentNullException>(httpRequestInfo != null); AccessProtectedResourceRequest request = null; try { if (this.Channel.TryReadFromRequest<AccessProtectedResourceRequest>(httpRequestInfo, out request)) { - if (this.AccessTokenAnalyzer.TryValidateAccessToken(request, request.AccessToken, out username, out scope)) { + if (this.AccessTokenAnalyzer.TryValidateAccessToken(request, request.AccessToken, out userName, out scope)) { // No errors to return. return null; } @@ -80,14 +85,14 @@ namespace DotNetOpenAuth.OAuth2 { } else { var response = new UnauthorizedResponse(new ProtocolException("Missing access token")); - username = null; + userName = null; scope = null; return this.Channel.PrepareResponse(response); } } catch (ProtocolException ex) { var response = request != null ? new UnauthorizedResponse(request, ex) : new UnauthorizedResponse(ex); - username = null; + userName = null; scope = null; return this.Channel.PrepareResponse(response); } @@ -101,6 +106,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <returns> /// An error to return to the client if access is not authorized; <c>null</c> if access is granted. /// </returns> + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")] public virtual OutgoingWebResponse VerifyAccess(HttpRequestInfo httpRequestInfo, out IPrincipal principal) { string username; HashSet<string> scope; @@ -118,9 +124,11 @@ namespace DotNetOpenAuth.OAuth2 { /// <returns> /// An error to return to the client if access is not authorized; <c>null</c> if access is granted. /// </returns> + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")] + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "Try pattern")] public virtual OutgoingWebResponse VerifyAccess(HttpRequestMessageProperty request, Uri requestUri, out IPrincipal principal) { - Contract.Requires<ArgumentNullException>(request != null, "request"); - Contract.Requires<ArgumentNullException>(requestUri != null, "requestUri"); + Contract.Requires<ArgumentNullException>(request != null); + Contract.Requires<ArgumentNullException>(requestUri != null); return this.VerifyAccess(new HttpRequestInfo(request, requestUri), out principal); } diff --git a/src/DotNetOpenAuth/OAuth2/StandardAccessTokenAnalyzer.cs b/src/DotNetOpenAuth/OAuth2/StandardAccessTokenAnalyzer.cs index ae52acf..1f59e52 100644 --- a/src/DotNetOpenAuth/OAuth2/StandardAccessTokenAnalyzer.cs +++ b/src/DotNetOpenAuth/OAuth2/StandardAccessTokenAnalyzer.cs @@ -22,8 +22,8 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="authorizationServerPublicSigningKey">The crypto service provider with the authorization server public signing key.</param> /// <param name="resourceServerPrivateEncryptionKey">The crypto service provider with the resource server private encryption key.</param> public StandardAccessTokenAnalyzer(RSACryptoServiceProvider authorizationServerPublicSigningKey, RSACryptoServiceProvider resourceServerPrivateEncryptionKey) { - Contract.Requires<ArgumentNullException>(authorizationServerPublicSigningKey != null, "authorizationServerPublicSigningKey"); - Contract.Requires<ArgumentNullException>(resourceServerPrivateEncryptionKey != null, "resourceServerPrivateEncryptionKey"); + Contract.Requires<ArgumentNullException>(authorizationServerPublicSigningKey != null); + Contract.Requires<ArgumentNullException>(resourceServerPrivateEncryptionKey != null); Contract.Requires<ArgumentException>(!resourceServerPrivateEncryptionKey.PublicOnly); this.AuthorizationServerPublicSigningKey = authorizationServerPublicSigningKey; this.ResourceServerPrivateEncryptionKey = resourceServerPrivateEncryptionKey; diff --git a/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs b/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs index 129102d..65c5898 100644 --- a/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs +++ b/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs @@ -34,7 +34,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="authorizationEndpoint">The authorization endpoint.</param> public UserAgentClient(Uri authorizationEndpoint) : base(new AuthorizationServerDescription { AuthorizationEndpoint = authorizationEndpoint }) { - Contract.Requires<ArgumentNullException>(authorizationEndpoint != null, "authorizationEndpoint"); + Contract.Requires<ArgumentNullException>(authorizationEndpoint != null); } /// <summary> @@ -55,7 +55,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="authorization">The authorization state that is tracking this particular request. Optional.</param> /// <returns>A fully-qualified URL suitable to initiate the authorization flow.</returns> public Uri RequestUserAuthorization(IAuthorizationState authorization) { - Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); + Contract.Requires<ArgumentNullException>(authorization != null); Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier)); if (authorization.Callback == null) { @@ -78,7 +78,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="authorizationState">The authorization.</param> /// <returns>The granted authorization, or <c>null</c> if the incoming HTTP request did not contain an authorization server response or authorization was rejected.</returns> public IAuthorizationState ProcessUserAuthorization(Uri actualRedirectUrl, IAuthorizationState authorizationState = null) { - Contract.Requires<ArgumentNullException>(actualRedirectUrl != null, "actualRedirectUrl"); + Contract.Requires<ArgumentNullException>(actualRedirectUrl != null); if (authorizationState == null) { authorizationState = new AuthorizationState(); @@ -94,7 +94,7 @@ namespace DotNetOpenAuth.OAuth2 { EndUserAuthorizationSuccessAuthCodeResponse authCodeSuccess; EndUserAuthorizationFailedResponse failure; if ((accessTokenSuccess = response as EndUserAuthorizationSuccessAccessTokenResponse) != null) { - this.UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess); + UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess); } else if ((authCodeSuccess = response as EndUserAuthorizationSuccessAuthCodeResponse) != null) { this.UpdateAuthorizationWithResponse(authorizationState, authCodeSuccess); } else if ((failure = response as EndUserAuthorizationFailedResponse) != null) { diff --git a/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs b/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs index 97a55c1..66ac276 100644 --- a/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs +++ b/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs @@ -35,11 +35,9 @@ namespace DotNetOpenAuth.OpenId.Behaviors { private static readonly TimeSpan MaximumAssociationLifetime = TimeSpan.FromSeconds(86400); /// <summary> - /// Initializes static members of the <see cref="GsaIcamProfile"/> class. + /// Backing field for the <see cref="DisableSslRequirement"/> static property. /// </summary> - static GsaIcamProfile() { - DisableSslRequirement = DotNetOpenAuthSection.Configuration.Messaging.RelaxSslRequirements; - } + private static bool disableSslRequirement = DotNetOpenAuthSection.Configuration.Messaging.RelaxSslRequirements; /// <summary> /// Initializes a new instance of the <see cref="GsaIcamProfile"/> class. @@ -65,7 +63,10 @@ namespace DotNetOpenAuth.OpenId.Behaviors { /// <summary> /// Gets or sets a value indicating whether to ignore the SSL requirement (for testing purposes only). /// </summary> - public static bool DisableSslRequirement { get; set; } + public static bool DisableSslRequirement { // not an auto-property because it has a default value, and FxCop doesn't want us using static constructors. + get { return disableSslRequirement; } + set { disableSslRequirement = value; } + } #region IRelyingPartyBehavior Members diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs index 6ff62a3..d9a0e50 100644 --- a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs @@ -63,7 +63,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// <param name="securitySettings">The security settings.</param> internal OpenIdChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings) : this(cryptoKeyStore, nonceStore, new OpenIdMessageFactory(), securitySettings) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); Contract.Requires<ArgumentNullException>(securitySettings != null); } @@ -93,7 +93,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// <param name="securitySettings">The security settings.</param> private OpenIdChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings) : this(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings)) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); Contract.Requires<ArgumentNullException>(messageTypeProvider != null); Contract.Requires<ArgumentNullException>(securitySettings != null); } @@ -365,9 +365,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// An array of binding elements which may be used to construct the channel. /// </returns> private static IChannelBindingElement[] InitializeBindingElements(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); Contract.Requires<ArgumentNullException>(securitySettings != null); - Contract.Requires<ArgumentNullException>(nonceStore != null, "nonceStore"); + Contract.Requires<ArgumentNullException>(nonceStore != null); SigningBindingElement signingElement; signingElement = new SigningBindingElement(cryptoKeyStore, securitySettings); diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs index 2e95436..30358e0 100644 --- a/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs @@ -198,8 +198,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { cryptoKey = this.cryptoKeyStore.GetKey(SecretUri.AbsoluteUri, returnToParameters[ReturnToSignatureHandleParameterName]); } - var signer = new HMACSHA256(cryptoKey.Key); - signature = signer.ComputeHash(bytesToSign); + using (var signer = new HMACSHA256(cryptoKey.Key)) { + signature = signer.ComputeHash(bytesToSign); + } } catch (ProtocolException ex) { throw ErrorUtilities.Wrap(ex, OpenIdStrings.MaximumAuthenticationTimeExpired); } diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs index e8ef531..e301a3e 100644 --- a/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs @@ -55,7 +55,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// <param name="associationStore">The association store used to look up the secrets needed for signing.</param> /// <param name="securitySettings">The security settings.</param> internal SigningBindingElement(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(associationStore != null, "associationStore"); + Contract.Requires<ArgumentNullException>(associationStore != null); Contract.Requires<ArgumentNullException>(securitySettings != null); this.opAssociations = associationStore; diff --git a/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs b/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs index 168960f..29da1be 100644 --- a/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs +++ b/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs @@ -155,7 +155,7 @@ namespace DotNetOpenAuth.OpenId { internal static HmacShaAssociation Create(Protocol protocol, string associationType, AssociationRelyingPartyType associationUse, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { Contract.Requires<ArgumentNullException>(protocol != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType)); - Contract.Requires<ArgumentNullException>(associationStore != null, "associationStore"); + Contract.Requires<ArgumentNullException>(associationStore != null); Contract.Requires<ArgumentNullException>(securitySettings != null); Contract.Ensures(Contract.Result<HmacShaAssociation>() != null); diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs index 04d566e..2a0dc7a 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs @@ -141,7 +141,7 @@ namespace DotNetOpenAuth.OpenId.Messages { /// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para> /// </remarks> internal IProtocolMessage CreateResponse(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(associationStore != null, "associationStore"); + Contract.Requires<ArgumentNullException>(associationStore != null); Contract.Requires<ArgumentNullException>(securitySettings != null); IProtocolMessage response; diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs index 134d980..d474608 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs @@ -17,7 +17,7 @@ namespace DotNetOpenAuth.OpenId.Messages { protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) { Contract.Requires<ArgumentNullException>(request != null); - Contract.Requires<ArgumentNullException>(associationStore != null, "associationStore"); + Contract.Requires<ArgumentNullException>(associationStore != null); Contract.Requires<ArgumentNullException>(securitySettings != null); throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs b/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs index a28a1be..68babd9 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs @@ -182,8 +182,8 @@ namespace DotNetOpenAuth.OpenId { /// <c>true</c> if the specified containing message is valid; otherwise, <c>false</c>. /// </returns> internal static bool IsValid(this IProviderAssociationStore associationStore, IProtocolMessage containingMessage, bool isPrivateAssociation, string handle) { - Contract.Requires<ArgumentNullException>(associationStore != null, "associationStore"); - Contract.Requires<ArgumentNullException>(containingMessage != null, "containingMessage"); + Contract.Requires<ArgumentNullException>(associationStore != null); + Contract.Requires<ArgumentNullException>(containingMessage != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle)); try { return associationStore.Deserialize(containingMessage, isPrivateAssociation, handle) != null; diff --git a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs index c5e6bba..974d729 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs @@ -31,7 +31,7 @@ namespace DotNetOpenAuth.OpenId.Provider { internal AnonymousRequest(OpenIdProvider provider, SignedResponseRequest request) : base(provider, request) { Contract.Requires<ArgumentNullException>(provider != null); - Contract.Requires<ArgumentException>(!(request is CheckIdRequest), "Instantiate AuthenticationRequest to handle this kind of message."); + Contract.Requires<ArgumentException>(!(request is CheckIdRequest)); this.positiveResponse = new IndirectSignedResponse(request); } diff --git a/src/DotNetOpenAuth/OpenId/Provider/AssociationDataBag.cs b/src/DotNetOpenAuth/OpenId/Provider/AssociationDataBag.cs index 72949d9..a8ac41e 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/AssociationDataBag.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/AssociationDataBag.cs @@ -86,7 +86,7 @@ namespace DotNetOpenAuth.OpenId.Provider { /// A formatter for serialization. /// </returns> internal static IDataBagFormatter<AssociationDataBag> CreateFormatter(ICryptoKeyStore cryptoKeyStore, string bucket, TimeSpan? minimumAge = null) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(bucket)); Contract.Ensures(Contract.Result<IDataBagFormatter<AssociationDataBag>>() != null); return new BinaryDataBagFormatter<AssociationDataBag>(cryptoKeyStore, bucket, signed: true, encrypted: true, minimumAge: minimumAge); diff --git a/src/DotNetOpenAuth/OpenId/Provider/IProviderAssociationStore.cs b/src/DotNetOpenAuth/OpenId/Provider/IProviderAssociationStore.cs index b63e2ee..5a554c1 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/IProviderAssociationStore.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/IProviderAssociationStore.cs @@ -41,13 +41,13 @@ namespace DotNetOpenAuth.OpenId.Provider { /// Retrieves an association given an association handle. /// </summary> /// <param name="containingMessage">The OpenID message that referenced this association handle.</param> - /// <param name="isPrivateAssociation">A value indicating whether a private association is expected.</param> + /// <param name="privateAssociation">A value indicating whether a private association is expected.</param> /// <param name="handle">The association handle.</param> /// <returns> /// An association instance, or <c>null</c> if the association has expired or the signature is incorrect (which may be because the OP's symmetric key has changed). /// </returns> /// <exception cref="ProtocolException">Thrown if the association is not of the expected type.</exception> - Association Deserialize(IProtocolMessage containingMessage, bool isPrivateAssociation, string handle); + Association Deserialize(IProtocolMessage containingMessage, bool privateAssociation, string handle); } /// <summary> @@ -60,11 +60,11 @@ namespace DotNetOpenAuth.OpenId.Provider { /// </summary> /// <param name="secret">The association secret.</param> /// <param name="expiresUtc">The expires UTC.</param> - /// <param name="isPrivateAssociation">A value indicating whether this is a private association.</param> + /// <param name="privateAssociation">A value indicating whether this is a private association.</param> /// <returns> /// The association handle that represents this association. /// </returns> - string IProviderAssociationStore.Serialize(byte[] secret, DateTime expiresUtc, bool isPrivateAssociation) { + string IProviderAssociationStore.Serialize(byte[] secret, DateTime expiresUtc, bool privateAssociation) { Contract.Requires<ArgumentNullException>(secret != null); Contract.Requires<ArgumentException>(expiresUtc.Kind == DateTimeKind.Utc); Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>())); @@ -75,14 +75,14 @@ namespace DotNetOpenAuth.OpenId.Provider { /// Retrieves an association given an association handle. /// </summary> /// <param name="containingMessage">The OpenID message that referenced this association handle.</param> - /// <param name="isPrivateAssociation">A value indicating whether a private association is expected.</param> + /// <param name="privateAssociation">A value indicating whether a private association is expected.</param> /// <param name="handle">The association handle.</param> /// <returns> /// An association instance, or <c>null</c> if the association has expired or the signature is incorrect (which may be because the OP's symmetric key has changed). /// </returns> /// <exception cref="ProtocolException">Thrown if the association is not of the expected type.</exception> - Association IProviderAssociationStore.Deserialize(IProtocolMessage containingMessage, bool isPrivateAssociation, string handle) { - Contract.Requires<ArgumentNullException>(containingMessage != null, "containingMessage"); + Association IProviderAssociationStore.Deserialize(IProtocolMessage containingMessage, bool privateAssociation, string handle) { + Contract.Requires<ArgumentNullException>(containingMessage != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle)); throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs index 4a52728..1c065b2 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs @@ -76,8 +76,8 @@ namespace DotNetOpenAuth.OpenId.Provider { /// <param name="nonceStore">The nonce store to use. Cannot be null.</param> /// <param name="cryptoKeyStore">The crypto key store. Cannot be null.</param> private OpenIdProvider(INonceStore nonceStore, ICryptoKeyStore cryptoKeyStore) { - Contract.Requires<ArgumentNullException>(nonceStore != null, "nonceStore"); - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "associationStore"); + Contract.Requires<ArgumentNullException>(nonceStore != null); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); Contract.Ensures(this.SecuritySettings != null); Contract.Ensures(this.Channel != null); @@ -594,8 +594,8 @@ namespace DotNetOpenAuth.OpenId.Provider { /// <param name="cryptoKeyStore">The crypto key store.</param> /// <param name="securitySettings">The security settings.</param> internal SwitchingAssociationStore(ICryptoKeyStore cryptoKeyStore, ProviderSecuritySettings securitySettings) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); - Contract.Requires<ArgumentNullException>(securitySettings != null, "securitySettings"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); + Contract.Requires<ArgumentNullException>(securitySettings != null); this.securitySettings = securitySettings; this.associationHandleEncoder = new ProviderAssociationHandleEncoder(cryptoKeyStore); diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationHandleEncoder.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationHandleEncoder.cs index 73d8b56..5de560c 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationHandleEncoder.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationHandleEncoder.cs @@ -32,7 +32,7 @@ namespace DotNetOpenAuth.OpenId.Provider { /// </summary> /// <param name="cryptoKeyStore">The crypto key store.</param> public ProviderAssociationHandleEncoder(ICryptoKeyStore cryptoKeyStore) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); this.cryptoKeyStore = cryptoKeyStore; } @@ -41,14 +41,14 @@ namespace DotNetOpenAuth.OpenId.Provider { /// </summary> /// <param name="secret">The symmetric secret.</param> /// <param name="expiresUtc">The UTC time that the association should expire.</param> - /// <param name="isPrivateAssociation">A value indicating whether this is a private association.</param> + /// <param name="privateAssociation">A value indicating whether this is a private association.</param> /// <returns> /// The association handle that represents this association. /// </returns> - public string Serialize(byte[] secret, DateTime expiresUtc, bool isPrivateAssociation) { + public string Serialize(byte[] secret, DateTime expiresUtc, bool privateAssociation) { var associationDataBag = new AssociationDataBag { Secret = secret, - IsPrivateAssociation = isPrivateAssociation, + IsPrivateAssociation = privateAssociation, ExpiresUtc = expiresUtc, }; @@ -60,13 +60,13 @@ namespace DotNetOpenAuth.OpenId.Provider { /// Retrieves an association given an association handle. /// </summary> /// <param name="containingMessage">The OpenID message that referenced this association handle.</param> - /// <param name="isPrivateAssociation">A value indicating whether a private association is expected.</param> + /// <param name="privateAssociation">A value indicating whether a private association is expected.</param> /// <param name="handle">The association handle.</param> /// <returns> /// An association instance, or <c>null</c> if the association has expired or the signature is incorrect (which may be because the OP's symmetric key has changed). /// </returns> /// <exception cref="ProtocolException">Thrown if the association is not of the expected type.</exception> - public Association Deserialize(IProtocolMessage containingMessage, bool isPrivateAssociation, string handle) { + public Association Deserialize(IProtocolMessage containingMessage, bool privateAssociation, string handle) { var formatter = AssociationDataBag.CreateFormatter(this.cryptoKeyStore, AssociationHandleEncodingSecretBucket); AssociationDataBag bag; try { @@ -76,7 +76,7 @@ namespace DotNetOpenAuth.OpenId.Provider { return null; } - ErrorUtilities.VerifyProtocol(bag.IsPrivateAssociation == isPrivateAssociation, "Unexpected association type."); + ErrorUtilities.VerifyProtocol(bag.IsPrivateAssociation == privateAssociation, "Unexpected association type."); Association assoc = Association.Deserialize(handle, bag.ExpiresUtc, bag.Secret); return assoc.IsExpired ? null : assoc; } diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationKeyStorage.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationKeyStorage.cs index 105e27b..64ef6e5 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationKeyStorage.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderAssociationKeyStorage.cs @@ -35,7 +35,7 @@ namespace DotNetOpenAuth.OpenId.Provider { /// </summary> /// <param name="cryptoKeyStore">The store where association secrets will be recorded.</param> internal ProviderAssociationKeyStorage(ICryptoKeyStore cryptoKeyStore) { - Contract.Requires<ArgumentNullException>(cryptoKeyStore != null, "cryptoKeyStore"); + Contract.Requires<ArgumentNullException>(cryptoKeyStore != null); this.cryptoKeyStore = cryptoKeyStore; } diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs index 4cc4e9e..02ed3b0 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/CryptoKeyStoreAsRelyingPartyAssociationStore.cs @@ -24,7 +24,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </summary> /// <param name="keyStore">The key store.</param> internal CryptoKeyStoreAsRelyingPartyAssociationStore(ICryptoKeyStore keyStore) { - Contract.Requires<ArgumentNullException>(keyStore != null, "keyStore"); + Contract.Requires<ArgumentNullException>(keyStore != null); Contract.Ensures(this.keyStore == keyStore); this.keyStore = keyStore; } |