From d2ef504b40c3a2bb90a8748b217a83a8da9fabd3 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 25 Sep 2019 16:08:56 -0400 Subject: [PATCH] org collection create and get template --- jslib | 2 +- src/commands/create.command.ts | 34 ++++++++++++++++++- src/commands/get.command.ts | 5 +++ .../request/organizationCollectionRequest.ts | 16 +++++++++ .../organizationCollectionResponse.ts | 14 ++++++++ src/models/selectionReadOnly.ts | 13 +++++++ src/program.ts | 2 +- 7 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/models/request/organizationCollectionRequest.ts create mode 100644 src/models/response/organizationCollectionResponse.ts create mode 100644 src/models/selectionReadOnly.ts diff --git a/jslib b/jslib index b74ee7b3ee8..971e19335f6 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit b74ee7b3ee823a820854623cc32c8522a09e9f4d +Subproject commit 971e19335f66ac64845b65a7bcf688811f60eaff diff --git a/src/commands/create.command.ts b/src/commands/create.command.ts index 8f2ee8667a4..4027b1a6465 100644 --- a/src/commands/create.command.ts +++ b/src/commands/create.command.ts @@ -2,24 +2,33 @@ import * as program from 'commander'; import * as fs from 'fs'; import * as path from 'path'; +import { ApiService } from 'jslib/abstractions/api.service'; import { CipherService } from 'jslib/abstractions/cipher.service'; import { CryptoService } from 'jslib/abstractions/crypto.service'; import { FolderService } from 'jslib/abstractions/folder.service'; import { UserService } from 'jslib/abstractions/user.service'; import { Cipher } from 'jslib/models/export/cipher'; +import { Collection } from 'jslib/models/export/collection'; import { Folder } from 'jslib/models/export/folder'; +import { CollectionRequest } from 'jslib/models/request/collectionRequest'; +import { SelectionReadOnlyRequest } from 'jslib/models/request/selectionReadOnlyRequest'; + import { Response } from 'jslib/cli/models/response'; import { CipherResponse } from '../models/response/cipherResponse'; import { FolderResponse } from '../models/response/folderResponse'; +import { OrganizationCollectionResponse } from '../models/response/organizationCollectionResponse'; + +import { OrganizationCollectionRequest } from '../models/request/organizationCollectionRequest'; import { CliUtils } from '../utils'; export class CreateCommand { constructor(private cipherService: CipherService, private folderService: FolderService, - private userService: UserService, private cryptoService: CryptoService) { } + private userService: UserService, private cryptoService: CryptoService, + private apiService: ApiService) { } async run(object: string, requestJson: string, cmd: program.Command): Promise { let req: any = null; @@ -47,6 +56,8 @@ export class CreateCommand { return await this.createAttachment(cmd); case 'folder': return await this.createFolder(req); + case 'org-collection': + return await this.createOrganizationCollection(req); default: return Response.badRequest('Unknown object.'); } @@ -118,4 +129,25 @@ export class CreateCommand { return Response.error(e); } } + + private async createOrganizationCollection(req: OrganizationCollectionRequest) { + try { + const orgKey = await this.cryptoService.getOrgKey(req.organizationId); + if (orgKey == null) { + throw new Error('No encryption key for this organization.'); + } + + const groups = req.groups == null ? null : + req.groups.map((g) => new SelectionReadOnlyRequest(g.id, g.readOnly)); + const request = new CollectionRequest(); + request.name = (await this.cryptoService.encrypt(req.name, orgKey)).encryptedString; + request.externalId = req.externalId; + request.groups = groups; + await this.apiService.postCollection(req.organizationId, request); + const res = new OrganizationCollectionResponse(Collection.toView(req), groups); + return Response.success(res); + } catch (e) { + return Response.error(e); + } + } } diff --git a/src/commands/get.command.ts b/src/commands/get.command.ts index 1c5f587d08c..017dbbbed94 100644 --- a/src/commands/get.command.ts +++ b/src/commands/get.command.ts @@ -39,6 +39,8 @@ import { FolderResponse } from '../models/response/folderResponse'; import { OrganizationResponse } from '../models/response/organizationResponse'; import { TemplateResponse } from '../models/response/templateResponse'; +import { OrganizationCollectionRequest } from '../models/request/organizationCollectionRequest'; + import { CliUtils } from '../utils'; import { Utils } from 'jslib/misc/utils'; @@ -383,6 +385,9 @@ export class GetCommand { case 'item-collections': template = ['collection-id1', 'collection-id2']; break; + case 'org-collection': + template = OrganizationCollectionRequest.template(); + break; default: return Response.badRequest('Unknown template object.'); } diff --git a/src/models/request/organizationCollectionRequest.ts b/src/models/request/organizationCollectionRequest.ts new file mode 100644 index 00000000000..6ccc081ea31 --- /dev/null +++ b/src/models/request/organizationCollectionRequest.ts @@ -0,0 +1,16 @@ +import { Collection } from 'jslib/models/export/collection'; + +import { SelectionReadOnly } from '../selectionReadOnly'; + +export class OrganizationCollectionRequest extends Collection { + static template(): OrganizationCollectionRequest { + const req = new OrganizationCollectionRequest(); + req.organizationId = '00000000-0000-0000-0000-000000000000'; + req.name = 'Collection name'; + req.externalId = null; + req.groups = [SelectionReadOnly.template(), SelectionReadOnly.template()]; + return req; + } + + groups: SelectionReadOnly[]; +} diff --git a/src/models/response/organizationCollectionResponse.ts b/src/models/response/organizationCollectionResponse.ts new file mode 100644 index 00000000000..e4f3c357f68 --- /dev/null +++ b/src/models/response/organizationCollectionResponse.ts @@ -0,0 +1,14 @@ +import { CollectionView } from 'jslib/models/view/collectionView'; + +import { SelectionReadOnly } from '../selectionReadOnly'; + +import { CollectionResponse } from './collectionResponse'; + +export class OrganizationCollectionResponse extends CollectionResponse { + groups: SelectionReadOnly[]; + + constructor(o: CollectionView, groups: SelectionReadOnly[]) { + super(o); + this.groups = groups; + } +} diff --git a/src/models/selectionReadOnly.ts b/src/models/selectionReadOnly.ts new file mode 100644 index 00000000000..70d730c4847 --- /dev/null +++ b/src/models/selectionReadOnly.ts @@ -0,0 +1,13 @@ +export class SelectionReadOnly { + static template(): SelectionReadOnly { + return new SelectionReadOnly('00000000-0000-0000-0000-000000000000', false); + } + + id: string; + readOnly: boolean; + + constructor(id: string, readOnly: boolean) { + this.id = id; + this.readOnly = readOnly; + } +} diff --git a/src/program.ts b/src/program.ts index 31217218474..480042329b2 100644 --- a/src/program.ts +++ b/src/program.ts @@ -334,7 +334,7 @@ export class Program extends BaseProgram { .action(async (object, encodedJson, cmd) => { await this.exitIfLocked(); const command = new CreateCommand(this.main.cipherService, this.main.folderService, - this.main.userService, this.main.cryptoService); + this.main.userService, this.main.cryptoService, this.main.apiService); const response = await command.run(object, encodedJson, cmd); this.processResponse(response); });