Skip to content

Commit 7dbd67e

Browse files
authored
Plat 1113 use search for group records (#127)
* [Plat-1113] Update storage.listRecordsSharedWithGroup() to use search service instead of storage service * [Plat-1113] Fixes listRecordsSharedWithGroup to be backwards compatible * [Plat-1113] Adding chaching of group AK for files shared with groups found via search * [Plat-1113] Updates searchResult to cache AK only if the record is a file AND shared via groups * [PLAT-1113] updates timeout for longrunning secrets test * [Plat-1113] removes timeout update and delays test start so indexer can finish * [Plat-1113] updates timeout for all secrets tests * [PLAT-1113] increases timeout limit for travis tests
1 parent feb67c6 commit 7dbd67e

File tree

6 files changed

+53
-67
lines changed

6 files changed

+53
-67
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ env:
1313
global:
1414
- TEST_LOCAL_USE_PROD=false
1515
- TEST_LOCAL_USE_CDN=false
16-
- TEST_IDLE_TIMEOUT_MILLISECONDS=100000
16+
- TEST_IDLE_TIMEOUT_MILLISECONDS=200000
1717
- TEST_ENVIRONMENT=remote
1818
- TEST_BROWSER_VERSION=latest
1919
jobs:

__tests__/secret.test.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const ops = require('./utils/operations')
55
const { SECRET_UUID } = require('../lib/utils/constants')
66
const { testEmail } = require('./utils')
77

8-
jest.setTimeout(100000)
8+
jest.setTimeout(200000)
99

1010
let realmConfig
1111
let realm
@@ -234,6 +234,7 @@ describe('Tozny identity client', () => {
234234
// use local search to wait
235235
await ops.createSecret(realmConfig, identity, secret)
236236
// wait for proper indexing of secret
237+
await new Promise((r) => setTimeout(r, 5000))
237238
let result = await ops.getSecrets(realmConfig, identity, 10)
238239
expect(result.list[result.list.length - 1].data.secretValue).toBe(
239240
'secret-value'
@@ -247,6 +248,7 @@ describe('Tozny identity client', () => {
247248
description: 'this is a description',
248249
}
249250
const created = await ops.createSecret(realmConfig, identity, secret)
251+
await new Promise((r) => setTimeout(r, 5000))
250252
const returned = await ops.viewSecret(
251253
realmConfig,
252254
identity,
@@ -270,6 +272,7 @@ describe('Tozny identity client', () => {
270272
}
271273
await ops.createSecret(realmConfig, identity, oldSecret)
272274
await ops.updateSecret(realmConfig, identity, oldSecret, newSecret)
275+
await new Promise((r) => setTimeout(r, 5000))
273276
const secretsWithUpdatedRecord = await identity.getSecrets(100)
274277
const newLengthSecrets = secretsWithUpdatedRecord.list.length
275278
// Tests
@@ -334,6 +337,7 @@ describe('Tozny identity client', () => {
334337
await ops.updateSecret(realmConfig, identity, oldSecret, newSecret)
335338
const start = new Date()
336339
let latestVersionOfSecret
340+
await new Promise((r) => setTimeout(r, 5000))
337341
while (new Date() - start < 30000) {
338342
latestVersionOfSecret = await ops.getLatestSecret(
339343
realmConfig,
@@ -479,6 +483,7 @@ describe('Tozny identity client', () => {
479483
// delay 200 milliseconds between tries
480484
await new Promise((r) => setTimeout(r, 200))
481485
}
486+
await new Promise((r) => setTimeout(r, 5000))
482487
const listResponse = await ops.getSecretSharedList(
483488
realmConfig,
484489
identity,
@@ -531,6 +536,7 @@ describe('Tozny identity client', () => {
531536
// delay 200 milliseconds between tries
532537
await new Promise((r) => setTimeout(r, 200))
533538
}
539+
await new Promise((r) => setTimeout(r, 5000))
534540
let sharedList = await ops.getSharedSecrets(realmConfig, identity2)
535541
expect(sharedList.sharedList[0].data.secretValue).toBe('secret-value')
536542
})
@@ -561,6 +567,7 @@ describe('Tozny identity client', () => {
561567
// delay 200 milliseconds between tries
562568
await new Promise((r) => setTimeout(r, 200))
563569
}
570+
await new Promise((r) => setTimeout(r, 5000))
564571
let sharedList = await ops.getSharedSecrets(realmConfig, identity2)
565572
expect(sharedList.sharedList[0].data.secretValue).toBe('secret-value')
566573
let recordView = await ops.viewSecret(
@@ -691,6 +698,7 @@ describe('Tozny identity client', () => {
691698
)
692699
})
693700
it('can delete all secrets created by an identity', async () => {
701+
await new Promise((r) => setTimeout(r, 5000))
694702
let listedSecrets = await ops.getSecrets(realmConfig, identity, 100)
695703
for (let index = 0; index < listedSecrets.list.length; index++) {
696704
let deleted = await ops.deleteSecretVersion(

__tests__/storage.test.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ describe('Tozny', () => {
440440
created.group.groupID,
441441
groupMembersToAdd
442442
)
443+
await new Promise((r) => setTimeout(r, 5000))
443444
let sharedWithGroup = await ops.listRecordsSharedWithGroup(
444445
readerClient,
445446
created.group.groupID,
@@ -479,12 +480,13 @@ describe('Tozny', () => {
479480
const meta = { hola: 'mundo' }
480481
let recordInfo = await ops.writeRecord(readerClient, type, data, meta)
481482
await ops.shareRecordWithGroup(readerClient, created.group.groupID, type)
483+
await new Promise((r) => setTimeout(r, 5000))
482484
let sharedWithGroup = await ops.listRecordsSharedWithGroup(
483485
authorizerClient,
484486
created.group.groupID,
485487
[],
486488
0,
487-
10
489+
1
488490
)
489491
expect(sharedWithGroup[0][0].meta.recordId).toBe(recordInfo.meta.recordId)
490492
})
@@ -512,7 +514,7 @@ describe('Tozny', () => {
512514
created.group.groupID,
513515
groupMembersToAdd
514516
)
515-
const type = 'say-hello'
517+
const type = `say-hello-${uuidv4()}`
516518
const data1 = { hi: 'world' }
517519
const meta1 = { hola: 'mundo' }
518520
await ops.writeRecord(readerClient, type, data1, meta1)
@@ -526,6 +528,7 @@ describe('Tozny', () => {
526528
const meta4 = { hola: 'mundo' }
527529
await ops.writeRecord(readerClient, type, data4, meta4)
528530
await ops.shareRecordWithGroup(readerClient, created.group.groupID, type)
531+
await new Promise((r) => setTimeout(r, 5000))
529532
let sharedWithGroup = await ops.listRecordsSharedWithGroup(
530533
authorizerClient,
531534
created.group.groupID,
@@ -541,7 +544,7 @@ describe('Tozny', () => {
541544
0,
542545
10
543546
)
544-
expect(sharedWithGroup2[0].length).toBe(5)
547+
expect(sharedWithGroup2[0].length).toBe(4)
545548
})
546549
it('It can share and unshare a record with a group', async () => {
547550
const groupName = `testGroup-updated-${uuidv4()}`
@@ -572,6 +575,7 @@ describe('Tozny', () => {
572575
const meta = { hola: 'mundo' }
573576
let recordInfo = await ops.writeRecord(readerClient, type, data, meta)
574577
await ops.shareRecordWithGroup(readerClient, created.group.groupID, type)
578+
await new Promise((r) => setTimeout(r, 5000))
575579
let sharedWithGroup = await ops.listRecordsSharedWithGroup(
576580
authorizerClient,
577581
created.group.groupID,
@@ -742,7 +746,6 @@ describe('Tozny', () => {
742746
groupName,
743747
groupDesciption
744748
)
745-
console.log(created)
746749
const groupMember = new GroupMember(readerClient.clientId, {
747750
read: true,
748751
share: true,

lib/storage/client.js

Lines changed: 17 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -624,14 +624,15 @@ class Client extends CryptoConsumer {
624624
}
625625

626626
async _search(searchRequest) {
627+
const searchBody = searchRequest.stringify()
627628
let response = await this.authenticator.tokenFetch(
628629
this.config.apiUrl + '/v2/search',
629630
{
630631
method: 'POST',
631632
headers: {
632633
'Content-Type': 'application/json',
633634
},
634-
body: searchRequest.stringify(),
635+
body: searchBody,
635636
}
636637
)
637638
await checkStatus(response)
@@ -1402,67 +1403,23 @@ class Client extends CryptoConsumer {
14021403
*
14031404
* @return {Array} An array of records returned from TozStore.
14041405
*/
1405-
async listRecordsSharedWithGroup(
1406+
async listRecordsSharedWithGroup(
14061407
groupId,
14071408
writerIds = [],
14081409
nextToken = null,
1409-
max = null
1410+
max = null,
14101411
) {
1411-
const listSharedRequest = {
1412-
group_id: groupId,
1413-
writer_ids: writerIds,
1414-
nextToken: nextToken,
1415-
max: max,
1416-
}
1417-
let encodedUrl = urlEncodeData(listSharedRequest)
1418-
let response = await this.authenticator.tsv1Fetch(
1419-
`${this.config.apiUrl}/v2/storage/groups/${groupId}/share?${encodedUrl}`,
1420-
{
1421-
method: 'GET',
1422-
headers: {
1423-
'Content-Type': 'application/json',
1424-
},
1425-
}
1426-
)
1427-
let returnValues = []
1428-
let listSharedWithGroups = []
1429-
let recordsJson = await validateResponseAsJSON(response)
1430-
if (recordsJson.results == null) {
1431-
return listSharedWithGroups
1432-
}
1433-
for (var i = 0; i < recordsJson.results.length; i++) {
1434-
let meta = await Meta.decode(recordsJson.results[i].meta)
1435-
let recordData = await new RecordData(recordsJson.results[i].record_data)
1436-
let record = await new Record(
1437-
meta,
1438-
recordData,
1439-
recordsJson.results[i].rec_sig
1440-
)
1441-
// Note: When fetching group records, particularly for the files use-case
1442-
// using the cached AK gives us the benefit of placing the AK in the cache
1443-
// which means later when downloading the file, the AK does not need to
1444-
// be fetched from the API. The gotcha here for now is that the API does
1445-
// not currently support AK fetches when access is granted via group
1446-
// permissions. This hides that by making sure the direct fetch is not
1447-
// needed, however for it to work the group records must be fetched via
1448-
// this list method first. This method is currently the only viable way
1449-
// of reading records that have been shared via the groups API.
1450-
let ak = await this._getCachedAk(
1451-
meta.writerId,
1452-
meta.userId,
1453-
this.config.clientId,
1454-
meta.type,
1455-
recordsJson.results[i].group_access_key
1456-
)
1457-
let decryptedRecord = await this.crypto.decryptRecord(record, ak)
1458-
listSharedWithGroups.push(decryptedRecord)
1459-
}
1460-
let NextToken = {
1461-
nextToken: recordsJson.next_token,
1462-
}
1463-
returnValues.push(listSharedWithGroups)
1464-
returnValues.push(NextToken)
1465-
return returnValues
1412+
console.log(writerIds)
1413+
// Create a search query
1414+
const groupIds = [groupId]
1415+
const searchRequest = new Search(true, true, max, nextToken, groupIds, true)
1416+
// Create search result
1417+
const resultQuery = await this.search(searchRequest)
1418+
// Execute search
1419+
let resultList = await resultQuery.next(true)
1420+
if (resultList.length == 0)
1421+
return []
1422+
return [resultList, {nextToken: resultQuery.request.nextToken}]
14661423
}
14671424

14681425
/**
@@ -1591,9 +1548,9 @@ class Client extends CryptoConsumer {
15911548
data_start_timestamp: params.DataStartTimestamp,
15921549
}
15931550
if (typeof params.DataEndTimestamp !== 'undefined') {
1594-
computeEncoded["data_end_timestamp"] = params.DataEndTimestamp
1551+
computeEncoded["data_end_timestamp"] = params.DataEndTimestamp
15951552
}
1596-
if (typeof params.DataRequired !== 'undefined') {
1553+
if (typeof params.DataRequired !== 'undefined') {
15971554
let obj = Object.fromEntries(params.DataRequired);
15981555
computeEncoded["data_required"] = obj
15991556
}

types/search.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class Search extends Serializable {
1212
includeData = false,
1313
includeAllWriters = false,
1414
count = DEFAULT_QUERY_COUNT,
15-
nextToken
15+
nextToken,
16+
groupIds = [],
17+
includeOnlyGroups = false,
1618
) {
1719
super()
1820
this.includeData = includeData
@@ -21,6 +23,8 @@ class Search extends Serializable {
2123
this.nextToken = nextToken
2224
this.matches = []
2325
this.excludes = []
26+
this.groupIds = groupIds
27+
this.includeOnlyGroups = includeOnlyGroups
2428
}
2529

2630
match(terms, condition, strategy) {
@@ -54,6 +58,8 @@ class Search extends Serializable {
5458
limit: this.count,
5559
include_all_writers: this.includeAllWriters,
5660
include_data: this.includeData,
61+
group_ids: this.groupIds,
62+
include_only_groups: this.includeOnlyGroups,
5763
}
5864
if (this.nextToken) {
5965
toSerialize.next_token = this.nextToken
@@ -70,6 +76,9 @@ class Search extends Serializable {
7076
if (this.searchOrder) {
7177
toSerialize.order = this.searchOrder.serializable()
7278
}
79+
if (this.groupIds){
80+
toSerialize.group_ids = this.groupIds
81+
}
7382
return toSerialize
7483
}
7584
}

types/searchResult.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ class SearchResult {
4242
const meta = await Meta.decode(result.meta)
4343
const record = new Record(meta, result.record_data)
4444
if (this.request.includeData) {
45+
if (record.isFile && result.sharing_model == "GROUP"){
46+
await this.client._getCachedAk(
47+
meta.writerId,
48+
meta.userId,
49+
this.client.config.clientId,
50+
meta.type,
51+
result.group_access_key
52+
)
53+
}
4554
const ak = await this.decodeAccessKey(result.sharing_model, result.access_key, result.group_access_key)
4655
return this.client.crypto.decryptRecord(record, ak)
4756
}

0 commit comments

Comments
 (0)