1
0
mirror of https://github.com/bitwarden/server synced 2026-01-15 06:53:26 +00:00

Move all event integration code to Dirt (#6757)

* Move all event integration code to Dirt

* Format to fix lint
This commit is contained in:
Brant DeBow
2025-12-30 10:59:19 -05:00
committed by GitHub
parent 9a340c0fdd
commit 86a68ab637
158 changed files with 487 additions and 472 deletions

View File

@@ -0,0 +1,76 @@
using Bit.Core.Dirt.Models.Data.EventIntegrations;
namespace Bit.Core.Dirt.Services.Implementations;
public class SlackIntegrationHandler(
ISlackService slackService)
: IntegrationHandlerBase<SlackIntegrationConfigurationDetails>
{
public override async Task<IntegrationHandlerResult> HandleAsync(IntegrationMessage<SlackIntegrationConfigurationDetails> message)
{
var slackResponse = await slackService.SendSlackMessageByChannelIdAsync(
message.Configuration.Token,
message.RenderedTemplate,
message.Configuration.ChannelId
);
if (slackResponse is null)
{
return IntegrationHandlerResult.Fail(
message,
IntegrationFailureCategory.TransientError,
"Slack response was null"
);
}
if (slackResponse.Ok)
{
return IntegrationHandlerResult.Succeed(message);
}
var category = ClassifySlackError(slackResponse.Error);
return IntegrationHandlerResult.Fail(
message,
category,
slackResponse.Error
);
}
/// <summary>
/// Classifies a Slack API error code string as an <see cref="IntegrationFailureCategory"/> to drive
/// retry behavior and operator-facing failure reporting.
/// </summary>
/// <remarks>
/// <para>
/// Slack responses commonly return an <c>error</c> string when <c>ok</c> is false. This method maps
/// known Slack error codes to failure categories.
/// </para>
/// <para>
/// Any unrecognized error codes default to <see cref="IntegrationFailureCategory.TransientError"/> to avoid
/// incorrectly marking new/unknown Slack failures as non-retryable.
/// </para>
/// </remarks>
/// <param name="error">The Slack error code string (e.g. <c>invalid_auth</c>, <c>rate_limited</c>).</param>
/// <returns>The corresponding <see cref="IntegrationFailureCategory"/>.</returns>
private static IntegrationFailureCategory ClassifySlackError(string error)
{
return error switch
{
"invalid_auth" => IntegrationFailureCategory.AuthenticationFailed,
"access_denied" => IntegrationFailureCategory.AuthenticationFailed,
"token_expired" => IntegrationFailureCategory.AuthenticationFailed,
"token_revoked" => IntegrationFailureCategory.AuthenticationFailed,
"account_inactive" => IntegrationFailureCategory.AuthenticationFailed,
"not_authed" => IntegrationFailureCategory.AuthenticationFailed,
"channel_not_found" => IntegrationFailureCategory.ConfigurationError,
"is_archived" => IntegrationFailureCategory.ConfigurationError,
"rate_limited" => IntegrationFailureCategory.RateLimited,
"ratelimited" => IntegrationFailureCategory.RateLimited,
"message_limit_exceeded" => IntegrationFailureCategory.RateLimited,
"internal_error" => IntegrationFailureCategory.TransientError,
"service_unavailable" => IntegrationFailureCategory.ServiceUnavailable,
"fatal_error" => IntegrationFailureCategory.ServiceUnavailable,
_ => IntegrationFailureCategory.TransientError
};
}
}