1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-05 23:53:21 +00:00

test command for cli

This commit is contained in:
Kyle Spearrin
2019-03-16 00:45:17 -04:00
parent 183b54f9b8
commit 46827cdaa0
8 changed files with 181 additions and 61 deletions

View File

@@ -12,18 +12,16 @@ import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { StateService } from 'jslib/abstractions/state.service';
import { AzureDirectoryService } from '../../services/azure-directory.service';
import { GSuiteDirectoryService } from '../../services/gsuite-directory.service';
import { LdapDirectoryService } from '../../services/ldap-directory.service';
import { SyncService } from '../../services/sync.service';
import { Entry } from '../../models/entry';
import { GroupEntry } from '../../models/groupEntry';
import { UserEntry } from '../../models/userEntry';
import { ConfigurationService } from '../../services/configuration.service';
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { ConnectorUtils } from '../../utils';
const BroadcasterSubscriptionId = 'DashboardComponent';
@Component({
@@ -105,63 +103,22 @@ export class DashboardComponent implements OnInit, OnDestroy {
this.simPromise = new Promise(async (resolve, reject) => {
try {
const result = await this.syncService.sync(!this.simSinceLast, true);
if (result[0] != null) {
this.simGroups = result[0];
}
if (result[1] != null) {
this.simUsers = result[1];
}
const result = await ConnectorUtils.simulate(this.syncService, this.i18nService, this.simSinceLast);
this.simGroups = result.groups;
this.simUsers = result.users;
this.simEnabledUsers = result.enabledUsers;
this.simDisabledUsers = result.disabledUsers;
this.simDeletedUsers = result.deletedUsers;
} catch (e) {
this.simGroups = null;
this.simUsers = null;
reject(e || this.i18nService.t('syncError'));
reject(e);
return;
}
const userMap = new Map<string, UserEntry>();
this.sort(this.simUsers);
for (const u of this.simUsers) {
userMap.set(u.externalId, u);
if (u.deleted) {
this.simDeletedUsers.push(u);
} else if (u.disabled) {
this.simDisabledUsers.push(u);
} else {
this.simEnabledUsers.push(u);
}
}
this.sort(this.simGroups);
for (const g of this.simGroups) {
if (g.userMemberExternalIds == null) {
continue;
}
const anyG = (g as any);
anyG.users = [];
for (const uid of g.userMemberExternalIds) {
if (userMap.has(uid)) {
anyG.users.push(userMap.get(uid));
} else {
anyG.users.push({ displayName: uid });
}
}
this.sort(anyG.users);
}
resolve();
});
}
private sort(arr: Entry[]) {
arr.sort((a, b) => {
return this.i18nService.collator ? this.i18nService.collator.compare(a.displayName, b.displayName) :
a.displayName.localeCompare(b.displayName);
});
}
private async updateLastSync() {
this.lastGroupSync = await this.configurationService.getLastGroupSyncDate();
this.lastUserSync = await this.configurationService.getLastUserSyncDate();

View File

@@ -0,0 +1,24 @@
import * as program from 'commander';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { SyncService } from '../services/sync.service';
import { ConnectorUtils } from '../utils';
import { Response } from 'jslib/cli/models/response';
import { TestResponse } from '../models/response/testResponse';
export class TestCommand {
constructor(private syncService: SyncService, private i18nService: I18nService) { }
async run(cmd: program.Command): Promise<Response> {
try {
const result = await ConnectorUtils.simulate(this.syncService, this.i18nService, cmd.last || false);
const res = new TestResponse(result);
return Response.success(res);
} catch (e) {
return Response.error(e);
}
}
}

View File

@@ -0,0 +1,13 @@
import { GroupEntry } from '../groupEntry';
export class GroupResponse {
externalId: string;
displayName: string;
userIds: string[];
constructor(g: GroupEntry) {
this.externalId = g.externalId;
this.displayName = g.displayName;
this.userIds = Array.from(g.userMemberExternalIds);
}
}

View File

@@ -0,0 +1,22 @@
import { GroupResponse } from './groupResponse';
import { UserResponse } from './userResponse';
import { SimResult } from '../simResult';
import { BaseResponse } from 'jslib/cli/models/response/baseResponse';
export class TestResponse implements BaseResponse {
object: string;
groups: GroupResponse[] = [];
enabledUsers: UserResponse[] = [];
disabledUsers: UserResponse[] = [];
deletedUsers: UserResponse[] = [];
constructor(result: SimResult) {
this.object = 'test';
this.groups = result.groups != null ? result.groups.map((g) => new GroupResponse(g)) : [];
this.enabledUsers = result.enabledUsers != null ? result.enabledUsers.map((u) => new UserResponse(u)) : [];
this.disabledUsers = result.disabledUsers != null ? result.disabledUsers.map((u) => new UserResponse(u)) : [];
this.deletedUsers = result.deletedUsers != null ? result.deletedUsers.map((u) => new UserResponse(u)) : [];
}
}

View File

@@ -0,0 +1,11 @@
import { UserEntry } from '../userEntry';
export class UserResponse {
externalId: string;
displayName: string;
constructor(u: UserEntry) {
this.externalId = u.externalId;
this.displayName = u.displayName;
}
}

10
src/models/simResult.ts Normal file
View File

@@ -0,0 +1,10 @@
import { GroupEntry } from './groupEntry';
import { UserEntry } from './userEntry';
export class SimResult {
groups: GroupEntry[] = [];
users: UserEntry[] = [];
enabledUsers: UserEntry[] = [];
disabledUsers: UserEntry[] = [];
deletedUsers: UserEntry[] = [];
}

View File

@@ -4,6 +4,7 @@ import * as program from 'commander';
import { Main } from './bwdc';
import { ConfigCommand } from './commands/config.command';
import { TestCommand } from './commands/test.command';
import { UpdateCommand } from 'jslib/cli/commands/update.command';
@@ -57,10 +58,30 @@ export class Program {
program.on('--help', () => {
writeLn('\n Examples:');
writeLn('');
writeLn(' bwdc login');
writeLn(' bwdc test');
writeLn(' bwdc config server bitwarden.com');
writeLn(' bwdc update');
writeLn('', true);
});
program
.command('test')
.description('Test a simulated sync.')
.option('-l, --last', 'Since the last successful sync.')
.on('--help', () => {
writeLn('\n Examples:');
writeLn('');
writeLn(' bwdc test');
writeLn(' bwdc test --last');
writeLn('', true);
})
.action(async (cmd) => {
await this.exitIfNotAuthed();
const command = new TestCommand(this.main.syncService, this.main.i18nService);
const response = await command.run(cmd);
this.processResponse(response);
});
program
.command('config <setting> <value>')
.description('Configure CLI settings.')
@@ -187,14 +208,6 @@ export class Program {
return out.trim() === '' ? null : out;
}
private async exitIfLocked() {
await this.exitIfNotAuthed();
const hasKey = await this.main.cryptoService.hasKey();
if (!hasKey) {
this.processResponse(Response.error('Vault is locked.'), true);
}
}
private async exitIfAuthed() {
const authed = await this.main.userService.isAuthenticated();
if (authed) {

70
src/utils.ts Normal file
View File

@@ -0,0 +1,70 @@
import { I18nService } from 'jslib/abstractions/i18n.service';
import { SyncService } from './services/sync.service';
import { Entry } from './models/entry';
import { SimResult } from './models/simResult';
import { UserEntry } from './models/userEntry';
export class ConnectorUtils {
static async simulate(syncService: SyncService, i18nService: I18nService, sinceLast: boolean): Promise<SimResult> {
return new Promise(async (resolve, reject) => {
const simResult = new SimResult();
try {
const result = await syncService.sync(!sinceLast, true);
if (result[0] != null) {
simResult.groups = result[0];
}
if (result[1] != null) {
simResult.users = result[1];
}
} catch (e) {
simResult.groups = null;
simResult.users = null;
reject(e || i18nService.t('syncError'));
return;
}
const userMap = new Map<string, UserEntry>();
this.sortEntries(simResult.users, i18nService);
for (const u of simResult.users) {
userMap.set(u.externalId, u);
if (u.deleted) {
simResult.deletedUsers.push(u);
} else if (u.disabled) {
simResult.disabledUsers.push(u);
} else {
simResult.enabledUsers.push(u);
}
}
this.sortEntries(simResult.groups, i18nService);
for (const g of simResult.groups) {
if (g.userMemberExternalIds == null) {
continue;
}
const anyG = (g as any);
anyG.users = [];
for (const uid of g.userMemberExternalIds) {
if (userMap.has(uid)) {
anyG.users.push(userMap.get(uid));
} else {
anyG.users.push({ displayName: uid });
}
}
this.sortEntries(anyG.users, i18nService);
}
resolve(simResult);
});
}
private static sortEntries(arr: Entry[], i18nService: I18nService) {
arr.sort((a, b) => {
return i18nService.collator ? i18nService.collator.compare(a.displayName, b.displayName) :
a.displayName.localeCompare(b.displayName);
});
}
}