mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-05 23:53:21 +00:00
[PM-26672] Add Google Workspace integration tests to CI pipeline (#909)
- reorganize integration test files to allow for future additions - add Google Workspace integration tests to the Github workflow - refactor to run tests selective based on changed files and use Azure Key Vault
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { DirectoryType } from "@/src/enums/directoryType";
|
||||
import { IDirectoryService } from "@/src/services/directory.service";
|
||||
import { IDirectoryService } from "@/src/services/directory-services/directory.service";
|
||||
|
||||
export abstract class DirectoryFactoryService {
|
||||
abstract createService(type: DirectoryType): IDirectoryService;
|
||||
|
||||
@@ -768,5 +768,8 @@
|
||||
},
|
||||
"launchWebVault": {
|
||||
"message": "Launch Web Vault"
|
||||
},
|
||||
"authenticationFailed": {
|
||||
"message": "Authentication failed"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ import { DirectoryFactoryService } from "../abstractions/directory-factory.servi
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
|
||||
import { EntraIdDirectoryService } from "./entra-id-directory.service";
|
||||
import { GSuiteDirectoryService } from "./gsuite-directory.service";
|
||||
import { LdapDirectoryService } from "./ldap-directory.service";
|
||||
import { OktaDirectoryService } from "./okta-directory.service";
|
||||
import { OneLoginDirectoryService } from "./onelogin-directory.service";
|
||||
import { EntraIdDirectoryService } from "./directory-services/entra-id-directory.service";
|
||||
import { GSuiteDirectoryService } from "./directory-services/gsuite-directory.service";
|
||||
import { LdapDirectoryService } from "./directory-services/ldap-directory.service";
|
||||
import { OktaDirectoryService } from "./directory-services/okta-directory.service";
|
||||
import { OneLoginDirectoryService } from "./directory-services/onelogin-directory.service";
|
||||
|
||||
export class DefaultDirectoryFactoryService implements DirectoryFactoryService {
|
||||
constructor(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { GroupEntry } from "../models/groupEntry";
|
||||
import { UserEntry } from "../models/userEntry";
|
||||
import { GroupEntry } from "../../models/groupEntry";
|
||||
import { UserEntry } from "../../models/userEntry";
|
||||
|
||||
export interface IDirectoryService {
|
||||
getEntries(force: boolean, test: boolean): Promise<[GroupEntry[], UserEntry[]]>;
|
||||
@@ -7,14 +7,14 @@ import * as graphType from "@microsoft/microsoft-graph-types";
|
||||
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
||||
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { EntraIdConfiguration } from "../models/entraIdConfiguration";
|
||||
import { GroupEntry } from "../models/groupEntry";
|
||||
import { SyncConfiguration } from "../models/syncConfiguration";
|
||||
import { UserEntry } from "../models/userEntry";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { DirectoryType } from "../../enums/directoryType";
|
||||
import { EntraIdConfiguration } from "../../models/entraIdConfiguration";
|
||||
import { GroupEntry } from "../../models/groupEntry";
|
||||
import { SyncConfiguration } from "../../models/syncConfiguration";
|
||||
import { UserEntry } from "../../models/userEntry";
|
||||
import { BaseDirectoryService } from "../baseDirectory.service";
|
||||
|
||||
import { BaseDirectoryService } from "./baseDirectory.service";
|
||||
import { IDirectoryService } from "./directory.service";
|
||||
|
||||
const EntraIdPublicIdentityAuthority = "login.microsoftonline.com";
|
||||
@@ -1,18 +1,18 @@
|
||||
import { config as dotenvConfig } from "dotenv";
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { I18nService } from "../../jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "../../jslib/common/src/abstractions/log.service";
|
||||
import { I18nService } from "../../../jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "../../../jslib/common/src/abstractions/log.service";
|
||||
import {
|
||||
getGSuiteConfiguration,
|
||||
getSyncConfiguration,
|
||||
} from "../../utils/google-workspace/config-fixtures";
|
||||
import { groupFixtures } from "../../utils/google-workspace/group-fixtures";
|
||||
import { userFixtures } from "../../utils/google-workspace/user-fixtures";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
} from "../../../utils/google-workspace/config-fixtures";
|
||||
import { groupFixtures } from "../../../utils/google-workspace/group-fixtures";
|
||||
import { userFixtures } from "../../../utils/google-workspace/user-fixtures";
|
||||
import { DirectoryType } from "../../enums/directoryType";
|
||||
import { StateService } from "../state.service";
|
||||
|
||||
import { GSuiteDirectoryService } from "./gsuite-directory.service";
|
||||
import { StateService } from "./state.service";
|
||||
|
||||
// These tests integrate with a test Google Workspace instance.
|
||||
// Credentials are located in the shared Bitwarden collection for Directory Connector testing.
|
||||
@@ -24,10 +24,13 @@ dotenvConfig({ path: "utils/.env" });
|
||||
// These filters target integration test data.
|
||||
// These should return data that matches the user and group fixtures exactly.
|
||||
// There may be additional data present if not used.
|
||||
const INTEGRATION_USER_FILTER =
|
||||
"exclude:integration-user-a@bwrox.dev|orgUnitPath='/Integration testing'";
|
||||
const INTEGRATION_USER_FILTER = "|orgUnitPath='/Integration testing'";
|
||||
const INTEGRATION_GROUP_FILTER = "|name:Integration*";
|
||||
|
||||
// These tests are slow!
|
||||
// Increase the default timeout from 5s to 15s
|
||||
jest.setTimeout(15000);
|
||||
|
||||
describe("gsuiteDirectoryService", () => {
|
||||
let logService: MockProxy<LogService>;
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
@@ -4,14 +4,14 @@ import { admin_directory_v1, google } from "googleapis";
|
||||
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
||||
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { GroupEntry } from "../models/groupEntry";
|
||||
import { GSuiteConfiguration } from "../models/gsuiteConfiguration";
|
||||
import { SyncConfiguration } from "../models/syncConfiguration";
|
||||
import { UserEntry } from "../models/userEntry";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { DirectoryType } from "../../enums/directoryType";
|
||||
import { GroupEntry } from "../../models/groupEntry";
|
||||
import { GSuiteConfiguration } from "../../models/gsuiteConfiguration";
|
||||
import { SyncConfiguration } from "../../models/syncConfiguration";
|
||||
import { UserEntry } from "../../models/userEntry";
|
||||
import { BaseDirectoryService } from "../baseDirectory.service";
|
||||
|
||||
import { BaseDirectoryService } from "./baseDirectory.service";
|
||||
import { IDirectoryService } from "./directory.service";
|
||||
|
||||
export class GSuiteDirectoryService extends BaseDirectoryService implements IDirectoryService {
|
||||
@@ -253,7 +253,15 @@ export class GSuiteDirectoryService extends BaseDirectoryService implements IDir
|
||||
],
|
||||
});
|
||||
|
||||
await this.client.authorize();
|
||||
try {
|
||||
await this.client.authorize();
|
||||
} catch (error) {
|
||||
// Catch and rethrow this to sanitize any sensitive info (e.g. private key) in the error message
|
||||
this.logService.error(
|
||||
`Google Workspace authentication failed: ${error?.name || "Unknown error"}`,
|
||||
);
|
||||
throw new Error(this.i18nService.t("authenticationFailed"));
|
||||
}
|
||||
|
||||
this.authParams = {
|
||||
auth: this.client,
|
||||
@@ -1,14 +1,17 @@
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { I18nService } from "../../jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "../../jslib/common/src/abstractions/log.service";
|
||||
import { getLdapConfiguration, getSyncConfiguration } from "../../utils/openldap/config-fixtures";
|
||||
import { groupFixtures } from "../../utils/openldap/group-fixtures";
|
||||
import { userFixtures } from "../../utils/openldap/user-fixtures";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { I18nService } from "../../../jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "../../../jslib/common/src/abstractions/log.service";
|
||||
import {
|
||||
getLdapConfiguration,
|
||||
getSyncConfiguration,
|
||||
} from "../../../utils/openldap/config-fixtures";
|
||||
import { groupFixtures } from "../../../utils/openldap/group-fixtures";
|
||||
import { userFixtures } from "../../../utils/openldap/user-fixtures";
|
||||
import { DirectoryType } from "../../enums/directoryType";
|
||||
import { StateService } from "../state.service";
|
||||
|
||||
import { LdapDirectoryService } from "./ldap-directory.service";
|
||||
import { StateService } from "./state.service";
|
||||
|
||||
// These tests integrate with the OpenLDAP docker image and seed data located in the openldap folder.
|
||||
// To run theses tests:
|
||||
@@ -7,12 +7,12 @@ import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
||||
import { Utils } from "@/jslib/common/src/misc/utils";
|
||||
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { GroupEntry } from "../models/groupEntry";
|
||||
import { LdapConfiguration } from "../models/ldapConfiguration";
|
||||
import { SyncConfiguration } from "../models/syncConfiguration";
|
||||
import { UserEntry } from "../models/userEntry";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { DirectoryType } from "../../enums/directoryType";
|
||||
import { GroupEntry } from "../../models/groupEntry";
|
||||
import { LdapConfiguration } from "../../models/ldapConfiguration";
|
||||
import { SyncConfiguration } from "../../models/syncConfiguration";
|
||||
import { UserEntry } from "../../models/userEntry";
|
||||
|
||||
import { IDirectoryService } from "./directory.service";
|
||||
|
||||
@@ -3,14 +3,14 @@ import * as https from "https";
|
||||
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
||||
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { GroupEntry } from "../models/groupEntry";
|
||||
import { OktaConfiguration } from "../models/oktaConfiguration";
|
||||
import { SyncConfiguration } from "../models/syncConfiguration";
|
||||
import { UserEntry } from "../models/userEntry";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { DirectoryType } from "../../enums/directoryType";
|
||||
import { GroupEntry } from "../../models/groupEntry";
|
||||
import { OktaConfiguration } from "../../models/oktaConfiguration";
|
||||
import { SyncConfiguration } from "../../models/syncConfiguration";
|
||||
import { UserEntry } from "../../models/userEntry";
|
||||
import { BaseDirectoryService } from "../baseDirectory.service";
|
||||
|
||||
import { BaseDirectoryService } from "./baseDirectory.service";
|
||||
import { IDirectoryService } from "./directory.service";
|
||||
|
||||
const DelayBetweenBuildGroupCallsInMilliseconds = 500;
|
||||
@@ -1,14 +1,14 @@
|
||||
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
||||
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { GroupEntry } from "../models/groupEntry";
|
||||
import { OneLoginConfiguration } from "../models/oneLoginConfiguration";
|
||||
import { SyncConfiguration } from "../models/syncConfiguration";
|
||||
import { UserEntry } from "../models/userEntry";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { DirectoryType } from "../../enums/directoryType";
|
||||
import { GroupEntry } from "../../models/groupEntry";
|
||||
import { OneLoginConfiguration } from "../../models/oneLoginConfiguration";
|
||||
import { SyncConfiguration } from "../../models/syncConfiguration";
|
||||
import { UserEntry } from "../../models/userEntry";
|
||||
import { BaseDirectoryService } from "../baseDirectory.service";
|
||||
|
||||
import { BaseDirectoryService } from "./baseDirectory.service";
|
||||
import { IDirectoryService } from "./directory.service";
|
||||
|
||||
// Basic email validation: something@something.something
|
||||
@@ -12,7 +12,7 @@ import { DirectoryFactoryService } from "../abstractions/directory-factory.servi
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
|
||||
import { BatchRequestBuilder } from "./batch-request-builder";
|
||||
import { LdapDirectoryService } from "./ldap-directory.service";
|
||||
import { LdapDirectoryService } from "./directory-services/ldap-directory.service";
|
||||
import { SingleRequestBuilder } from "./single-request-builder";
|
||||
import { StateService } from "./state.service";
|
||||
import { SyncService } from "./sync.service";
|
||||
|
||||
@@ -11,8 +11,8 @@ import { DirectoryFactoryService } from "../abstractions/directory-factory.servi
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
|
||||
import { BatchRequestBuilder } from "./batch-request-builder";
|
||||
import { LdapDirectoryService } from "./directory-services/ldap-directory.service";
|
||||
import { I18nService } from "./i18n.service";
|
||||
import { LdapDirectoryService } from "./ldap-directory.service";
|
||||
import { SingleRequestBuilder } from "./single-request-builder";
|
||||
import { StateService } from "./state.service";
|
||||
import { SyncService } from "./sync.service";
|
||||
|
||||
Reference in New Issue
Block a user