mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-05 23:53:21 +00:00
[PM-26671] Google workspace integration tests (#894)
Add tests for Google Workspace - not enabled in CI yet
This commit is contained in:
@@ -2,8 +2,8 @@ import { GetUniqueString } from "@/jslib/common/spec/utils";
|
||||
|
||||
import { UserEntry } from "@/src/models/userEntry";
|
||||
|
||||
import { groupSimulator, userSimulator } from "../../utils/request-builder-helper";
|
||||
import { RequestBuilderOptions } from "../abstractions/request-builder.service";
|
||||
import { groupSimulator, userSimulator } from "../utils/request-builder-helper";
|
||||
|
||||
import { BatchRequestBuilder } from "./batch-request-builder";
|
||||
|
||||
|
||||
82
src/services/gsuite-directory.service.integration.spec.ts
Normal file
82
src/services/gsuite-directory.service.integration.spec.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
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 {
|
||||
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";
|
||||
|
||||
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.
|
||||
// Place the .env file attachment in the utils folder.
|
||||
|
||||
// Load .env variables
|
||||
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_GROUP_FILTER = "|name:Integration*";
|
||||
|
||||
describe("gsuiteDirectoryService", () => {
|
||||
let logService: MockProxy<LogService>;
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
let stateService: MockProxy<StateService>;
|
||||
|
||||
let directoryService: GSuiteDirectoryService;
|
||||
|
||||
beforeEach(() => {
|
||||
logService = mock();
|
||||
i18nService = mock();
|
||||
stateService = mock();
|
||||
|
||||
stateService.getDirectoryType.mockResolvedValue(DirectoryType.GSuite);
|
||||
stateService.getLastUserSync.mockResolvedValue(null); // do not filter results by last modified date
|
||||
i18nService.t.mockImplementation((id) => id); // passthrough implementation for any error messages
|
||||
|
||||
directoryService = new GSuiteDirectoryService(logService, i18nService, stateService);
|
||||
});
|
||||
|
||||
it("syncs without using filters (includes test data)", async () => {
|
||||
const directoryConfig = getGSuiteConfiguration();
|
||||
stateService.getDirectory.calledWith(DirectoryType.GSuite).mockResolvedValue(directoryConfig);
|
||||
|
||||
const syncConfig = getSyncConfiguration({
|
||||
groups: true,
|
||||
users: true,
|
||||
});
|
||||
stateService.getSync.mockResolvedValue(syncConfig);
|
||||
|
||||
const result = await directoryService.getEntries(true, true);
|
||||
|
||||
expect(result[0]).toEqual(expect.arrayContaining(groupFixtures));
|
||||
expect(result[1]).toEqual(expect.arrayContaining(userFixtures));
|
||||
});
|
||||
|
||||
it("syncs using user and group filters (exact match for test data)", async () => {
|
||||
const directoryConfig = getGSuiteConfiguration();
|
||||
stateService.getDirectory.calledWith(DirectoryType.GSuite).mockResolvedValue(directoryConfig);
|
||||
|
||||
const syncConfig = getSyncConfiguration({
|
||||
groups: true,
|
||||
users: true,
|
||||
userFilter: INTEGRATION_USER_FILTER,
|
||||
groupFilter: INTEGRATION_GROUP_FILTER,
|
||||
});
|
||||
stateService.getSync.mockResolvedValue(syncConfig);
|
||||
|
||||
const result = await directoryService.getEntries(true, true);
|
||||
|
||||
expect(result).toEqual([groupFixtures, userFixtures]);
|
||||
});
|
||||
});
|
||||
@@ -2,10 +2,10 @@ 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 { groupFixtures } from "../../openldap/group-fixtures";
|
||||
import { userFixtures } from "../../openldap/user-fixtures";
|
||||
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 { getLdapConfiguration, getSyncConfiguration } from "../utils/test-fixtures";
|
||||
|
||||
import { LdapDirectoryService } from "./ldap-directory.service";
|
||||
import { StateService } from "./state.service";
|
||||
@@ -52,7 +52,7 @@ describe("ldapDirectoryService", () => {
|
||||
getLdapConfiguration({
|
||||
ssl: true,
|
||||
startTls: true,
|
||||
tlsCaPath: "./openldap/certs/rootCA.pem",
|
||||
tlsCaPath: "./utils/openldap/certs/rootCA.pem",
|
||||
}),
|
||||
);
|
||||
stateService.getSync.mockResolvedValue(getSyncConfiguration({ groups: true, users: true }));
|
||||
@@ -67,7 +67,7 @@ describe("ldapDirectoryService", () => {
|
||||
getLdapConfiguration({
|
||||
port: 1636,
|
||||
ssl: true,
|
||||
sslCaPath: "./openldap/certs/rootCA.pem",
|
||||
sslCaPath: "./utils/openldap/certs/rootCA.pem",
|
||||
}),
|
||||
);
|
||||
stateService.getSync.mockResolvedValue(getSyncConfiguration({ groups: true, users: true }));
|
||||
|
||||
@@ -2,8 +2,8 @@ import { GetUniqueString } from "@/jslib/common/spec/utils";
|
||||
|
||||
import { UserEntry } from "@/src/models/userEntry";
|
||||
|
||||
import { groupSimulator, userSimulator } from "../../utils/request-builder-helper";
|
||||
import { RequestBuilderOptions } from "../abstractions/request-builder.service";
|
||||
import { groupSimulator, userSimulator } from "../utils/request-builder-helper";
|
||||
|
||||
import { SingleRequestBuilder } from "./single-request-builder";
|
||||
|
||||
|
||||
@@ -7,11 +7,9 @@ import { EnvironmentService } from "@/jslib/common/src/services/environment.serv
|
||||
|
||||
import { I18nService } from "../../jslib/common/src/abstractions/i18n.service";
|
||||
import { LogService } from "../../jslib/common/src/abstractions/log.service";
|
||||
import { groupFixtures } from "../../openldap/group-fixtures";
|
||||
import { userFixtures } from "../../openldap/user-fixtures";
|
||||
import { getLdapConfiguration, getSyncConfiguration } from "../../utils/openldap/config-fixtures";
|
||||
import { DirectoryFactoryService } from "../abstractions/directory-factory.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { getLdapConfiguration, getSyncConfiguration } from "../utils/test-fixtures";
|
||||
|
||||
import { BatchRequestBuilder } from "./batch-request-builder";
|
||||
import { LdapDirectoryService } from "./ldap-directory.service";
|
||||
@@ -20,6 +18,9 @@ import { StateService } from "./state.service";
|
||||
import { SyncService } from "./sync.service";
|
||||
import * as constants from "./sync.service";
|
||||
|
||||
import { groupFixtures } from "@/utils/openldap/group-fixtures";
|
||||
import { userFixtures } from "@/utils/openldap/user-fixtures";
|
||||
|
||||
describe("SyncService", () => {
|
||||
let logService: MockProxy<LogService>;
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
|
||||
@@ -6,9 +6,9 @@ import { MessagingService } from "@/jslib/common/src/abstractions/messaging.serv
|
||||
import { OrganizationImportRequest } from "@/jslib/common/src/models/request/organizationImportRequest";
|
||||
import { ApiService } from "@/jslib/common/src/services/api.service";
|
||||
|
||||
import { getSyncConfiguration } from "../../utils/openldap/config-fixtures";
|
||||
import { DirectoryFactoryService } from "../abstractions/directory-factory.service";
|
||||
import { DirectoryType } from "../enums/directoryType";
|
||||
import { getSyncConfiguration } from "../utils/test-fixtures";
|
||||
|
||||
import { BatchRequestBuilder } from "./batch-request-builder";
|
||||
import { I18nService } from "./i18n.service";
|
||||
@@ -18,8 +18,8 @@ import { StateService } from "./state.service";
|
||||
import { SyncService } from "./sync.service";
|
||||
import * as constants from "./sync.service";
|
||||
|
||||
import { groupFixtures } from "@/openldap/group-fixtures";
|
||||
import { userFixtures } from "@/openldap/user-fixtures";
|
||||
import { groupFixtures } from "@/utils/openldap/group-fixtures";
|
||||
import { userFixtures } from "@/utils/openldap/user-fixtures";
|
||||
|
||||
describe("SyncService", () => {
|
||||
let cryptoFunctionService: MockProxy<CryptoFunctionService>;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { GetUniqueString } from "@/jslib/common/spec/utils";
|
||||
|
||||
import { GroupEntry } from "../models/groupEntry";
|
||||
import { UserEntry } from "../models/userEntry";
|
||||
|
||||
export function userSimulator(userCount: number): UserEntry[] {
|
||||
const users: UserEntry[] = [];
|
||||
while (userCount > 0) {
|
||||
const userEntry = new UserEntry();
|
||||
userEntry.email = GetUniqueString() + "@example.com";
|
||||
users.push(userEntry);
|
||||
userCount--;
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
export function groupSimulator(groupCount: number): GroupEntry[] {
|
||||
const groups: GroupEntry[] = [];
|
||||
while (groupCount > 0) {
|
||||
const groupEntry = new GroupEntry();
|
||||
groupEntry.name = GetUniqueString();
|
||||
groups.push(groupEntry);
|
||||
groupCount--;
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import { LdapConfiguration } from "../models/ldapConfiguration";
|
||||
import { SyncConfiguration } from "../models/syncConfiguration";
|
||||
|
||||
/**
|
||||
* @returns a basic ldap configuration without TLS/SSL enabled. Can be overridden by passing in a partial configuration.
|
||||
*/
|
||||
export const getLdapConfiguration = (config?: Partial<LdapConfiguration>): LdapConfiguration => ({
|
||||
ssl: false,
|
||||
startTls: false,
|
||||
tlsCaPath: null,
|
||||
sslAllowUnauthorized: false,
|
||||
sslCertPath: null,
|
||||
sslKeyPath: null,
|
||||
sslCaPath: null,
|
||||
hostname: "localhost",
|
||||
port: 1389,
|
||||
domain: null,
|
||||
rootPath: "dc=bitwarden,dc=com",
|
||||
currentUser: false,
|
||||
username: "cn=admin,dc=bitwarden,dc=com",
|
||||
password: "admin",
|
||||
ad: false,
|
||||
pagedSearch: false,
|
||||
...(config ?? {}),
|
||||
});
|
||||
|
||||
/**
|
||||
* @returns a basic sync configuration. Can be overridden by passing in a partial configuration.
|
||||
*/
|
||||
export const getSyncConfiguration = (config?: Partial<SyncConfiguration>): SyncConfiguration => ({
|
||||
users: false,
|
||||
groups: false,
|
||||
interval: 5,
|
||||
userFilter: null,
|
||||
groupFilter: null,
|
||||
removeDisabled: false,
|
||||
overwriteExisting: false,
|
||||
largeImport: false,
|
||||
// Ldap properties
|
||||
groupObjectClass: "posixGroup",
|
||||
userObjectClass: "person",
|
||||
groupPath: null,
|
||||
userPath: null,
|
||||
groupNameAttribute: "cn",
|
||||
userEmailAttribute: "mail",
|
||||
memberAttribute: "memberUid",
|
||||
useEmailPrefixSuffix: false,
|
||||
emailPrefixAttribute: "sAMAccountName",
|
||||
emailSuffix: null,
|
||||
creationDateAttribute: "whenCreated",
|
||||
revisionDateAttribute: "whenChanged",
|
||||
...(config ?? {}),
|
||||
});
|
||||
Reference in New Issue
Block a user