From 2e8d0aaf5394407195d776cd18b445f5363dc9a3 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 18 May 2018 15:26:59 -0400 Subject: [PATCH] list and get organizations --- jslib | 2 +- src/commands/get.command.ts | 30 ++++++++++++++++++++- src/commands/list.command.ts | 21 ++++++++++++--- src/models/response/organizationResponse.ts | 24 +++++++++++++++++ src/program.ts | 6 +++-- src/utils.ts | 11 ++++++++ 6 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 src/models/response/organizationResponse.ts diff --git a/jslib b/jslib index a421f6e64a..bf260819bb 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit a421f6e64a1f47c34806419012b3983bd0505bc6 +Subproject commit bf260819bb303d125379c92e712f762fe17f043c diff --git a/src/commands/get.command.ts b/src/commands/get.command.ts index b20e638aba..39e363a8ae 100644 --- a/src/commands/get.command.ts +++ b/src/commands/get.command.ts @@ -10,6 +10,9 @@ import { CryptoService } from 'jslib/abstractions/crypto.service'; import { FolderService } from 'jslib/abstractions/folder.service'; import { TokenService } from 'jslib/abstractions/token.service'; import { TotpService } from 'jslib/abstractions/totp.service'; +import { UserService } from 'jslib/abstractions/user.service'; + +import { Organization } from 'jslib/models/domain/organization'; import { CipherView } from 'jslib/models/view/cipherView'; import { CollectionView } from 'jslib/models/view/collectionView'; @@ -20,6 +23,7 @@ import { CipherResponse } from '../models/response/cipherResponse'; import { CollectionResponse } from '../models/response/collectionResponse'; import { FolderResponse } from '../models/response/folderResponse'; import { MessageResponse } from '../models/response/messageResponse'; +import { OrganizationResponse } from '../models/response/organizationResponse'; import { StringResponse } from '../models/response/stringResponse'; import { TemplateResponse } from '../models/response/templateResponse'; @@ -39,7 +43,7 @@ export class GetCommand { constructor(private cipherService: CipherService, private folderService: FolderService, private collectionService: CollectionService, private totpService: TotpService, private auditService: AuditService, private cryptoService: CryptoService, - private tokenService: TokenService) { } + private tokenService: TokenService, private userService: UserService) { } async run(object: string, id: string, cmd: program.Command): Promise { if (id != null) { @@ -65,6 +69,8 @@ export class GetCommand { return await this.getFolder(id); case 'collection': return await this.getCollection(id); + case 'organization': + return await this.getOrganization(id); case 'template': return await this.getTemplate(id); default: @@ -301,6 +307,28 @@ export class GetCommand { return Response.success(res); } + private async getOrganization(id: string) { + let org: Organization = null; + if (this.isGuid(id)) { + org = await this.userService.getOrganization(id); + } else if (id.trim() !== '') { + let orgs = await this.userService.getAllOrganizations(); + orgs = CliUtils.searchOrganizations(orgs, id); + if (orgs.length > 1) { + return Response.multipleResults(orgs.map((c) => c.id)); + } + if (orgs.length > 0) { + org = orgs[0]; + } + } + + if (org == null) { + return Response.notFound(); + } + const res = new OrganizationResponse(org); + return Response.success(res); + } + private isGuid(id: string) { return RegExp(/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/, 'i').test(id); } diff --git a/src/commands/list.command.ts b/src/commands/list.command.ts index 25fce71aa4..025978ae5d 100644 --- a/src/commands/list.command.ts +++ b/src/commands/list.command.ts @@ -1,20 +1,22 @@ import * as program from 'commander'; import { CipherService } from 'jslib/abstractions/cipher.service'; -import { CollectionService } from 'jslib/services/collection.service'; -import { FolderService } from 'jslib/services/folder.service'; +import { CollectionService } from 'jslib/abstractions/collection.service'; +import { FolderService } from 'jslib/abstractions/folder.service'; +import { UserService } from 'jslib/abstractions/user.service'; import { Response } from '../models/response'; import { CipherResponse } from '../models/response/cipherResponse'; import { CollectionResponse } from '../models/response/collectionResponse'; import { FolderResponse } from '../models/response/folderResponse'; import { ListResponse } from '../models/response/listResponse'; +import { OrganizationResponse } from '../models/response/organizationResponse'; import { CliUtils } from '../utils'; export class ListCommand { constructor(private cipherService: CipherService, private folderService: FolderService, - private collectionService: CollectionService) { } + private collectionService: CollectionService, private userService: UserService) { } async run(object: string, cmd: program.Command): Promise { switch (object.toLowerCase()) { @@ -24,6 +26,8 @@ export class ListCommand { return await this.listFolders(cmd); case 'collections': return await this.listCollections(cmd); + case 'organizations': + return await this.listOrganizations(cmd); default: return Response.badRequest('Unknown object.'); } @@ -108,4 +112,15 @@ export class ListCommand { const res = new ListResponse(collections.map((o) => new CollectionResponse(o))); return Response.success(res); } + + private async listOrganizations(cmd: program.Command) { + let organizations = await this.userService.getAllOrganizations(); + + if (cmd.search != null && cmd.search.trim() !== '') { + organizations = CliUtils.searchOrganizations(organizations, cmd.search); + } + + const res = new ListResponse(organizations.map((o) => new OrganizationResponse(o))); + return Response.success(res); + } } diff --git a/src/models/response/organizationResponse.ts b/src/models/response/organizationResponse.ts new file mode 100644 index 0000000000..b8d367b776 --- /dev/null +++ b/src/models/response/organizationResponse.ts @@ -0,0 +1,24 @@ +import { BaseResponse } from './baseResponse'; + +import { Organization } from 'jslib/models/domain/organization'; + +import { OrganizationUserStatusType } from 'jslib/enums/organizationUserStatusType'; +import { OrganizationUserType } from 'jslib/enums/organizationUserType'; + +export class OrganizationResponse implements BaseResponse { + object: string; + id: string; + name: string; + status: OrganizationUserStatusType; + type: OrganizationUserType; + enabled: boolean; + + constructor(o: Organization) { + this.object = 'organization'; + this.id = o.id; + this.name = o.name; + this.status = o.status; + this.type = o.type; + this.enabled = o.enabled; + } +} diff --git a/src/program.ts b/src/program.ts index e31790ece0..fcf4365a93 100644 --- a/src/program.ts +++ b/src/program.ts @@ -207,6 +207,7 @@ export class Program { writeLn(' items'); writeLn(' folders'); writeLn(' collections'); + writeLn(' organizations'); writeLn(''); writeLn(' Notes:'); writeLn(''); @@ -228,7 +229,7 @@ export class Program { .action(async (object, cmd) => { await this.exitIfLocked(); const command = new ListCommand(this.main.cipherService, this.main.folderService, - this.main.collectionService); + this.main.collectionService, this.main.userService); const response = await command.run(object, cmd); this.processResponse(response); }); @@ -250,6 +251,7 @@ export class Program { writeLn(' attachment'); writeLn(' folder'); writeLn(' collection'); + writeLn(' organization'); writeLn(' template'); writeLn(''); writeLn(' Id:'); @@ -273,7 +275,7 @@ export class Program { await this.exitIfLocked(); const command = new GetCommand(this.main.cipherService, this.main.folderService, this.main.collectionService, this.main.totpService, this.main.auditService, - this.main.cryptoService, this.main.tokenService); + this.main.cryptoService, this.main.tokenService, this.main.userService); const response = await command.run(object, id, cmd); this.processResponse(response); }); diff --git a/src/utils.ts b/src/utils.ts index 765ffbc6c1..8df65a55cc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; +import { Organization } from 'jslib/models/domain/organization'; import { CipherView } from 'jslib/models/view/cipherView'; import { CollectionView } from 'jslib/models/view/collectionView'; import { FolderView } from 'jslib/models/view/folderView'; @@ -116,4 +117,14 @@ export class CliUtils { return false; }); } + + static searchOrganizations(organizations: Organization[], search: string) { + search = search.toLowerCase(); + return organizations.filter((o) => { + if (o.name != null && o.name.toLowerCase().indexOf(search) > -1) { + return true; + } + return false; + }); + } }