diff --git a/app/src/db/models/tables/objectModel.js b/app/src/db/models/tables/objectModel.js index 24cc9e7c..f4b7654c 100644 --- a/app/src/db/models/tables/objectModel.js +++ b/app/src/db/models/tables/objectModel.js @@ -159,23 +159,27 @@ class ObjectModel extends Timestamps(Model) { }); } }, - // TODO: consider handling an array of permCodes hasPermission(query, userId, permCode) { if (userId && permCode) { query - .allowGraph('[objectPermission, bucketPermission]') - .withGraphJoined('[objectPermission, bucketPermission]') - .whereIn('objectPermission.objectId', query => { + .fullOuterJoinRelated('[objectPermission, bucketPermission]') + // wrap in WHERE to make contained clauses exclusive of root query + .where(query => { query - .distinct('objectPermission.objectId') - .where('objectPermission.permCode', permCode) - .where('objectPermission.userId', userId); - }) - .orWhereIn('object.bucketId', query => { - query - .distinct('bucketPermission.bucketId') - .where('bucketPermission.permCode', permCode) - .where('bucketPermission.userId', userId); + .where(query => { + query + .where({ + 'objectPermission.permCode': permCode, + 'objectPermission.userId': userId + }); + }) + .orWhere(query => { + query + .where({ + 'bucketPermission.permCode': permCode, + 'bucketPermission.userId': userId + }); + }); }); } } diff --git a/app/src/services/metadata.js b/app/src/services/metadata.js index ce0bd0ff..2834bab9 100644 --- a/app/src/services/metadata.js +++ b/app/src/services/metadata.js @@ -175,7 +175,7 @@ const service = { .modifyGraph('version.metadata', builder => { builder .select('key', 'value') - .modify('filterKeyValue', { tag: params.metadata }); + .modify('filterKeyValue', { metadata: params.metadata }); }) // match on objId parameter .modify('filterIds', params.objId) @@ -210,12 +210,11 @@ const service = { }) .modify('filterId', params.versionIds) // filter by objects that user(s) has READ permission at object or bucket-level - // TODO: consider instead doing `.whereIn('version.objectId', )` .modify((query) => { if (params.userId) { query - .allowGraph('object.[objectPermission, bucketPermission]') - .withGraphJoined('object.[objectPermission, bucketPermission]') + .allowGraph('object') + .withGraphJoined('object') .modifyGraph('object', query => { query.modify('hasPermission', params.userId, 'READ'); }) .whereNotNull('object.id'); } diff --git a/app/src/services/object.js b/app/src/services/object.js index 9f2ba5a0..30db2b8f 100644 --- a/app/src/services/object.js +++ b/app/src/services/object.js @@ -113,7 +113,7 @@ const service = { */ searchObjects: (params) => { return ObjectModel.query() - .allowGraph('[objectPermission, version]') + .allowGraph('version') .modify('filterIds', params.id) .modify('filterBucketIds', params.bucketId) .modify('filterPath', params.path) @@ -128,11 +128,17 @@ const service = { tag: params.tag }) .modify('hasPermission', params.userId, 'READ') - .then(result => result.map(row => { - // eslint-disable-next-line no-unused-vars - const { objectPermission, bucketPermission, version, ...object } = row; - return object; - })); + // format result + .then(result => { + // just return object table records + const res = result.map(row => { + // eslint-disable-next-line no-unused-vars + const { objectPermission, bucketPermission, version, ...object } = row; + return object; + }); + // remove duplicates + return [...new Map(res.map(item => [item.id, item])).values()]; + }); }, /** diff --git a/app/src/services/tag.js b/app/src/services/tag.js index c84d49be..9096f234 100644 --- a/app/src/services/tag.js +++ b/app/src/services/tag.js @@ -284,12 +284,11 @@ const service = { }) .modify('filterId', params.versionIds) // filter by objects that user(s) has READ permission at object or bucket-level - // TODO: consider instead doing `.whereIn('version.objectId', )` .modify((query) => { if (params.userId) { query - .allowGraph('object.[objectPermission, bucketPermission]') - .withGraphJoined('object.[objectPermission, bucketPermission]') + .allowGraph('object') + .withGraphJoined('object') .modifyGraph('object', query => { query.modify('hasPermission', params.userId, 'READ'); }) .whereNotNull('object.id'); } @@ -314,9 +313,9 @@ const service = { if (params.privacyMask) { query .select('key') - .modify( 'filterKey', { tag: params.tag }); + .modify('filterKey', { tag: params.tag }); } - else{ + else { query .select('key', 'value') .modify('filterKeyValue', { tag: params.tag }); diff --git a/charts/coms/Chart.yaml b/charts/coms/Chart.yaml index 52b4601f..f6d93482 100644 --- a/charts/coms/Chart.yaml +++ b/charts/coms/Chart.yaml @@ -3,7 +3,7 @@ name: common-object-management-service # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.0.8 +version: 0.0.9 kubeVersion: ">= 1.13.0" description: A microservice for managing access control to S3 Objects # A chart can be either an 'application' or a 'library' chart. diff --git a/charts/coms/README.md b/charts/coms/README.md index 8399915b..5a871ec9 100644 --- a/charts/coms/README.md +++ b/charts/coms/README.md @@ -1,6 +1,6 @@ # common-object-management-service -![Version: 0.0.8](https://img.shields.io/badge/Version-0.0.8-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square) +![Version: 0.0.9](https://img.shields.io/badge/Version-0.0.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square) A microservice for managing access control to S3 Objects