Skip to content

Commit fe95226

Browse files
test: add integration tests
1 parent e2c2da5 commit fe95226

File tree

2 files changed

+170
-2
lines changed

2 files changed

+170
-2
lines changed

test/Identity.IntegrationTest/RequestValidation/SendAccess/SendAccessTestUtilities.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Bit.Core.Auth.IdentityServer;
1+
using Bit.Core.Auth.IdentityServer;
22
using Bit.Core.Enums;
33
using Bit.Core.Utilities;
44
using Bit.Identity.IdentityServer.Enums;
@@ -42,4 +42,4 @@ public static FormUrlEncodedContent CreateTokenRequestBody(
4242

4343
return new FormUrlEncodedContent(parameters);
4444
}
45-
}
45+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
using Bit.Core.Services;
2+
using Bit.Core.Tools.Models.Data;
3+
using Bit.Core.Tools.SendFeatures.Queries.Interfaces;
4+
using Bit.Core.Utilities;
5+
using Bit.Identity.IdentityServer.RequestValidators.SendAccess;
6+
using Bit.IntegrationTestCommon.Factories;
7+
using Duende.IdentityModel;
8+
using NSubstitute;
9+
using Xunit;
10+
11+
namespace Bit.Identity.IntegrationTest.RequestValidation.SendAccess;
12+
13+
public class SendNeverAuthenticateRequestValidatorIntegrationTests(
14+
IdentityApplicationFactory _factory) : IClassFixture<IdentityApplicationFactory>
15+
{
16+
/// <summary>
17+
/// To support the static hashing function <see cref="EnumerationProtectionHelpers.GetIndexForSaltHash"/> theses GUIDs and Key must be hardcoded
18+
/// </summary>
19+
private static readonly string _testHashKey = "test-key-123456789012345678901234567890";
20+
// These Guids are static and ensure the correct index for each error type
21+
private static readonly Guid _invalidSendGuid = Guid.Parse("1b35fbf3-a14a-4d48-82b7-2adc34fdae6f");
22+
private static readonly Guid _emailSendGuid = Guid.Parse("bc8e2ef5-a0bd-44d2-bdb7-5902be6f5c41");
23+
private static readonly Guid _passwordSendGuid = Guid.Parse("da36fa27-f0e8-4701-a585-d3d8c2f67c4b");
24+
25+
[Fact]
26+
public async Task SendAccess_NeverAuthenticateSend_NoParameters_ReturnsInvalidSendId()
27+
{
28+
// Arrange
29+
var client = ConfigureTestHttpClient(_invalidSendGuid);
30+
var requestBody = SendAccessTestUtilities.CreateTokenRequestBody(_invalidSendGuid);
31+
32+
// Act
33+
var response = await client.PostAsync("/connect/token", requestBody);
34+
35+
// Assert
36+
var content = await response.Content.ReadAsStringAsync();
37+
38+
Assert.Contains(OidcConstants.TokenErrors.InvalidGrant, content);
39+
40+
var expectedError = SendAccessConstants.GrantValidatorResults.InvalidSendId;
41+
Assert.Contains(expectedError, content);
42+
}
43+
44+
[Fact]
45+
public async Task SendAccess_NeverAuthenticateSend_ReturnsEmailRequired()
46+
{
47+
// Arrange
48+
var client = ConfigureTestHttpClient(_emailSendGuid);
49+
var requestBody = SendAccessTestUtilities.CreateTokenRequestBody(_emailSendGuid);
50+
51+
// Act
52+
var response = await client.PostAsync("/connect/token", requestBody);
53+
54+
// Assert
55+
var content = await response.Content.ReadAsStringAsync();
56+
57+
// should be invalid grant
58+
Assert.Contains(OidcConstants.TokenErrors.InvalidRequest, content);
59+
60+
// Try to compel the invalid email error
61+
var expectedError = SendAccessConstants.EmailOtpValidatorResults.EmailRequired;
62+
Assert.Contains(expectedError, content);
63+
}
64+
65+
[Fact]
66+
public async Task SendAccess_NeverAuthenticateSend_WithEmail_ReturnsEmailInvalid()
67+
{
68+
// Arrange
69+
var email = "[email protected]";
70+
var client = ConfigureTestHttpClient(_emailSendGuid);
71+
var requestBody = SendAccessTestUtilities.CreateTokenRequestBody(_emailSendGuid, email: email);
72+
73+
// Act
74+
var response = await client.PostAsync("/connect/token", requestBody);
75+
76+
// Assert
77+
var content = await response.Content.ReadAsStringAsync();
78+
79+
// should be invalid grant
80+
Assert.Contains(OidcConstants.TokenErrors.InvalidGrant, content);
81+
82+
// Try to compel the invalid email error
83+
var expectedError = SendAccessConstants.EmailOtpValidatorResults.EmailInvalid;
84+
Assert.Contains(expectedError, content);
85+
}
86+
87+
[Fact]
88+
public async Task SendAccess_NeverAuthenticateSend_ReturnsPasswordRequired()
89+
{
90+
// Arrange
91+
var client = ConfigureTestHttpClient(_passwordSendGuid);
92+
93+
var requestBody = SendAccessTestUtilities.CreateTokenRequestBody(_passwordSendGuid);
94+
95+
// Act
96+
var response = await client.PostAsync("/connect/token", requestBody);
97+
98+
// Assert
99+
var content = await response.Content.ReadAsStringAsync();
100+
101+
Assert.Contains(OidcConstants.TokenErrors.InvalidGrant, content);
102+
103+
var expectedError = SendAccessConstants.PasswordValidatorResults.RequestPasswordIsRequired;
104+
Assert.Contains(expectedError, content);
105+
}
106+
107+
[Fact]
108+
public async Task SendAccess_NeverAuthenticateSend_WithPassword_ReturnsPasswordInvalid()
109+
{
110+
// Arrange
111+
var password = "test-password-hash";
112+
113+
var client = ConfigureTestHttpClient(_passwordSendGuid);
114+
115+
var requestBody = SendAccessTestUtilities.CreateTokenRequestBody(_passwordSendGuid, password: password);
116+
117+
// Act
118+
var response = await client.PostAsync("/connect/token", requestBody);
119+
120+
// Assert
121+
var content = await response.Content.ReadAsStringAsync();
122+
123+
Assert.Contains(OidcConstants.TokenErrors.InvalidRequest, content);
124+
125+
var expectedError = SendAccessConstants.PasswordValidatorResults.RequestPasswordDoesNotMatch;
126+
Assert.Contains(expectedError, content);
127+
}
128+
129+
[Fact]
130+
public async Task SendAccess_NeverAuthenticateSend_ConsistentResponse_SameSendId()
131+
{
132+
// Arrange
133+
var client = ConfigureTestHttpClient(_emailSendGuid);
134+
135+
var requestBody1 = SendAccessTestUtilities.CreateTokenRequestBody(_emailSendGuid);
136+
var requestBody2 = SendAccessTestUtilities.CreateTokenRequestBody(_emailSendGuid);
137+
138+
// Act
139+
var response1 = await client.PostAsync("/connect/token", requestBody1);
140+
var response2 = await client.PostAsync("/connect/token", requestBody2);
141+
142+
// Assert
143+
var content1 = await response1.Content.ReadAsStringAsync();
144+
var content2 = await response2.Content.ReadAsStringAsync();
145+
146+
Assert.Equal(content1, content2);
147+
}
148+
149+
private HttpClient ConfigureTestHttpClient(Guid sendId)
150+
{
151+
_factory.UpdateConfiguration(
152+
"globalSettings:sendDefaultHashKey", _testHashKey);
153+
return _factory.WithWebHostBuilder(builder =>
154+
{
155+
builder.ConfigureServices(services =>
156+
{
157+
var featureService = Substitute.For<IFeatureService>();
158+
featureService.IsEnabled(Arg.Any<string>()).Returns(true);
159+
services.AddSingleton(featureService);
160+
161+
var sendAuthQuery = Substitute.For<ISendAuthenticationQuery>();
162+
sendAuthQuery.GetAuthenticationMethod(sendId)
163+
.Returns(new NeverAuthenticate());
164+
services.AddSingleton(sendAuthQuery);
165+
});
166+
}).CreateClient();
167+
}
168+
}

0 commit comments

Comments
 (0)