mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
[PM-23822] [PM-23823] Organization integration and configuration api services (#15763)
* Adding the organization integration api service and test cases * Adding configuration api files and test cases. Fixing the id guids and integration type and event type nullable * Adding get endpoint methods to the integration and config service and test cases * fixing type check issues * lowercase directory name
This commit is contained in:
@@ -0,0 +1 @@
|
||||
export * from "./services";
|
||||
@@ -0,0 +1,20 @@
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
|
||||
export class OrganizationIntegrationConfigurationRequest {
|
||||
eventType?: EventType | null = null;
|
||||
configuration?: string | null = null;
|
||||
filters?: string | null = null;
|
||||
template?: string | null = null;
|
||||
|
||||
constructor(
|
||||
eventType?: EventType | null,
|
||||
configuration?: string | null,
|
||||
filters?: string | null,
|
||||
template?: string | null,
|
||||
) {
|
||||
this.eventType = eventType;
|
||||
this.configuration = configuration;
|
||||
this.filters = filters;
|
||||
this.template = template;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { BaseResponse } from "@bitwarden/common/models/response/base.response";
|
||||
import { OrganizationIntegrationConfigurationId } from "@bitwarden/common/types/guid";
|
||||
|
||||
export class OrganizationIntegrationConfigurationResponse extends BaseResponse {
|
||||
id: OrganizationIntegrationConfigurationId;
|
||||
eventType?: EventType;
|
||||
configuration?: string;
|
||||
filters?: string;
|
||||
template?: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.eventType = this.getResponseProperty("EventType");
|
||||
this.configuration = this.getResponseProperty("Configuration");
|
||||
this.filters = this.getResponseProperty("Filters");
|
||||
this.template = this.getResponseProperty("Template");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { OrganizationIntegrationType } from "./organization-integration-type";
|
||||
|
||||
export class OrganizationIntegrationRequest {
|
||||
type: OrganizationIntegrationType;
|
||||
configuration?: string;
|
||||
|
||||
constructor(integrationType: OrganizationIntegrationType, configuration?: string) {
|
||||
this.type = integrationType;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { BaseResponse } from "@bitwarden/common/models/response/base.response";
|
||||
import { OrganizationIntegrationId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { OrganizationIntegrationType } from "./organization-integration-type";
|
||||
|
||||
export class OrganizationIntegrationResponse extends BaseResponse {
|
||||
id: OrganizationIntegrationId;
|
||||
organizationIntegrationType: OrganizationIntegrationType;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.organizationIntegrationType = this.getResponseProperty("Type");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export const OrganizationIntegrationServiceType = Object.freeze({
|
||||
CrowdStrike: "CrowdStrike",
|
||||
} as const);
|
||||
|
||||
export type OrganizationIntegrationServiceType =
|
||||
(typeof OrganizationIntegrationServiceType)[keyof typeof OrganizationIntegrationServiceType];
|
||||
@@ -0,0 +1,10 @@
|
||||
export const OrganizationIntegrationType = Object.freeze({
|
||||
CloudBillingSync: 1,
|
||||
Scim: 2,
|
||||
Slack: 3,
|
||||
Webhook: 4,
|
||||
Hec: 5,
|
||||
} as const);
|
||||
|
||||
export type OrganizationIntegrationType =
|
||||
(typeof OrganizationIntegrationType)[keyof typeof OrganizationIntegrationType];
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./organization-integration-api.service";
|
||||
export * from "./organization-integration-configuration-api.service";
|
||||
@@ -0,0 +1,115 @@
|
||||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { OrganizationId, OrganizationIntegrationId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { OrganizationIntegrationRequest } from "../models/organization-integration-request";
|
||||
import { OrganizationIntegrationServiceType } from "../models/organization-integration-service-type";
|
||||
import { OrganizationIntegrationType } from "../models/organization-integration-type";
|
||||
|
||||
import { OrganizationIntegrationApiService } from "./organization-integration-api.service";
|
||||
|
||||
export const mockIntegrationResponse: any = {
|
||||
id: "1" as OrganizationIntegrationId,
|
||||
organizationIntegrationType: OrganizationIntegrationType.Hec,
|
||||
};
|
||||
|
||||
export const mockIntegrationResponses: any[] = [
|
||||
{
|
||||
id: "1" as OrganizationIntegrationId,
|
||||
OrganizationIntegrationType: OrganizationIntegrationType.Hec,
|
||||
},
|
||||
{
|
||||
id: "2" as OrganizationIntegrationId,
|
||||
OrganizationIntegrationType: OrganizationIntegrationType.Webhook,
|
||||
},
|
||||
];
|
||||
|
||||
describe("OrganizationIntegrationApiService", () => {
|
||||
let service: OrganizationIntegrationApiService;
|
||||
const apiService = mock<ApiService>();
|
||||
|
||||
beforeEach(() => {
|
||||
service = new OrganizationIntegrationApiService(apiService);
|
||||
});
|
||||
|
||||
it("should be created", () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should call apiService.send with correct parameters for getOrganizationIntegrations", async () => {
|
||||
const orgId = "org1" as OrganizationId;
|
||||
|
||||
apiService.send.mockReturnValue(Promise.resolve(mockIntegrationResponses));
|
||||
|
||||
const result = await service.getOrganizationIntegrations(orgId);
|
||||
expect(result).toEqual(mockIntegrationResponses);
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"GET",
|
||||
`organizations/${orgId}/integrations`,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("should call apiService.send with correct parameters for createOrganizationIntegration", async () => {
|
||||
const request = new OrganizationIntegrationRequest(
|
||||
OrganizationIntegrationType.Hec,
|
||||
`{ 'uri:' 'test.com', 'scheme:' 'bearer', 'token:' '123456789', 'service:' '${OrganizationIntegrationServiceType.CrowdStrike}' }`,
|
||||
);
|
||||
const orgId = "org1" as OrganizationId;
|
||||
|
||||
apiService.send.mockReturnValue(Promise.resolve(mockIntegrationResponse));
|
||||
|
||||
const result = await service.createOrganizationIntegration(orgId, request);
|
||||
expect(result.organizationIntegrationType).toEqual(
|
||||
mockIntegrationResponse.organizationIntegrationType,
|
||||
);
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"POST",
|
||||
`organizations/${orgId.toString()}/integrations`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("should call apiService.send with the correct parameters for updateOrganizationIntegration", async () => {
|
||||
const request = new OrganizationIntegrationRequest(
|
||||
OrganizationIntegrationType.Hec,
|
||||
`{ 'uri:' 'test.com', 'scheme:' 'bearer', 'token:' '123456789', 'service:' '${OrganizationIntegrationServiceType.CrowdStrike}' }`,
|
||||
);
|
||||
const orgId = "org1" as OrganizationId;
|
||||
const integrationId = "integration1" as OrganizationIntegrationId;
|
||||
|
||||
apiService.send.mockReturnValue(Promise.resolve(mockIntegrationResponse));
|
||||
|
||||
const result = await service.updateOrganizationIntegration(orgId, integrationId, request);
|
||||
expect(result.organizationIntegrationType).toEqual(
|
||||
mockIntegrationResponse.organizationIntegrationType,
|
||||
);
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"PUT",
|
||||
`organizations/${orgId}/integrations/${integrationId}`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("should call apiService.send with the correct parameters for deleteOrganizationIntegration", async () => {
|
||||
const orgId = "org1" as OrganizationId;
|
||||
const integrationId = "integration1" as OrganizationIntegrationId;
|
||||
|
||||
await service.deleteOrganizationIntegration(orgId, integrationId);
|
||||
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"DELETE",
|
||||
`organizations/${orgId}/integrations/${integrationId}`,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { OrganizationId, OrganizationIntegrationId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { OrganizationIntegrationRequest } from "../models/organization-integration-request";
|
||||
import { OrganizationIntegrationResponse } from "../models/organization-integration-response";
|
||||
|
||||
@Injectable()
|
||||
export class OrganizationIntegrationApiService {
|
||||
constructor(private apiService: ApiService) {}
|
||||
|
||||
async getOrganizationIntegrations(
|
||||
orgId: OrganizationId,
|
||||
): Promise<OrganizationIntegrationResponse[]> {
|
||||
const response = await this.apiService.send(
|
||||
"GET",
|
||||
`organizations/${orgId}/integrations`,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
async createOrganizationIntegration(
|
||||
orgId: OrganizationId,
|
||||
request: OrganizationIntegrationRequest,
|
||||
): Promise<OrganizationIntegrationResponse> {
|
||||
const response = await this.apiService.send(
|
||||
"POST",
|
||||
`organizations/${orgId}/integrations`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
async updateOrganizationIntegration(
|
||||
orgId: OrganizationId,
|
||||
integrationId: OrganizationIntegrationId,
|
||||
request: OrganizationIntegrationRequest,
|
||||
): Promise<OrganizationIntegrationResponse> {
|
||||
const response = await this.apiService.send(
|
||||
"PUT",
|
||||
`organizations/${orgId}/integrations/${integrationId}`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
async deleteOrganizationIntegration(
|
||||
orgId: OrganizationId,
|
||||
integrationId: OrganizationIntegrationId,
|
||||
): Promise<any> {
|
||||
await this.apiService.send(
|
||||
"DELETE",
|
||||
`organizations/${orgId}/integrations/${integrationId}`,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import {
|
||||
OrganizationId,
|
||||
OrganizationIntegrationId,
|
||||
OrganizationIntegrationConfigurationId,
|
||||
} from "@bitwarden/common/types/guid";
|
||||
|
||||
import { OrganizationIntegrationConfigurationRequest } from "../models/organization-integration-configuration-request";
|
||||
|
||||
import { OrganizationIntegrationConfigurationApiService } from "./organization-integration-configuration-api.service";
|
||||
|
||||
export const mockConfigurationResponse: any = {
|
||||
id: "1" as OrganizationIntegrationConfigurationId,
|
||||
template: "{ 'event': '#EventMessage#', 'source': 'Bitwarden', 'index': 'testIndex' }",
|
||||
};
|
||||
|
||||
export const mockConfigurationResponses: any[] = [
|
||||
{
|
||||
id: "1" as OrganizationIntegrationConfigurationId,
|
||||
template: "{ 'event': '#EventMessage#', 'source': 'Bitwarden', 'index': 'testIndex' }",
|
||||
},
|
||||
{
|
||||
id: "2" as OrganizationIntegrationConfigurationId,
|
||||
template: "{ 'event': '#EventMessage#', 'source': 'Bitwarden', 'index': 'otherIndex' }",
|
||||
},
|
||||
];
|
||||
|
||||
describe("OrganizationIntegrationConfigurationApiService", () => {
|
||||
let service: OrganizationIntegrationConfigurationApiService;
|
||||
const apiService = mock<ApiService>();
|
||||
|
||||
beforeEach(() => {
|
||||
service = new OrganizationIntegrationConfigurationApiService(apiService);
|
||||
});
|
||||
|
||||
it("should be created", () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should call apiService.send with correct parameters for getOrganizationIntegrationConfigurations", async () => {
|
||||
const orgId = "org1" as OrganizationId;
|
||||
const integrationId = "integration1" as OrganizationIntegrationId;
|
||||
|
||||
apiService.send.mockReturnValue(Promise.resolve(mockConfigurationResponses));
|
||||
|
||||
const result = await service.getOrganizationIntegrationConfigurations(orgId, integrationId);
|
||||
expect(result).toEqual(mockConfigurationResponses);
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"GET",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations`,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("should call apiService.send with correct parameters for createOrganizationIntegrationConfiguration", async () => {
|
||||
const request = new OrganizationIntegrationConfigurationRequest(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"{ 'event': '#EventMessage#', 'source': 'Bitwarden', 'index': 'testIndex' }",
|
||||
);
|
||||
const orgId = "org1" as OrganizationId;
|
||||
const integrationId = "integration1" as OrganizationIntegrationId;
|
||||
|
||||
apiService.send.mockReturnValue(Promise.resolve(mockConfigurationResponse));
|
||||
|
||||
const result = await service.createOrganizationIntegrationConfiguration(
|
||||
orgId,
|
||||
integrationId,
|
||||
request,
|
||||
);
|
||||
expect(result.eventType).toEqual(mockConfigurationResponse.eventType);
|
||||
expect(result.template).toEqual(mockConfigurationResponse.template);
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"POST",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("should call apiService.send with correct parameters for updateOrganizationIntegrationConfiguration", async () => {
|
||||
const request = new OrganizationIntegrationConfigurationRequest(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"{ 'event': '#EventMessage#', 'source': 'Bitwarden', 'index': 'testIndex' }",
|
||||
);
|
||||
const orgId = "org1" as OrganizationId;
|
||||
const integrationId = "integration1" as OrganizationIntegrationId;
|
||||
const configurationId = "configurationId" as OrganizationIntegrationConfigurationId;
|
||||
|
||||
apiService.send.mockReturnValue(Promise.resolve(mockConfigurationResponse));
|
||||
|
||||
const result = await service.updateOrganizationIntegrationConfiguration(
|
||||
orgId,
|
||||
integrationId,
|
||||
configurationId,
|
||||
request,
|
||||
);
|
||||
expect(result.eventType).toEqual(mockConfigurationResponse.eventType);
|
||||
expect(result.template).toEqual(mockConfigurationResponse.template);
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"PUT",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations/${configurationId}`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("should call apiService.send with correct parameters for deleteOrganizationIntegrationConfiguration", async () => {
|
||||
const orgId = "org1" as OrganizationId;
|
||||
const integrationId = "integration1" as OrganizationIntegrationId;
|
||||
const configurationId = "configurationId" as OrganizationIntegrationConfigurationId;
|
||||
|
||||
await service.deleteOrganizationIntegrationConfiguration(orgId, integrationId, configurationId);
|
||||
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"DELETE",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations/${configurationId}`,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import {
|
||||
OrganizationId,
|
||||
OrganizationIntegrationConfigurationId,
|
||||
OrganizationIntegrationId,
|
||||
} from "@bitwarden/common/types/guid";
|
||||
|
||||
import { OrganizationIntegrationConfigurationRequest } from "../models/organization-integration-configuration-request";
|
||||
import { OrganizationIntegrationConfigurationResponse } from "../models/organization-integration-configuration-response";
|
||||
|
||||
@Injectable()
|
||||
export class OrganizationIntegrationConfigurationApiService {
|
||||
constructor(private apiService: ApiService) {}
|
||||
|
||||
async getOrganizationIntegrationConfigurations(
|
||||
orgId: OrganizationId,
|
||||
integrationId: OrganizationIntegrationId,
|
||||
): Promise<OrganizationIntegrationConfigurationResponse[]> {
|
||||
const responses = await this.apiService.send(
|
||||
"GET",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations`,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
return responses;
|
||||
}
|
||||
|
||||
async createOrganizationIntegrationConfiguration(
|
||||
orgId: OrganizationId,
|
||||
integrationId: OrganizationIntegrationId,
|
||||
request: OrganizationIntegrationConfigurationRequest,
|
||||
): Promise<OrganizationIntegrationConfigurationResponse> {
|
||||
const response = await this.apiService.send(
|
||||
"POST",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
async updateOrganizationIntegrationConfiguration(
|
||||
orgId: OrganizationId,
|
||||
integrationId: OrganizationIntegrationId,
|
||||
configurationId: OrganizationIntegrationConfigurationId,
|
||||
request: OrganizationIntegrationConfigurationRequest,
|
||||
): Promise<OrganizationIntegrationConfigurationResponse> {
|
||||
const response = await this.apiService.send(
|
||||
"PUT",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations/${configurationId}`,
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
async deleteOrganizationIntegrationConfiguration(
|
||||
orgId: OrganizationId,
|
||||
integrationId: OrganizationIntegrationId,
|
||||
configurationId: OrganizationIntegrationConfigurationId,
|
||||
): Promise<any> {
|
||||
await this.apiService.send(
|
||||
"DELETE",
|
||||
`organizations/${orgId}/integrations/${integrationId}/configurations/${configurationId}`,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -15,3 +15,8 @@ export type IndexedEntityId = Opaque<string, "IndexedEntityId">;
|
||||
export type SecurityTaskId = Opaque<string, "SecurityTaskId">;
|
||||
export type NotificationId = Opaque<string, "NotificationId">;
|
||||
export type EmergencyAccessId = Opaque<string, "EmergencyAccessId">;
|
||||
export type OrganizationIntegrationId = Opaque<string, "OrganizationIntegrationId">;
|
||||
export type OrganizationIntegrationConfigurationId = Opaque<
|
||||
string,
|
||||
"OrganizationIntegrationConfigurationId"
|
||||
>;
|
||||
|
||||
Reference in New Issue
Block a user