mirror of
https://github.com/bitwarden/server
synced 2025-12-18 09:13:19 +00:00
Refactor Slack Callback Mechanism (#6388)
* Refactor Slack Callback * Add more safety to state param, clarify if logic, update tests * Added an additional 2 possible cases to test: integration is not a slack integration, and the integration has already been claimed * Implement SonarQube suggestion * Adjusted org hash to include timestamp; addressed PR feedback
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
#nullable enable
|
||||
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Microsoft.Extensions.Time.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.AdminConsole.Models.Data.EventIntegrations;
|
||||
|
||||
public class IntegrationOAuthStateTests
|
||||
{
|
||||
private readonly FakeTimeProvider _fakeTimeProvider = new(
|
||||
new DateTime(2014, 3, 2, 1, 0, 0, DateTimeKind.Utc)
|
||||
);
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void FromIntegration_ToString_RoundTripsCorrectly(OrganizationIntegration integration)
|
||||
{
|
||||
var state = IntegrationOAuthState.FromIntegration(integration, _fakeTimeProvider);
|
||||
var parsed = IntegrationOAuthState.FromString(state.ToString(), _fakeTimeProvider);
|
||||
|
||||
Assert.NotNull(parsed);
|
||||
Assert.Equal(state.IntegrationId, parsed.IntegrationId);
|
||||
Assert.True(parsed.ValidateOrg(integration.OrganizationId));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
[InlineData("not-a-valid-state")]
|
||||
public void FromString_InvalidString_ReturnsNull(string state)
|
||||
{
|
||||
var parsed = IntegrationOAuthState.FromString(state, _fakeTimeProvider);
|
||||
|
||||
Assert.Null(parsed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromString_InvalidGuid_ReturnsNull()
|
||||
{
|
||||
var badState = $"not-a-guid.ABCD1234.1706313600";
|
||||
|
||||
var parsed = IntegrationOAuthState.FromString(badState, _fakeTimeProvider);
|
||||
|
||||
Assert.Null(parsed);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void FromString_ExpiredState_ReturnsNull(OrganizationIntegration integration)
|
||||
{
|
||||
var state = IntegrationOAuthState.FromIntegration(integration, _fakeTimeProvider);
|
||||
|
||||
// Advance time 30 minutes to exceed the 20-minute max age
|
||||
_fakeTimeProvider.Advance(TimeSpan.FromMinutes(30));
|
||||
|
||||
var parsed = IntegrationOAuthState.FromString(state.ToString(), _fakeTimeProvider);
|
||||
|
||||
Assert.Null(parsed);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void ValidateOrg_WithCorrectOrgId_ReturnsTrue(OrganizationIntegration integration)
|
||||
{
|
||||
var state = IntegrationOAuthState.FromIntegration(integration, _fakeTimeProvider);
|
||||
|
||||
Assert.True(state.ValidateOrg(integration.OrganizationId));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void ValidateOrg_WithWrongOrgId_ReturnsFalse(OrganizationIntegration integration)
|
||||
{
|
||||
var state = IntegrationOAuthState.FromIntegration(integration, _fakeTimeProvider);
|
||||
|
||||
Assert.False(state.ValidateOrg(Guid.NewGuid()));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void ValidateOrg_ModifiedTimestamp_ReturnsFalse(OrganizationIntegration integration)
|
||||
{
|
||||
var state = IntegrationOAuthState.FromIntegration(integration, _fakeTimeProvider);
|
||||
var parts = state.ToString().Split('.');
|
||||
|
||||
parts[2] = $"{_fakeTimeProvider.GetUtcNow().ToUnixTimeSeconds() - 1}";
|
||||
var modifiedState = IntegrationOAuthState.FromString(string.Join(".", parts), _fakeTimeProvider);
|
||||
|
||||
Assert.True(state.ValidateOrg(integration.OrganizationId));
|
||||
Assert.NotNull(modifiedState);
|
||||
Assert.False(modifiedState.ValidateOrg(integration.OrganizationId));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user