From c042d345ea494889b536602dc7998e30e2c30f1a Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Mon, 13 Jul 2020 16:37:36 -0500 Subject: [PATCH 01/10] feat: auth mapping ep --- src/server/auth/arboristClient.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/server/auth/arboristClient.js b/src/server/auth/arboristClient.js index 977fb9b0..b230c2eb 100644 --- a/src/server/auth/arboristClient.js +++ b/src/server/auth/arboristClient.js @@ -10,7 +10,7 @@ class ArboristClient { listAuthorizedResources(jwt) { // Make request to arborist for list of resources with access - const resourcesEndpoint = `${this.baseEndpoint}/auth/resources`; + const resourcesEndpoint = `${this.baseEndpoint}/auth/mapping`; log.debug('[ArboristClient] listAuthorizedResources jwt: ', jwt); const headers = (jwt) ? { Authorization: `bearer ${jwt}` } : {}; return fetch( @@ -20,7 +20,19 @@ class ArboristClient { headers, }, ).then( - (response) => response.json(), + (response) => { + const responseJSON = response.json(); + const data = { + resources: [], + }; + Object.keys(responseJSON).forEach((key) => { + if (responseJSON[key] && responseJSON[key].some((x) => x.method === 'read')) { + data.resources.push(key); + } + }); + log.debug('[ArboristClient] data: ', data); + return data; + }, (err) => { log.error(err); throw new CodedError(500, err); From b2b4c263417a9038e886c1dd2d484ef939e26b62 Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Mon, 13 Jul 2020 17:13:02 -0500 Subject: [PATCH 02/10] fix: test --- src/server/__mocks__/config.js | 1 + src/server/__mocks__/mockDataFromES.js | 50 +++++++++++++++++++++++--- src/server/auth/arboristClient.js | 35 +++++++++--------- 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/server/__mocks__/config.js b/src/server/__mocks__/config.js index 4b66f9da..64b2cca7 100644 --- a/src/server/__mocks__/config.js +++ b/src/server/__mocks__/config.js @@ -19,6 +19,7 @@ const config = { port: 3000, path: '/graphql', + logLevel: 'DEBUG', tierAccessLevel: 'regular', tierAccessLimit: 20, arboristEndpoint: 'http://mock-arborist', diff --git a/src/server/__mocks__/mockDataFromES.js b/src/server/__mocks__/mockDataFromES.js index 80643092..5175657c 100644 --- a/src/server/__mocks__/mockDataFromES.js +++ b/src/server/__mocks__/mockDataFromES.js @@ -204,11 +204,53 @@ const mockResourcePath = () => { const mockArborist = () => { nock(config.arboristEndpoint) .persist() - .get('/auth/resources') + .get('/auth/mapping') .reply(200, { - resources: [ - 'internal-project-1', - 'internal-project-2', + 'internal-project-1': [ + { + service: '*', + method: 'create', + }, + { + service: '*', + method: 'delete', + }, + { + service: '*', + method: 'read', + }, + { + service: '*', + method: 'read-storage', + }, + { + service: '*', + method: 'update', + }, + ], + 'internal-project-2': [ + { + service: '*', + method: 'read', + }, + ], + 'internal-project-3': [ + { + service: '*', + method: 'create', + }, + { + service: '*', + method: 'delete', + }, + { + service: '*', + method: 'read-storage', + }, + { + service: '*', + method: 'update', + }, ], }); }; diff --git a/src/server/auth/arboristClient.js b/src/server/auth/arboristClient.js index b230c2eb..9fa13c42 100644 --- a/src/server/auth/arboristClient.js +++ b/src/server/auth/arboristClient.js @@ -20,24 +20,23 @@ class ArboristClient { headers, }, ).then( - (response) => { - const responseJSON = response.json(); - const data = { - resources: [], - }; - Object.keys(responseJSON).forEach((key) => { - if (responseJSON[key] && responseJSON[key].some((x) => x.method === 'read')) { - data.resources.push(key); - } - }); - log.debug('[ArboristClient] data: ', data); - return data; - }, - (err) => { - log.error(err); - throw new CodedError(500, err); - }, - ); + (response) => response.json(), + ).then((result) => { + const data = { + resources: [], + }; + Object.keys(result).forEach((key) => { + if (result[key] && result[key].some((x) => x.method === 'read')) { + data.resources.push(key); + } + }); + log.debug('[ArboristClient] data: ', data); + return data; + }, + (err) => { + log.error(err); + throw new CodedError(500, err); + }); } } From cf734186ab57eccba7de3405cd5aee41ef51e1c7 Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Tue, 14 Jul 2020 10:49:23 -0500 Subject: [PATCH 03/10] chore: cleaning --- src/server/__mocks__/config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server/__mocks__/config.js b/src/server/__mocks__/config.js index 64b2cca7..4b66f9da 100644 --- a/src/server/__mocks__/config.js +++ b/src/server/__mocks__/config.js @@ -19,7 +19,6 @@ const config = { port: 3000, path: '/graphql', - logLevel: 'DEBUG', tierAccessLevel: 'regular', tierAccessLimit: 20, arboristEndpoint: 'http://mock-arborist', From 988eb1c1e1ef13400adb085a03e364bd062254b3 Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Tue, 14 Jul 2020 12:35:43 -0500 Subject: [PATCH 04/10] address comments --- src/server/__mocks__/mockDataFromES.js | 6 ++++++ src/server/auth/__tests__/authHelper.test.js | 6 +++++- src/server/auth/arboristClient.js | 2 +- src/server/resolvers.js | 1 - 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/server/__mocks__/mockDataFromES.js b/src/server/__mocks__/mockDataFromES.js index 5175657c..6b0604a2 100644 --- a/src/server/__mocks__/mockDataFromES.js +++ b/src/server/__mocks__/mockDataFromES.js @@ -252,6 +252,12 @@ const mockArborist = () => { method: 'update', }, ], + 'internal-project-4': [ + { + service: '*', + method: '*', + }, + ], }); }; diff --git a/src/server/auth/__tests__/authHelper.test.js b/src/server/auth/__tests__/authHelper.test.js index 081fe5a1..7aceaf3d 100644 --- a/src/server/auth/__tests__/authHelper.test.js +++ b/src/server/auth/__tests__/authHelper.test.js @@ -12,7 +12,8 @@ setupMockDataEndpoint(); describe('AuthHelper', () => { test('could create auth helper instance', async () => { const authHelper = await getAuthHelperInstance('fake-jwt'); - expect(authHelper.getAccessibleResources()).toEqual(['internal-project-1', 'internal-project-2']); + expect(authHelper.getAccessibleResources()).toEqual(['internal-project-1', 'internal-project-2', 'internal-project-4']); + expect(authHelper.getAccessibleResources()).not.toContain(['internal-project-3']); expect(authHelper.getUnaccessibleResources()).toEqual(['external-project-1', 'external-project-2']); }); @@ -51,6 +52,7 @@ describe('AuthHelper', () => { gen3_resource_path: [ 'internal-project-1', 'internal-project-2', + 'internal-project-4', ], }, }; @@ -70,6 +72,7 @@ describe('AuthHelper', () => { gen3_resource_path: [ 'internal-project-1', 'internal-project-2', + 'internal-project-4', ], }, }, @@ -108,6 +111,7 @@ describe('AuthHelper', () => { gen3_resource_path: [ 'internal-project-1', 'internal-project-2', + 'internal-project-4', ], }, }; diff --git a/src/server/auth/arboristClient.js b/src/server/auth/arboristClient.js index 9fa13c42..a6a52ebb 100644 --- a/src/server/auth/arboristClient.js +++ b/src/server/auth/arboristClient.js @@ -26,7 +26,7 @@ class ArboristClient { resources: [], }; Object.keys(result).forEach((key) => { - if (result[key] && result[key].some((x) => x.method === 'read')) { + if (result[key] && result[key].some((x) => x.method === 'read' || x.method === '*')) { data.resources.push(key); } }); diff --git a/src/server/resolvers.js b/src/server/resolvers.js index 179c4548..847bdc8a 100644 --- a/src/server/resolvers.js +++ b/src/server/resolvers.js @@ -146,7 +146,6 @@ const getFieldAggregationResolverMappings = (esInstance, esIndex) => { return fieldAggregationResolverMappings; }; - /** * Tree-structured resolvers pass down arguments. * For better understanding, following is an example query, and related resolvers for each level: From c1b051eac2a99dc2df46851a54c0109976e7fece Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Mon, 20 Jul 2020 13:18:35 -0500 Subject: [PATCH 05/10] fix: logic --- src/server/auth/arboristClient.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/server/auth/arboristClient.js b/src/server/auth/arboristClient.js index a6a52ebb..226d854d 100644 --- a/src/server/auth/arboristClient.js +++ b/src/server/auth/arboristClient.js @@ -26,7 +26,13 @@ class ArboristClient { resources: [], }; Object.keys(result).forEach((key) => { - if (result[key] && result[key].some((x) => x.method === 'read' || x.method === '*')) { + // logic: you have access to a project if you either + // 1. have 'read' access to a project resource + // or + // 2. have '*' access to service 'guppy' or service '*' + if (result[key] && result[key].some((x) => x.method === 'read' + || (x.method === '*' && (x.service === 'guppy' || x.service === '*'))) + ) { data.resources.push(key); } }); From 06e67b60ffc096afd9f52176fb0f5eba5e932d5f Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Mon, 20 Jul 2020 13:30:32 -0500 Subject: [PATCH 06/10] chore: update test --- src/server/__mocks__/mockDataFromES.js | 20 ++++++++++++++++---- src/server/auth/__tests__/authHelper.test.js | 7 +++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/server/__mocks__/mockDataFromES.js b/src/server/__mocks__/mockDataFromES.js index 6b0604a2..f2daac30 100644 --- a/src/server/__mocks__/mockDataFromES.js +++ b/src/server/__mocks__/mockDataFromES.js @@ -206,7 +206,7 @@ const mockArborist = () => { .persist() .get('/auth/mapping') .reply(200, { - 'internal-project-1': [ + 'internal-project-1': [ // accessible { service: '*', method: 'create', @@ -228,13 +228,13 @@ const mockArborist = () => { method: 'update', }, ], - 'internal-project-2': [ + 'internal-project-2': [ // accessible { service: '*', method: 'read', }, ], - 'internal-project-3': [ + 'internal-project-3': [ // not accessible since method does not match { service: '*', method: 'create', @@ -252,12 +252,24 @@ const mockArborist = () => { method: 'update', }, ], - 'internal-project-4': [ + 'internal-project-4': [ // accessible { service: '*', method: '*', }, ], + 'internal-project-5': [ // accessible + { + service: 'guppy', + method: '*', + }, + ], + 'internal-project-6': [ // not accessible since service does not match + { + service: 'indexd', + method: '*', + }, + ], }); }; diff --git a/src/server/auth/__tests__/authHelper.test.js b/src/server/auth/__tests__/authHelper.test.js index 7aceaf3d..41762d7a 100644 --- a/src/server/auth/__tests__/authHelper.test.js +++ b/src/server/auth/__tests__/authHelper.test.js @@ -12,8 +12,8 @@ setupMockDataEndpoint(); describe('AuthHelper', () => { test('could create auth helper instance', async () => { const authHelper = await getAuthHelperInstance('fake-jwt'); - expect(authHelper.getAccessibleResources()).toEqual(['internal-project-1', 'internal-project-2', 'internal-project-4']); - expect(authHelper.getAccessibleResources()).not.toContain(['internal-project-3']); + expect(authHelper.getAccessibleResources()).toEqual(['internal-project-1', 'internal-project-2', 'internal-project-4', 'internal-project-5']); + expect(authHelper.getAccessibleResources()).not.toContain(['internal-project-3', 'internal-project-6']); expect(authHelper.getUnaccessibleResources()).toEqual(['external-project-1', 'external-project-2']); }); @@ -53,6 +53,7 @@ describe('AuthHelper', () => { 'internal-project-1', 'internal-project-2', 'internal-project-4', + 'internal-project-5', ], }, }; @@ -73,6 +74,7 @@ describe('AuthHelper', () => { 'internal-project-1', 'internal-project-2', 'internal-project-4', + 'internal-project-5', ], }, }, @@ -112,6 +114,7 @@ describe('AuthHelper', () => { 'internal-project-1', 'internal-project-2', 'internal-project-4', + 'internal-project-5', ], }, }; From a6f03430cadff1bee2433c97edf52f193a14aca4 Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Mon, 20 Jul 2020 13:47:13 -0500 Subject: [PATCH 07/10] chore: should not exclude --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f7d672a7..bee3a45b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,4 +4,3 @@ repos: hooks: - id: detect-secrets args: ['--baseline', '.secrets.baseline'] - exclude: .*/tests/.* From a5aa05b5282b9b5c46f1956a574fec2ddd015081 Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Mon, 20 Jul 2020 14:19:15 -0500 Subject: [PATCH 08/10] fix: logic --- src/server/auth/arboristClient.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/server/auth/arboristClient.js b/src/server/auth/arboristClient.js index 226d854d..66d2f231 100644 --- a/src/server/auth/arboristClient.js +++ b/src/server/auth/arboristClient.js @@ -26,13 +26,13 @@ class ArboristClient { resources: [], }; Object.keys(result).forEach((key) => { - // logic: you have access to a project if you either - // 1. have 'read' access to a project resource - // or - // 2. have '*' access to service 'guppy' or service '*' - if (result[key] && result[key].some((x) => x.method === 'read' - || (x.method === '*' && (x.service === 'guppy' || x.service === '*'))) - ) { + // logic: you have access to a project if you have the following access: + // method 'read' (or '*' - all methods) to service 'guppy' (or '*' - all services) + // on the project resource. + if (result[key] && result[key].some((x) => ( + (x.method === 'read' || x.method === '*') + && (x.service === 'guppy' || x.service === '*') + ))) { data.resources.push(key); } }); From bad5f337f55f098787606bfa59546e5906be151d Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Mon, 20 Jul 2020 15:54:55 -0500 Subject: [PATCH 09/10] chore: update hook --- .pre-commit-config.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bee3a45b..2ec5bf25 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,3 +4,10 @@ repos: hooks: - id: detect-secrets args: ['--baseline', '.secrets.baseline'] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: no-commit-to-branch + args: [--branch, develop, --branch, master, --pattern, release/.*] From a57de489eca8a4013309b6e4c2b9a0f8a8dc21e1 Mon Sep 17 00:00:00 2001 From: Mingfei Shao Date: Tue, 21 Jul 2020 16:23:35 -0500 Subject: [PATCH 10/10] update ver --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f0eb85d2..babe64be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@gen3/guppy", - "version": "0.7.0", + "version": "0.8.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 64c21bc7..9c79f9de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gen3/guppy", - "version": "0.7.0", + "version": "0.8.0", "description": "Server that support GraphQL queries on data from elasticsearch", "main": "src/server/server.js", "directories": {