* [PM-17562] Add HEC integration support
* Re-ordered parameters per PR suggestion
* Apply suggestions from code review
Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
* Refactored webhook request model validation to be more clear
---------
Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
@ -33,6 +33,10 @@ public class OrganizationIntegrationConfigurationRequestModel
@@ -33,6 +33,10 @@ public class OrganizationIntegrationConfigurationRequestModel
@ -39,10 +41,22 @@ public class OrganizationIntegrationRequestModel : IValidatableObject
@@ -39,10 +41,22 @@ public class OrganizationIntegrationRequestModel : IValidatableObject
yieldreturnnewValidationResult($"{nameof(Type)} integrations cannot be created directly.",new[]{nameof(Type)});
break;
caseIntegrationType.Webhook:
if(Configurationisnotnull)
if(string.IsNullOrWhiteSpace(Configuration))
{
break;
}
if(!IsIntegrationValid<WebhookIntegration>())
{
yieldreturnnewValidationResult(
"Webhook integrations must not include configuration.",
"Webhook integrations must include valid configuration.",
new[]{nameof(Configuration)});
}
break;
caseIntegrationType.Hec:
if(!IsIntegrationValid<HecIntegration>())
{
yieldreturnnewValidationResult(
"HEC integrations must include valid configuration.",
new[]{nameof(Configuration)});
}
break;
@ -53,4 +67,22 @@ public class OrganizationIntegrationRequestModel : IValidatableObject
@@ -53,4 +67,22 @@ public class OrganizationIntegrationRequestModel : IValidatableObject
@ -197,22 +197,37 @@ interface and therefore can also handle directly all the message publishing func
@@ -197,22 +197,37 @@ interface and therefore can also handle directly all the message publishing func
Organizations can configure integration configurations to send events to different endpoints -- each
handler maps to a specific integration and checks for the configuration when it receives an event.
Currently, there are integrations / handlers for Slack and webhooks (as mentioned above).
Currently, there are integrations / handlers for Slack, webhooks, and HTTP Event Collector (HEC).
### `OrganizationIntegration`
- The top-level object that enables a specific integration for the organization.
- Includes any properties that apply to the entire integration across all events.
- For Slack, it consists of the token: `{ "token": "xoxb-token-from-slack" }`
- For webhooks, it is `null`. However, even though there is no configuration, an organization must
have a webhook `OrganizationIntegration` to enable configuration via `OrganizationIntegrationConfiguration`.
- For Slack, it consists of the token: `{ "Token": "xoxb-token-from-slack" }`.
- For webhooks, it is optional. Webhooks can either be configured at this level or the configuration level,
but the configuration level takes precedence. However, even though it is optional, an organization must
have a webhook `OrganizationIntegration` (even will a `null``Configuration`) to enable configuration
via `OrganizationIntegrationConfiguration`.
- For HEC, it consists of the scheme, token, and URI:
```json
{
"Scheme": "Bearer",
"Token": "Auth-token-from-HEC-service",
"Uri": "https://example.com/api"
}
```
### `OrganizationIntegrationConfiguration`
- This contains the configurations specific to each `EventType` for the integration.
- `Configuration` contains the event-specific configuration.
- For Slack, this would contain what channel to send the message to: `{ "channelId": "C123456" }`
- For Webhook, this is the URL the request should be sent to: `{ "url": "https://api.example.com" }`
- For webhooks, this is the URL the request should be sent to: `{ "url": "https://api.example.com" }`
- Optionally this also can include a `Scheme` and `Token` if this webhook needs Authentication.
- As stated above, all of this information can be specified here or at the `OrganizationIntegration`
level, but any properties declared here will take precedence over the ones above.
- For HEC, this must be null. HEC is configured only at the `OrganizationIntegration` level.
- `Template` contains a template string that is expected to be filled in with the contents of the actual event.
- The tokens in the string are wrapped in `#` characters. For instance, the UserId would be `#UserId#`.
- The `IntegrationTemplateProcessor` does the actual work of replacing these tokens with introspected values from
@ -225,6 +240,8 @@ Currently, there are integrations / handlers for Slack and webhooks (as mentione
@@ -225,6 +240,8 @@ Currently, there are integrations / handlers for Slack and webhooks (as mentione
- This is the combination of both the `OrganizationIntegration` and `OrganizationIntegrationConfiguration` into
a single object. The combined contents tell the integration's handler all the details needed to send to an
external service.
- `OrganizationIntegrationConfiguration` takes precedence over `OrganizationIntegration` - any keys present in
both will receive the value declared in `OrganizationIntegrationConfiguration`.
- An array of `OrganizationIntegrationConfigurationDetails` is what the `EventIntegrationHandler` fetches from
the database to determine what to publish at the integration level.
@ -189,7 +189,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@@ -189,7 +189,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@ -227,7 +227,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@@ -227,7 +227,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@ -390,7 +390,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@@ -390,7 +390,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@ -477,7 +477,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@@ -477,7 +477,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@ -520,7 +520,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@@ -520,7 +520,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@ -561,7 +561,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@@ -561,7 +561,7 @@ public class OrganizationIntegrationsConfigurationControllerTests
@ -17,13 +17,13 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@@ -17,13 +17,13 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@ -32,25 +32,55 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@@ -32,25 +32,55 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@ -62,14 +92,16 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@@ -62,14 +92,16 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@ -89,13 +121,13 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@@ -89,13 +121,13 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@ -103,7 +135,7 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@@ -103,7 +135,7 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@ -136,33 +168,39 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@@ -136,33 +168,39 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@ -197,6 +235,6 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@@ -197,6 +235,6 @@ public class OrganizationIntegrationConfigurationRequestModelTests
@ -22,6 +22,22 @@ public class OrganizationIntegrationConfigurationDetailsTests
@@ -22,6 +22,22 @@ public class OrganizationIntegrationConfigurationDetailsTests