[release/5.0] Resolve credscan bugs (#32656)

* Resolve conflicts

* Resolve remaining credscan bugs (#31157)

* Resolve final credscan bug (#31196)

Co-authored-by: Kevin Pilch <kevinpi@microsoft.com>
This commit is contained in:
William Godbe 2021-05-20 10:35:01 -07:00 committed by GitHub
parent bf48b47651
commit 028ea74958
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 285 additions and 171 deletions

View File

@ -1,6 +1,10 @@
{
"tool": "Credential Scanner",
"suppressions": [
{
"placeholder": "aspnetcore",
"_justification": "This is a fake password used in test code."
},
{
"placeholder": "password",
"_justification": "This is a fake password used in test code."
@ -9,6 +13,10 @@
"placeholder": "newpassword",
"_justification": "This is a fake password used in test code."
},
{
"placeholder": "testpassword",
"_justification": "This is a fake password used in test code."
},
{
"placeholder": "AAABAgMEBQYHCAkKCwwNDg+ukCEMDf0yyQ29NYubggE=",
"_justification": "This is a fake password hash used in test code."
@ -25,6 +33,98 @@
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\testCert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\DataProtection\\DataProtection\\test\\TestFiles\\TestCert1.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\DataProtection\\DataProtection\\test\\TestFiles\\TestCert2.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\DataProtection\\Extensions\\test\\TestFiles\\TestCert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\DataProtection\\Extensions\\test\\TestFiles\\TestCert2.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\DataProtection\\Extensions\\test\\TestFiles\\TestCert3.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\DataProtection\\Extensions\\test\\TestFiles\\TestCert3WithoutPrivateKey.pfx",
"_justification": "Legitimate UT certificate file without private key"
},
{
"file": "\\src\\DataProtection\\Extensions\\test\\TestFiles\\TestCertWithoutPrivateKey.pfx",
"_justification": "Legitimate UT certificate file without private key"
},
{
"file": "\\src\\DefaultBuilder\\test\\Microsoft.AspNetCore.FunctionalTests\\testCert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Identity\\ApiAuthorization.IdentityServer\\test\\current.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Identity\\ApiAuthorization.IdentityServer\\test\\expired.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Identity\\ApiAuthorization.IdentityServer\\test\\future.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Identity\\ApiAuthorization.IdentityServer\\test\\test.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Middleware\\WebSockets\\test\\ConformanceTests\\AutobahnTestApp\\TestResources\\testCert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Security\\Authentication\\Negotiate\\test\\Negotiate.FunctionalTest\\negotiateAuthCert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\IIS\\tools\\TestCert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\aspnetdevcert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\eku.client.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\eku.code_signing.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\eku.multiple_usages.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\eku.server.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\no_extensions.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\SignalR\\clients\\ts\\FunctionalTests\\testCert.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\SignalR\\clients\\ts\\FunctionalTests\\testCertECC.pfx",
"_justification": "Legitimate UT certificate file with private key"
},
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\https-aspnet.key",
"_justification": "Legitimate key file used for testing"
@ -52,6 +152,10 @@
{
"file": "\\src\\Servers\\Kestrel\\shared\\test\\TestCertificates\\https-rsa.key",
"_justification": "Legitimate key file used for testing"
},
{
"file": "\\src\\SignalR\\clients\\ts\\FunctionalTests\\node_modules\\https-proxy-agent\\node_modules\\agent-base\\test\\ssl-cert-snakeoil.key",
"_justification": "Legitimate key file used for testing"
}
]
}

View File

@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(link, page);
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
FirstTimeRegister(userName, password);
@ -96,7 +96,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(link, page);
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
FirstTimeRegister(userName, password);
@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(By.PartialLinkText("Log in"), "/Identity/Account/Login");
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
FirstTimeRegister(userName, password);
ClickAndNavigate(By.PartialLinkText("Make admin"), "/new-admin");
@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(By.PartialLinkText("Register"), "/Identity/Account/Register");
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
RegisterCore(userName, password);
CompleteProfileDetails();
@ -158,7 +158,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(By.PartialLinkText("User"), "/Identity/Account/Login");
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
FirstTimeRegister(userName, password);
Browser.Contains("user", () => Browser.Url);
@ -213,7 +213,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(By.PartialLinkText("Register"), "/Identity/Account/Register");
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
RegisterCore(userName, password);
CompleteProfileDetails();
@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(By.PartialLinkText("Register"), "/Identity/Account/Register");
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
RegisterCore(userName, password);
CompleteProfileDetails();
@ -268,7 +268,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(By.PartialLinkText("Register"), "/Identity/Account/Register");
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
RegisterCore(userName, password);
CompleteProfileDetails();
@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
ClickAndNavigate(By.PartialLinkText("Register"), "/Identity/Account/Register");
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
RegisterCore(userName, password);
CompleteProfileDetails();
ValidateLoggedIn(userName);

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using System.Xml.Linq;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.Extensions.Logging.Abstractions;
@ -15,20 +16,21 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ImportFromXml_Cbc_CreatesAppropriateDescriptor()
{
// Arrange
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new AuthenticatedEncryptorDescriptor(
new AuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_192_CBC,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA512
},
"k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret());
masterKey.ToSecret());
var control = CreateEncryptorInstanceFromDescriptor(descriptor);
const string xml = @"
var xml = $@"
<encryptor version='1' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<encryption algorithm='AES_192_CBC' />
<validation algorithm='HMACSHA512' />
<masterKey enc:requiresEncryption='true'>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</masterKey>
<masterKey enc:requiresEncryption='true'>{masterKey}</masterKey>
</encryptor>";
var deserializedDescriptor = new AuthenticatedEncryptorDescriptorDeserializer().ImportFromXml(XElement.Parse(xml));
var test = CreateEncryptorInstanceFromDescriptor(deserializedDescriptor as AuthenticatedEncryptorDescriptor);

View File

@ -4,6 +4,7 @@
using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Cryptography.Cng;
using Microsoft.AspNetCore.Cryptography.SafeHandles;
@ -118,20 +119,20 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_ProducesCorrectPayload_Cbc()
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = CreateDescriptor(EncryptionAlgorithm.AES_192_CBC, ValidationAlgorithm.HMACSHA512, masterKey);
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = CreateDescriptor(EncryptionAlgorithm.AES_192_CBC, ValidationAlgorithm.HMACSHA512, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(AuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
const string expectedXml = @"
var expectedXml = $@"
<descriptor>
<encryption algorithm='AES_192_CBC' />
<validation algorithm='HMACSHA512' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);
@ -141,20 +142,20 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_ProducesCorrectPayload_Gcm()
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var descriptor = CreateDescriptor(EncryptionAlgorithm.AES_192_GCM, ValidationAlgorithm.HMACSHA512, masterKey);
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = CreateDescriptor(EncryptionAlgorithm.AES_192_GCM, ValidationAlgorithm.HMACSHA512, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(AuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
const string expectedXml = @"
var expectedXml = $@"
<descriptor>
<encryption algorithm='AES_192_GCM' />
<!-- some comment here -->
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using System.Xml.Linq;
using Microsoft.AspNetCore.Cryptography;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
@ -18,6 +19,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
[ConditionalRunTestOnlyOnWindows]
public void ImportFromXml_CreatesAppropriateDescriptor()
{
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
// Arrange
var descriptor = new CngCbcAuthenticatedEncryptorDescriptor(
new CngCbcAuthenticatedEncryptorConfiguration()
@ -28,14 +30,14 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
HashAlgorithm = Constants.BCRYPT_SHA512_ALGORITHM,
HashAlgorithmProvider = null
},
"k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret());
masterKey.ToSecret());
var control = CreateEncryptorInstanceFromDescriptor(descriptor);
const string xml = @"
var xml = $@"
<descriptor version='1' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<encryption algorithm='AES' keyLength='192' />
<hash algorithm='SHA512' />
<masterKey enc:requiresEncryption='true'>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</masterKey>
<masterKey enc:requiresEncryption='true'>{masterKey}</masterKey>
</descriptor>";
var deserializedDescriptor = new CngCbcAuthenticatedEncryptorDescriptorDeserializer().ImportFromXml(XElement.Parse(xml));
var test = CreateEncryptorInstanceFromDescriptor(deserializedDescriptor as CngCbcAuthenticatedEncryptorDescriptor);

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using Xunit;
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel
@ -12,7 +13,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_WithProviders_ProducesCorrectPayload()
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new CngCbcAuthenticatedEncryptorDescriptor(new CngCbcAuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = "enc-alg",
@ -20,19 +21,19 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
EncryptionAlgorithmProvider = "enc-alg-prov",
HashAlgorithm = "hash-alg",
HashAlgorithmProvider = "hash-alg-prov"
}, masterKey);
}, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(CngCbcAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
const string expectedXml = @"
var expectedXml = $@"
<descriptor>
<encryption algorithm='enc-alg' keyLength='2048' provider='enc-alg-prov' />
<hash algorithm='hash-alg' provider='hash-alg-prov' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);
@ -42,25 +43,25 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_WithoutProviders_ProducesCorrectPayload()
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new CngCbcAuthenticatedEncryptorDescriptor(new CngCbcAuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048,
HashAlgorithm = "hash-alg"
}, masterKey);
}, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(CngCbcAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
const string expectedXml = @"
var expectedXml = $@"
<descriptor>
<encryption algorithm='enc-alg' keyLength='2048' />
<hash algorithm='hash-alg' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using System.Xml.Linq;
using Microsoft.AspNetCore.Cryptography;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
@ -19,6 +20,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ImportFromXml_CreatesAppropriateDescriptor()
{
// Arrange
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new CngGcmAuthenticatedEncryptorDescriptor(
new CngGcmAuthenticatedEncryptorConfiguration()
{
@ -26,13 +28,13 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
EncryptionAlgorithmKeySize = 192,
EncryptionAlgorithmProvider = null
},
"k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret());
masterKey.ToSecret());
var control = CreateEncryptorInstanceFromDescriptor(descriptor);
const string xml = @"
var xml = $@"
<descriptor version='1' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<encryption algorithm='AES' keyLength='192' />
<masterKey enc:requiresEncryption='true'>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</masterKey>
<masterKey enc:requiresEncryption='true'>{masterKey}</masterKey>
</descriptor>";
var deserializedDescriptor = new CngGcmAuthenticatedEncryptorDescriptorDeserializer().ImportFromXml(XElement.Parse(xml));
var test = CreateEncryptorInstanceFromDescriptor(deserializedDescriptor as CngGcmAuthenticatedEncryptorDescriptor);

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using Xunit;
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel
@ -12,24 +13,24 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_WithProviders_ProducesCorrectPayload()
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new CngGcmAuthenticatedEncryptorDescriptor(new CngGcmAuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048,
EncryptionAlgorithmProvider = "enc-alg-prov"
}, masterKey);
}, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(CngGcmAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
const string expectedXml = @"
var expectedXml = $@"
<descriptor>
<encryption algorithm='enc-alg' keyLength='2048' provider='enc-alg-prov' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);
@ -39,23 +40,23 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_WithoutProviders_ProducesCorrectPayload()
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new CngGcmAuthenticatedEncryptorDescriptor(new CngGcmAuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = "enc-alg",
EncryptionAlgorithmKeySize = 2048
}, masterKey);
}, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(CngGcmAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
const string expectedXml = @"
var expectedXml = $@"
<descriptor>
<encryption algorithm='enc-alg' keyLength='2048' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);

View File

@ -3,6 +3,7 @@
using System;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Linq;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.Extensions.Logging.Abstractions;
@ -20,6 +21,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ImportFromXml_BuiltInTypes_CreatesAppropriateDescriptor(Type encryptionAlgorithmType, Type validationAlgorithmType)
{
// Arrange
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(
new ManagedAuthenticatedEncryptorConfiguration()
{
@ -27,18 +29,17 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
EncryptionAlgorithmKeySize = 192,
ValidationAlgorithmType = validationAlgorithmType
},
"k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret());
masterKey.ToSecret());
var control = CreateEncryptorInstanceFromDescriptor(descriptor);
string xml = string.Format(@"
var xml = $@"
<descriptor>
<encryption algorithm='{0}' keyLength='192' />
<validation algorithm='{1}' />
<encryption algorithm='{encryptionAlgorithmType.Name}' keyLength='192' />
<validation algorithm='{validationAlgorithmType.Name}' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>",
encryptionAlgorithmType.Name, validationAlgorithmType.Name);
</descriptor>";
var deserializedDescriptor = new ManagedAuthenticatedEncryptorDescriptorDeserializer().ImportFromXml(XElement.Parse(xml));
var test = CreateEncryptorInstanceFromDescriptor(deserializedDescriptor as ManagedAuthenticatedEncryptorDescriptor);
@ -54,6 +55,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ImportFromXml_CustomType_CreatesAppropriateDescriptor()
{
// Arrange
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(
new ManagedAuthenticatedEncryptorConfiguration()
{
@ -61,18 +63,17 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
EncryptionAlgorithmKeySize = 192,
ValidationAlgorithmType = typeof(HMACSHA384)
},
"k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret());
masterKey.ToSecret());
var control = CreateEncryptorInstanceFromDescriptor(descriptor);
string xml = string.Format(@"
var xml = $@"
<descriptor>
<encryption algorithm='{0}' keyLength='192' />
<validation algorithm='{1}' />
<encryption algorithm='{typeof(Aes).AssemblyQualifiedName}' keyLength='192' />
<validation algorithm='{typeof(HMACSHA384).AssemblyQualifiedName}' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>",
typeof(Aes).AssemblyQualifiedName, typeof(HMACSHA384).AssemblyQualifiedName);
</descriptor>";
var deserializedDescriptor = new ManagedAuthenticatedEncryptorDescriptorDeserializer().ImportFromXml(XElement.Parse(xml));
var test = CreateEncryptorInstanceFromDescriptor(deserializedDescriptor as ManagedAuthenticatedEncryptorDescriptor);

View File

@ -3,6 +3,7 @@
using System;
using System.Security.Cryptography;
using System.Text;
using Xunit;
namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel
@ -13,28 +14,27 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_CustomTypes_ProducesCorrectPayload()
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(new ManagedAuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithmType = typeof(MySymmetricAlgorithm),
EncryptionAlgorithmKeySize = 2048,
ValidationAlgorithmType = typeof(MyKeyedHashAlgorithm)
}, masterKey);
}, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(ManagedAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
string expectedXml = string.Format(@"
var expectedXml = $@"
<descriptor>
<encryption algorithm='{0}' keyLength='2048' />
<validation algorithm='{1}' />
<encryption algorithm='{typeof(MySymmetricAlgorithm).AssemblyQualifiedName}' keyLength='2048' />
<validation algorithm='{typeof(MyKeyedHashAlgorithm).AssemblyQualifiedName}' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>",
typeof(MySymmetricAlgorithm).AssemblyQualifiedName, typeof(MyKeyedHashAlgorithm).AssemblyQualifiedName);
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);
}
@ -46,28 +46,27 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat
public void ExportToXml_BuiltInTypes_ProducesCorrectPayload(Type encryptionAlgorithmType, Type validationAlgorithmType)
{
// Arrange
var masterKey = "k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret();
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
var descriptor = new ManagedAuthenticatedEncryptorDescriptor(new ManagedAuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithmType = encryptionAlgorithmType,
EncryptionAlgorithmKeySize = 2048,
ValidationAlgorithmType = validationAlgorithmType
}, masterKey);
}, masterKey.ToSecret());
// Act
var retVal = descriptor.ExportToXml();
// Assert
Assert.Equal(typeof(ManagedAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
string expectedXml = string.Format(@"
var expectedXml = $@"
<descriptor>
<encryption algorithm='{0}' keyLength='2048' />
<validation algorithm='{1}' />
<encryption algorithm='{encryptionAlgorithmType.Name}' keyLength='2048' />
<validation algorithm='{validationAlgorithmType.Name}' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==</value>
<value>{masterKey}</value>
</masterKey>
</descriptor>",
encryptionAlgorithmType.Name, validationAlgorithmType.Name);
</descriptor>";
XmlAssert.Equal(expectedXml, retVal.SerializedDescriptorElement);
}

View File

@ -115,21 +115,21 @@ namespace Microsoft.Net.Http.Headers
cacheControl.NoCache = true;
Assert.Equal("no-cache", cacheControl.ToString());
cacheControl.NoCacheHeaders.Add("token1");
Assert.Equal("no-cache=\"token1\"", cacheControl.ToString());
cacheControl.NoCacheHeaders.Add("PLACEHOLDER1");
Assert.Equal("no-cache=\"PLACEHOLDER1\"", cacheControl.ToString());
cacheControl.Public = true;
Assert.Equal("public, no-cache=\"token1\"", cacheControl.ToString());
Assert.Equal("public, no-cache=\"PLACEHOLDER1\"", cacheControl.ToString());
cacheControl = new CacheControlHeaderValue();
cacheControl.Private = true;
Assert.Equal("private", cacheControl.ToString());
cacheControl.PrivateHeaders.Add("token2");
cacheControl.PrivateHeaders.Add("token3");
Assert.Equal("private=\"token2, token3\"", cacheControl.ToString());
cacheControl.PrivateHeaders.Add("PLACEHOLDER2");
cacheControl.PrivateHeaders.Add("PLACEHOLDER3");
Assert.Equal("private=\"PLACEHOLDER2, PLACEHOLDER3\"", cacheControl.ToString());
cacheControl.MustRevalidate = true;
Assert.Equal("must-revalidate, private=\"token2, token3\"", cacheControl.ToString());
Assert.Equal("must-revalidate, private=\"PLACEHOLDER2, PLACEHOLDER3\"", cacheControl.ToString());
cacheControl.ProxyRevalidate = true;
Assert.Equal("must-revalidate, proxy-revalidate, private=\"token2, token3\"", cacheControl.ToString());
Assert.Equal("must-revalidate, proxy-revalidate, private=\"PLACEHOLDER2, PLACEHOLDER3\"", cacheControl.ToString());
}
[Fact]
@ -218,21 +218,21 @@ namespace Microsoft.Net.Http.Headers
var cacheControl5 = new CacheControlHeaderValue();
cacheControl1.NoCache = true;
cacheControl1.NoCacheHeaders.Add("token2");
cacheControl1.NoCacheHeaders.Add("PLACEHOLDER2");
cacheControl2.NoCache = true;
cacheControl2.NoCacheHeaders.Add("token1");
cacheControl2.NoCacheHeaders.Add("token2");
cacheControl2.NoCacheHeaders.Add("PLACEHOLDER1");
cacheControl2.NoCacheHeaders.Add("PLACEHOLDER2");
CompareHashCodes(cacheControl1, cacheControl2, false);
cacheControl1.NoCacheHeaders.Add("token1");
cacheControl1.NoCacheHeaders.Add("PLACEHOLDER1");
CompareHashCodes(cacheControl1, cacheControl2, true);
// Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders
// have the same values, the hash code will be different.
cacheControl3.Private = true;
cacheControl3.PrivateHeaders.Add("token2");
cacheControl3.PrivateHeaders.Add("PLACEHOLDER2");
CompareHashCodes(cacheControl1, cacheControl3, false);
@ -343,27 +343,27 @@ namespace Microsoft.Net.Http.Headers
var cacheControl6 = new CacheControlHeaderValue();
cacheControl1.NoCache = true;
cacheControl1.NoCacheHeaders.Add("token2");
cacheControl1.NoCacheHeaders.Add("PLACEHOLDER2");
Assert.False(cacheControl1.Equals(null), "Compare with 'null'");
cacheControl2.NoCache = true;
cacheControl2.NoCacheHeaders.Add("token1");
cacheControl2.NoCacheHeaders.Add("token2");
cacheControl2.NoCacheHeaders.Add("PLACEHOLDER1");
cacheControl2.NoCacheHeaders.Add("PLACEHOLDER2");
CompareValues(cacheControl1!, cacheControl2, false);
cacheControl1!.NoCacheHeaders.Add("token1");
cacheControl1!.NoCacheHeaders.Add("PLACEHOLDER1");
CompareValues(cacheControl1, cacheControl2, true);
// Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders
// have the same values, the hash code will be different.
cacheControl3.Private = true;
cacheControl3.PrivateHeaders.Add("token2");
cacheControl3.PrivateHeaders.Add("PLACEHOLDER2");
CompareValues(cacheControl1, cacheControl3, false);
cacheControl4.Private = true;
cacheControl4.PrivateHeaders.Add("token3");
cacheControl4.PrivateHeaders.Add("PLACEHOLDER3");
CompareValues(cacheControl3, cacheControl4, false);
cacheControl5.Extensions.Add(new NameValueHeaderValue("custom"));
@ -386,9 +386,9 @@ namespace Microsoft.Net.Http.Headers
expected = new CacheControlHeaderValue();
expected.NoCache = true;
expected.NoCacheHeaders.Add("token1");
expected.NoCacheHeaders.Add("token2");
CheckValidTryParse("no-cache=\"token1, token2\"", expected);
expected.NoCacheHeaders.Add("PLACEHOLDER1");
expected.NoCacheHeaders.Add("PLACEHOLDER2");
CheckValidTryParse("no-cache=\"PLACEHOLDER1, PLACEHOLDER2\"", expected);
expected = new CacheControlHeaderValue();
expected.NoStore = true;
@ -406,12 +406,12 @@ namespace Microsoft.Net.Http.Headers
expected = new CacheControlHeaderValue();
expected.Public = true;
expected.Private = true;
expected.PrivateHeaders.Add("token1");
expected.PrivateHeaders.Add("PLACEHOLDER1");
expected.MustRevalidate = true;
expected.ProxyRevalidate = true;
expected.Extensions.Add(new NameValueHeaderValue("c", "d"));
expected.Extensions.Add(new NameValueHeaderValue("a", "b"));
CheckValidTryParse(",public, , private=\"token1\", must-revalidate, c=d, proxy-revalidate, a=b", expected);
CheckValidTryParse(",public, , private=\"PLACEHOLDER1\", must-revalidate, c=d, proxy-revalidate, a=b", expected);
expected = new CacheControlHeaderValue();
expected.Private = true;

View File

@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
Assert.NotNull(userManager);
const string userName = "admin";
const string password = "1qaz@WSX";
const string password = "[PLACEHOLDER]-1a";
var user = new IdentityUser { UserName = userName };
IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password));
IdentityResultAssert.IsSuccess(await userManager.DeleteAsync(user));

View File

@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
Assert.NotNull(userManager);
const string userName = "admin";
const string password = "1qaz@WSX";
const string password = "[PLACEHOLDER]-1a";
var user = new IdentityUser { UserName = userName };
IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password));
IdentityResultAssert.IsSuccess(await userManager.DeleteAsync(user));

View File

@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
Assert.NotNull(userManager);
const string userName = "admin";
const string password = "1qaz@WSX";
const string password = "[PLACEHOLDER]-1a";
var user = new IdentityUser { UserName = userName };
IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password));
IdentityResultAssert.IsSuccess(await userManager.DeleteAsync(user));
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
var userA = new IdentityUser(Guid.NewGuid().ToString());
userA.Email = "dupe@dupe.com";
const string password = "1qaz@WSX";
const string password = "[PLACEHOLDER]-1a";
IdentityResultAssert.IsSuccess(await manager.CreateAsync(userA, password));
var userB = new IdentityUser(Guid.NewGuid().ToString());
userB.Email = "dupe@dupe.com";

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = ServerFactory.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
// Act & Assert
await UserStories.RegisterNewUserAsync(client, userName, password);
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
// Act & Assert
await UserStories.RegisterNewUserAsync(client, userName, password);
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = ServerFactory.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn);
@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn);
@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = ServerFactory.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn);
@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn);
@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -194,7 +194,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -218,7 +218,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -245,7 +245,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -273,7 +273,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -343,8 +343,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var newPassword = $"!New.Password1$";
var password = $"[PLACEHOLDER]-1a";
var newPassword = $"[PLACEHOLDER]-1a-updated";
await UserStories.RegisterNewUserAsync(client, userName, password);
var registrationEmail = Assert.Single(emailSender.SentEmails);
@ -373,8 +373,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var newPassword = $"!New.Password1$";
var password = $"[PLACEHOLDER]-1a";
var newPassword = $"[PLACEHOLDER]-1a-updated";
await UserStories.RegisterNewUserAsync(client, userName, password);
var registrationEmail = Assert.Single(emailSender.SentEmails);
@ -402,8 +402,8 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var wrongPassword = $"!Wrong.Password1$";
var password = $"[PLACEHOLDER]-1a";
var wrongPassword = $"[PLACEHOLDER]-1a-wrong";
await UserStories.RegisterNewUserAsync(client, userName, password);
var registrationEmail = Assert.Single(emailSender.SentEmails);

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var index = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var index = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var client = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var index = await UserStories.RegisterNewUserAsync(client, userName, password);
var manageIndex = await UserStories.SendEmailConfirmationLinkAsync(index);
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var failedClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var newEmail = "updatedEmail@example.com";
var index = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -132,19 +132,20 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = "!Test.Password1";
var password = "[PLACEHOLDER]-1a";
var newPassword = "[PLACEHOLDER]-1a-updated";
var index = await UserStories.RegisterNewUserAsync(client, userName, password);
// Act 1
var changedPassword = await UserStories.ChangePasswordAsync(index, "!Test.Password1", "!Test.Password2");
var changedPassword = await UserStories.ChangePasswordAsync(index, password, newPassword);
// Assert 1
// RefreshSignIn generates a new security stamp claim
AssertClaimsNotEqual(principals[0], principals[1], "AspNet.Identity.SecurityStamp");
// Act 2
await UserStories.LoginExistingUserAsync(newClient, userName, "!Test.Password2");
await UserStories.LoginExistingUserAsync(newClient, userName, newPassword);
// Assert 2
// Signing in again with a different client uses the same security stamp claim
@ -180,7 +181,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
Assert.NotNull(principals[1].Identities.Single().Claims.Single(c => c.Type == ClaimTypes.AuthenticationMethod).Value);
// Act 2
await UserStories.SetPasswordAsync(index, "!Test.Password2");
await UserStories.SetPasswordAsync(index, "[PLACEHOLDER]-1a-updated");
// Assert 2
// RefreshSignIn uses the same AuthenticationMethod claim value
@ -188,7 +189,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
// Act & Assert 3
// Can log in with the password set above
await UserStories.LoginExistingUserAsync(loginAfterSetPasswordClient, email, "!Test.Password2");
await UserStories.LoginExistingUserAsync(loginAfterSetPasswordClient, email, "[PLACEHOLDER]-1a-updated");
}
[Fact]
@ -211,7 +212,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var email = $"{guid}@example.com";
// Act
var index = await UserStories.RegisterNewUserAsync(client, email, "!TestPassword1");
var index = await UserStories.RegisterNewUserAsync(client, email, "[PLACEHOLDER]-1a");
var linkLogin = await UserStories.LinkExternalLoginAsync(index, email);
await UserStories.RemoveExternalLoginAsync(linkLogin, email);
@ -258,7 +259,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var newClient = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
// Act
var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password);
@ -295,7 +296,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var index = social
? await UserStories.RegisterNewUserWithSocialLoginAsync(client, userName, email)
: await UserStories.RegisterNewUserAsync(client, email, "!TestPassword1");
: await UserStories.RegisterNewUserAsync(client, email, "[PLACEHOLDER]-1a");
if (twoFactor)
{
@ -362,7 +363,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
var index = await UserStories.RegisterNewUserAsync(client, userName, password);

View File

@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
// Act & Assert
await UserStories.RegisterNewUserAsync(client, userName, password);
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var client2 = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
// Act & Assert
var register = await UserStories.RegisterNewUserAsyncWithConfirmation(client, userName, password);
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
var client2 = server.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
// Act & Assert
var register = await UserStories.RegisterNewUserAsyncWithConfirmation(client, userName, password, hasRealEmailSender: true);
@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
.CreateClient();
var userName = $"{Guid.NewGuid()}@example.com";
var password = $"!Test.Password1$";
var password = $"[PLACEHOLDER]-1a";
// Act & Assert
await UserStories.RegisterNewUserAsync(client, userName, password);

View File

@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Identity.Test
// {
// UserName = "Yolo"
// };
// const string password = "Yol0Sw@g!";
// const string password = "[PLACEHOLDER]-1a";
// var userManager = app.ApplicationServices.GetRequiredService<ApplicationUserManager>();
// var HttpSignInManager = app.ApplicationServices.GetRequiredService<ApplicationHttpSignInManager>();
@ -127,7 +127,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var helper = new SignInManager<PocoUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new DefaultUserConfirmation<PocoUser>());
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-bogus1", false, false);
// Assert
Assert.False(result.Succeeded);
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var helper = new SignInManager<PocoUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new DefaultUserConfirmation<PocoUser>());
// Act
var result = await helper.CheckPasswordSignInAsync(user, "bogus", false);
var result = await helper.CheckPasswordSignInAsync(user, "[PLACEHOLDER]-bogus1", false);
// Assert
Assert.False(result.Succeeded);
@ -201,14 +201,14 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
var context = new DefaultHttpContext();
var auth = MockAuth(context);
SetupSignIn(context, auth, user.Id, isPersistent, loginProvider: null, amr: "pwd");
var helper = SetupSignInManager(manager.Object, context);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-1a", isPersistent, false);
// Assert
Assert.True(result.Succeeded);
@ -224,7 +224,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
var context = new DefaultHttpContext();
var auth = MockAuth(context);
@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var helper = SetupSignInManager(manager.Object, context);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-1a", false, false);
// Assert
Assert.True(result.Succeeded);
@ -249,7 +249,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
var context = new DefaultHttpContext();
@ -258,7 +258,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var helper = SetupSignInManager(manager.Object, context);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-1a", false, false);
// Assert
Assert.True(result.Succeeded);
@ -278,7 +278,7 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.SupportsUserTwoFactor).Returns(tfaEnabled).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
var context = new DefaultHttpContext();
var auth = MockAuth(context);
@ -304,7 +304,7 @@ namespace Microsoft.AspNetCore.Identity.Test
// Act
var helper = SetupSignInManager(manager.Object, context);
var result = await helper.CheckPasswordSignInAsync(user, "password", false);
var result = await helper.CheckPasswordSignInAsync(user, "[PLACEHOLDER]-1a", false);
// Assert
Assert.True(result.Succeeded);
@ -321,14 +321,14 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
var context = new DefaultHttpContext();
var helper = SetupSignInManager(manager.Object, context);
// Act
var result = await helper.CheckPasswordSignInAsync(user, "password", false);
var result = await helper.CheckPasswordSignInAsync(user, "[PLACEHOLDER]-1a", false);
// Assert
Assert.True(result.Succeeded);
@ -355,7 +355,7 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.GetValidTwoFactorProvidersAsync(user)).Returns(Task.FromResult(providers)).Verifiable();
manager.Setup(m => m.SupportsUserTwoFactor).Returns(true).Verifiable();
manager.Setup(m => m.GetTwoFactorEnabledAsync(user)).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.GetValidTwoFactorProvidersAsync(user)).ReturnsAsync(new string[1] { "Fake" }).Verifiable();
var context = new DefaultHttpContext();
var helper = SetupSignInManager(manager.Object, context);
@ -365,7 +365,7 @@ namespace Microsoft.AspNetCore.Identity.Test
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-1a", false, false);
// Assert
Assert.False(result.Succeeded);
@ -717,7 +717,7 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.SupportsUserTwoFactor).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
var context = new DefaultHttpContext();
var auth = MockAuth(context);
SetupSignIn(context, auth);
@ -728,7 +728,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var helper = SetupSignInManager(manager.Object, context);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-1a", isPersistent, false);
// Assert
Assert.True(result.Succeeded);
@ -770,14 +770,14 @@ namespace Microsoft.AspNetCore.Identity.Test
var manager = SetupUserManager(user);
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-bogus1")).ReturnsAsync(false).Verifiable();
var context = new Mock<HttpContext>();
var logger = new TestLogger<SignInManager<PocoUser>>();
var helper = SetupSignInManager(manager.Object, context.Object, logger);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
var checkResult = await helper.CheckPasswordSignInAsync(user, "bogus", false);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-bogus1", false, false);
var checkResult = await helper.CheckPasswordSignInAsync(user, "[PLACEHOLDER]-bogus1", false);
// Assert
Assert.False(result.Succeeded);
@ -792,12 +792,12 @@ namespace Microsoft.AspNetCore.Identity.Test
{
// Setup
var manager = MockHelpers.MockUserManager<PocoUser>();
manager.Setup(m => m.FindByNameAsync("bogus")).ReturnsAsync(default(PocoUser)).Verifiable();
manager.Setup(m => m.FindByNameAsync("unknown-username")).ReturnsAsync(default(PocoUser)).Verifiable();
var context = new Mock<HttpContext>();
var helper = SetupSignInManager(manager.Object, context.Object);
// Act
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
var result = await helper.PasswordSignInAsync("unknown-username", "[PLACEHOLDER]-bogus1", false, false);
// Assert
Assert.False(result.Succeeded);
@ -819,12 +819,12 @@ namespace Microsoft.AspNetCore.Identity.Test
}).Verifiable();
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).Returns(() => Task.FromResult(lockedout));
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-bogus1")).ReturnsAsync(false).Verifiable();
var context = new Mock<HttpContext>();
var helper = SetupSignInManager(manager.Object, context.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);
var result = await helper.PasswordSignInAsync(user.UserName, "[PLACEHOLDER]-bogus1", false, true);
// Assert
Assert.False(result.Succeeded);
@ -846,12 +846,12 @@ namespace Microsoft.AspNetCore.Identity.Test
}).Verifiable();
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
manager.Setup(m => m.IsLockedOutAsync(user)).Returns(() => Task.FromResult(lockedout));
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-bogus1")).ReturnsAsync(false).Verifiable();
var context = new Mock<HttpContext>();
var helper = SetupSignInManager(manager.Object, context.Object);
// Act
var result = await helper.CheckPasswordSignInAsync(user, "bogus", true);
var result = await helper.CheckPasswordSignInAsync(user, "[PLACEHOLDER]-bogus1", true);
// Assert
Assert.False(result.Succeeded);
@ -870,13 +870,13 @@ namespace Microsoft.AspNetCore.Identity.Test
manager.Setup(m => m.IsEmailConfirmedAsync(user)).ReturnsAsync(confirmed).Verifiable();
if (confirmed)
{
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
}
var context = new DefaultHttpContext();
var auth = MockAuth(context);
if (confirmed)
{
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
SetupSignIn(context, auth, user.Id, isPersistent: null, loginProvider: null, amr: "pwd");
}
var identityOptions = new IdentityOptions();
@ -885,7 +885,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var helper = SetupSignInManager(manager.Object, context, logger, identityOptions);
// Act
var result = await helper.PasswordSignInAsync(user, "password", false, false);
var result = await helper.PasswordSignInAsync(user, "[PLACEHOLDER]-1a", false, false);
// Assert
@ -930,7 +930,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var auth = MockAuth(context);
if (confirmed)
{
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
manager.Setup(m => m.CheckPasswordAsync(user, "[PLACEHOLDER]-1a")).ReturnsAsync(true).Verifiable();
SetupSignIn(context, auth, user.Id, isPersistent: null, loginProvider: null, amr: "pwd");
}
@ -940,7 +940,7 @@ namespace Microsoft.AspNetCore.Identity.Test
var helper = SetupSignInManager(manager.Object, context, logger, identityOptions);
// Act
var result = await helper.PasswordSignInAsync(user, "password", false, false);
var result = await helper.PasswordSignInAsync(user, "[PLACEHOLDER]-1a", false, false);
// Assert
Assert.Equal(confirmed, result.Succeeded);

View File

@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
{
UserName = "Yolo"
};
const string password = "Yol0Sw@g!";
const string password = "[PLACEHOLDER]-1a";
var userManager = app.ApplicationServices.GetRequiredService<UserManager<PocoUser>>();
var signInManager = app.ApplicationServices.GetRequiredService<SignInManager<PocoUser>>();

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
{
public class FunctionalTest
{
const string TestPassword = "1qaz!QAZ";
const string TestPassword = "[PLACEHOLDER]-1a";
[Fact]
public async Task CanChangePasswordOptions()

View File

@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
protected override void ConfigureDefaults(FacebookOptions o)
{
o.AppId = "whatever";
o.AppSecret = "whatever";
o.AppSecret = "PLACEHOLDER";
o.SignInScheme = "auth1";
}
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
{
using var host = await CreateHost(
app => { },
services => services.AddAuthentication().AddFacebook(o => o.SignInScheme = "Whatever"),
services => services.AddAuthentication().AddFacebook(o => o.SignInScheme = "PLACEHOLDER"),
async context =>
{
await Assert.ThrowsAsync<ArgumentException>("AppId", () => context.ChallengeAsync("Facebook"));

View File

@ -36,8 +36,8 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
protected override void ConfigureDefaults(TwitterOptions o)
{
o.ConsumerKey = "whatever";
o.ConsumerSecret = "whatever";
o.ConsumerKey = "PLACEHOLDER";
o.ConsumerSecret = "PLACEHOLDER";
o.SignInScheme = "auth1";
}