mirror of
https://github.com/bitwarden/server.git
synced 2025-04-24 06:25:09 -05:00

* [PM-17562] Slack Event Investigation * Refactored Slack and Webhook integrations to pull configurations dynamically from a new Repository * Added new TemplateProcessor and added/updated unit tests * SlackService improvements, testing, integration configurations * Refactor SlackService to use a dedicated model to parse responses * Refactored SlackOAuthController to use SlackService as an injected dependency; added tests for SlackService * Remove unnecessary methods from the IOrganizationIntegrationConfigurationRepository * Moved Slack OAuth to take into account the Organization it's being stored for. Added methods to store the top level integration for Slack * Organization integrations and configuration database schemas * Format EF files * Initial buildout of basic repositories * [PM-17562] Add Dapper Repositories For Organization Integrations and Configurations * Update Slack and Webhook handlers to use new Repositories * Update SlackOAuth tests to new signatures * Added EF Repositories * Update handlers to use latest repositories * [PM-17562] Add Dapper and EF Repositories For Ogranization Integrations and Configurations * Updated with changes from PR comments * Adjusted Handlers to new repository method names; updated tests to naming convention * Adjust URL structure; add delete for Slack, add tests * Added Webhook Integration Controller * Add tests for WebhookIntegrationController * Added Create/Delete for OrganizationIntegrationConfigurations * Prepend ConnectionTypes into IntegrationType so we don't run into issues later * Added Update to OrganizationIntegrationConfigurtionController * Moved Webhook-specific integration code to being a generic controller for everything but Slack * Removed delete from SlackController - Deletes should happen through the normal Integration controller * Fixed SlackController, reworked OIC Controller to use ids from URL and update the returned object * Added parse/type checking for integration and integration configuration JSONs, Cleaned up GlobalSettings to remove old values * Cleanup and fixes for Azure Service Bus support * Clean up naming on TemplateProcessorTests * Address SonarQube warnings/suggestions * Expanded test coverage; Cleaned up tests * Respond to PR Feedback * Rename TemplateProcessor to IntegrationTemplateProcessor --------- Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
131 lines
5.6 KiB
C#
131 lines
5.6 KiB
C#
using Bit.Api.AdminConsole.Controllers;
|
|
using Bit.Core.AdminConsole.Entities;
|
|
using Bit.Core.Context;
|
|
using Bit.Core.Exceptions;
|
|
using Bit.Core.Repositories;
|
|
using Bit.Core.Services;
|
|
using Bit.Test.Common.AutoFixture;
|
|
using Bit.Test.Common.AutoFixture.Attributes;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using NSubstitute;
|
|
using Xunit;
|
|
|
|
namespace Bit.Api.Test.AdminConsole.Controllers;
|
|
|
|
[ControllerCustomize(typeof(SlackIntegrationController))]
|
|
[SutProviderCustomize]
|
|
public class SlackIntegrationControllerTests
|
|
{
|
|
[Theory, BitAutoData]
|
|
public async Task CreateAsync_AllParamsProvided_Succeeds(SutProvider<SlackIntegrationController> sutProvider, Guid organizationId)
|
|
{
|
|
var token = "xoxb-test-token";
|
|
sutProvider.Sut.Url = Substitute.For<IUrlHelper>();
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organizationId)
|
|
.Returns(true);
|
|
sutProvider.GetDependency<ISlackService>()
|
|
.ObtainTokenViaOAuth(Arg.Any<string>(), Arg.Any<string>())
|
|
.Returns(token);
|
|
sutProvider.GetDependency<IOrganizationIntegrationRepository>()
|
|
.CreateAsync(Arg.Any<OrganizationIntegration>())
|
|
.Returns(callInfo => callInfo.Arg<OrganizationIntegration>());
|
|
var requestAction = await sutProvider.Sut.CreateAsync(organizationId, "A_test_code");
|
|
|
|
await sutProvider.GetDependency<IOrganizationIntegrationRepository>().Received(1)
|
|
.CreateAsync(Arg.Any<OrganizationIntegration>());
|
|
Assert.IsType<CreatedResult>(requestAction);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task CreateAsync_CodeIsEmpty_ThrowsBadRequest(SutProvider<SlackIntegrationController> sutProvider, Guid organizationId)
|
|
{
|
|
sutProvider.Sut.Url = Substitute.For<IUrlHelper>();
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organizationId)
|
|
.Returns(true);
|
|
|
|
await Assert.ThrowsAsync<BadRequestException>(async () => await sutProvider.Sut.CreateAsync(organizationId, string.Empty));
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task CreateAsync_SlackServiceReturnsEmpty_ThrowsBadRequest(SutProvider<SlackIntegrationController> sutProvider, Guid organizationId)
|
|
{
|
|
sutProvider.Sut.Url = Substitute.For<IUrlHelper>();
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organizationId)
|
|
.Returns(true);
|
|
sutProvider.GetDependency<ISlackService>()
|
|
.ObtainTokenViaOAuth(Arg.Any<string>(), Arg.Any<string>())
|
|
.Returns(string.Empty);
|
|
|
|
await Assert.ThrowsAsync<BadRequestException>(async () => await sutProvider.Sut.CreateAsync(organizationId, "A_test_code"));
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task CreateAsync_UserIsNotOrganizationAdmin_ThrowsNotFound(SutProvider<SlackIntegrationController> sutProvider, Guid organizationId)
|
|
{
|
|
var token = "xoxb-test-token";
|
|
sutProvider.Sut.Url = Substitute.For<IUrlHelper>();
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organizationId)
|
|
.Returns(false);
|
|
sutProvider.GetDependency<ISlackService>()
|
|
.ObtainTokenViaOAuth(Arg.Any<string>(), Arg.Any<string>())
|
|
.Returns(token);
|
|
|
|
await Assert.ThrowsAsync<NotFoundException>(async () => await sutProvider.Sut.CreateAsync(organizationId, "A_test_code"));
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task RedirectAsync_Success(SutProvider<SlackIntegrationController> sutProvider, Guid organizationId)
|
|
{
|
|
var expectedUrl = $"https://localhost/{organizationId}";
|
|
|
|
sutProvider.Sut.Url = Substitute.For<IUrlHelper>();
|
|
sutProvider.GetDependency<ISlackService>().GetRedirectUrl(Arg.Any<string>()).Returns(expectedUrl);
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organizationId)
|
|
.Returns(true);
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.HttpContext.Request.Scheme
|
|
.Returns("https");
|
|
|
|
var requestAction = await sutProvider.Sut.RedirectAsync(organizationId);
|
|
|
|
var redirectResult = Assert.IsType<RedirectResult>(requestAction);
|
|
Assert.Equal(expectedUrl, redirectResult.Url);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task RedirectAsync_SlackServiceReturnsEmpty_ThrowsNotFound(SutProvider<SlackIntegrationController> sutProvider, Guid organizationId)
|
|
{
|
|
sutProvider.Sut.Url = Substitute.For<IUrlHelper>();
|
|
sutProvider.GetDependency<ISlackService>().GetRedirectUrl(Arg.Any<string>()).Returns(string.Empty);
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organizationId)
|
|
.Returns(true);
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.HttpContext.Request.Scheme
|
|
.Returns("https");
|
|
|
|
await Assert.ThrowsAsync<NotFoundException>(async () => await sutProvider.Sut.RedirectAsync(organizationId));
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
public async Task RedirectAsync_UserIsNotOrganizationAdmin_ThrowsNotFound(SutProvider<SlackIntegrationController> sutProvider,
|
|
Guid organizationId)
|
|
{
|
|
sutProvider.Sut.Url = Substitute.For<IUrlHelper>();
|
|
sutProvider.GetDependency<ISlackService>().GetRedirectUrl(Arg.Any<string>()).Returns(string.Empty);
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.OrganizationOwner(organizationId)
|
|
.Returns(false);
|
|
sutProvider.GetDependency<ICurrentContext>()
|
|
.HttpContext.Request.Scheme
|
|
.Returns("https");
|
|
|
|
await Assert.ThrowsAsync<NotFoundException>(async () => await sutProvider.Sut.RedirectAsync(organizationId));
|
|
}
|
|
}
|