1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-24 13:01:03 -05:00
Brant DeBow 90d831d9ef
[PM-17562] API For Organization Integrations/Configurations, Refactored Distributed Events, Slack Integration (#5654)
* [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>
2025-04-23 10:44:43 -04:00

110 lines
4.5 KiB
C#

using System.Globalization;
using Bit.Core.AdminConsole.Services.NoopImplementations;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Bit.SharedWeb.Utilities;
using Microsoft.IdentityModel.Logging;
using TableStorageRepos = Bit.Core.Repositories.TableStorage;
namespace Bit.EventsProcessor;
public class Startup
{
public Startup(IWebHostEnvironment env, IConfiguration configuration)
{
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
Configuration = configuration;
Environment = env;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; set; }
public void ConfigureServices(IServiceCollection services)
{
// Options
services.AddOptions();
// Settings
var globalSettings = services.AddGlobalSettingsServices(Configuration, Environment);
// Data Protection
services.AddCustomDataProtectionServices(Environment, globalSettings);
// Repositories
services.AddDatabaseRepositories(globalSettings);
// Hosted Services
// Optional Azure Service Bus Listeners
if (CoreHelpers.SettingHasValue(globalSettings.EventLogging.AzureServiceBus.ConnectionString) &&
CoreHelpers.SettingHasValue(globalSettings.EventLogging.AzureServiceBus.TopicName))
{
services.AddSingleton<IEventRepository, TableStorageRepos.EventRepository>();
services.AddSingleton<AzureTableStorageEventHandler>();
services.AddKeyedSingleton<IEventWriteService, RepositoryEventWriteService>("persistent");
services.AddSingleton<IHostedService>(provider =>
new AzureServiceBusEventListenerService(
provider.GetRequiredService<AzureTableStorageEventHandler>(),
provider.GetRequiredService<ILogger<AzureServiceBusEventListenerService>>(),
globalSettings,
globalSettings.EventLogging.AzureServiceBus.EventRepositorySubscriptionName));
if (CoreHelpers.SettingHasValue(globalSettings.Slack.ClientId) &&
CoreHelpers.SettingHasValue(globalSettings.Slack.ClientSecret) &&
CoreHelpers.SettingHasValue(globalSettings.Slack.Scopes))
{
services.AddHttpClient(SlackService.HttpClientName);
services.AddSingleton<ISlackService, SlackService>();
}
else
{
services.AddSingleton<ISlackService, NoopSlackService>();
}
services.AddSingleton<SlackEventHandler>();
services.AddSingleton<IHostedService>(provider =>
new AzureServiceBusEventListenerService(
provider.GetRequiredService<SlackEventHandler>(),
provider.GetRequiredService<ILogger<AzureServiceBusEventListenerService>>(),
globalSettings,
globalSettings.EventLogging.AzureServiceBus.SlackSubscriptionName));
services.AddSingleton<WebhookEventHandler>();
services.AddHttpClient(WebhookEventHandler.HttpClientName);
services.AddSingleton<IHostedService>(provider =>
new AzureServiceBusEventListenerService(
provider.GetRequiredService<WebhookEventHandler>(),
provider.GetRequiredService<ILogger<AzureServiceBusEventListenerService>>(),
globalSettings,
globalSettings.EventLogging.AzureServiceBus.WebhookSubscriptionName));
}
services.AddHostedService<AzureQueueHostedService>();
}
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
IdentityModelEventSource.ShowPII = true;
app.UseSerilog(env, appLifetime, globalSettings);
// Add general security headers
app.UseMiddleware<SecurityHeadersMiddleware>();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/alive",
async context => await context.Response.WriteAsJsonAsync(System.DateTime.UtcNow));
endpoints.MapGet("/now",
async context => await context.Response.WriteAsJsonAsync(System.DateTime.UtcNow));
endpoints.MapGet("/version",
async context => await context.Response.WriteAsJsonAsync(AssemblyHelpers.GetVersion()));
});
}
}