From 836fc805605f87d78bf98803a41a48e49bb781af Mon Sep 17 00:00:00 2001 From: Maha Benzekri Date: Thu, 14 Dec 2023 14:07:26 +0100 Subject: [PATCH 1/2] CLDSRV-451: updating buckettagging apis for impDeny --- lib/api/backbeat/listLifecycleCurrents.js | 4 +- lib/api/backbeat/listLifecycleNonCurrents.js | 4 +- .../listLifecycleOrphanDeleteMarkers.js | 4 +- lib/api/bucketDeleteTagging.js | 8 +- lib/api/bucketGetTagging.js | 8 +- lib/api/bucketPutTagging.js | 6 +- lib/metadata/metadataUtils.js | 90 ------------------- 7 files changed, 17 insertions(+), 107 deletions(-) diff --git a/lib/api/backbeat/listLifecycleCurrents.js b/lib/api/backbeat/listLifecycleCurrents.js index 4f4ae01e90..faba301ba0 100644 --- a/lib/api/backbeat/listLifecycleCurrents.js +++ b/lib/api/backbeat/listLifecycleCurrents.js @@ -1,7 +1,7 @@ const { errors } = require('arsenal'); const constants = require('../../../constants'); const services = require('../../services'); -const { metadataValidateBucket } = require('../../metadata/metadataUtils'); +const { standardMetadataValidateBucket } = require('../../metadata/metadataUtils'); const { pushMetric } = require('../../utapi/utilities'); const monitoring = require('../../utilities/metrics'); const { getLocationConstraintErrorMessage, processCurrents, @@ -77,7 +77,7 @@ function listLifecycleCurrents(authInfo, locationConstraints, request, log, call maxScannedLifecycleListingEntries, }; - return metadataValidateBucket(metadataValParams, log, (err, bucket) => { + return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => { if (err) { log.debug('error processing request', { method: 'metadataValidateBucket', error: err }); monitoring.promMetrics( diff --git a/lib/api/backbeat/listLifecycleNonCurrents.js b/lib/api/backbeat/listLifecycleNonCurrents.js index bfb556de30..bce5196413 100644 --- a/lib/api/backbeat/listLifecycleNonCurrents.js +++ b/lib/api/backbeat/listLifecycleNonCurrents.js @@ -1,7 +1,7 @@ const { errors, versioning } = require('arsenal'); const constants = require('../../../constants'); const services = require('../../services'); -const { metadataValidateBucket } = require('../../metadata/metadataUtils'); +const { standardMetadataValidateBucket } = require('../../metadata/metadataUtils'); const { pushMetric } = require('../../utapi/utilities'); const versionIdUtils = versioning.VersionID; const monitoring = require('../../utilities/metrics'); @@ -83,7 +83,7 @@ function listLifecycleNonCurrents(authInfo, locationConstraints, request, log, c listParams.versionIdMarker = params['version-id-marker'] ? versionIdUtils.decode(params['version-id-marker']) : undefined; - return metadataValidateBucket(metadataValParams, log, (err, bucket) => { + return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => { if (err) { log.debug('error processing request', { method: 'metadataValidateBucket', error: err }); monitoring.promMetrics( diff --git a/lib/api/backbeat/listLifecycleOrphanDeleteMarkers.js b/lib/api/backbeat/listLifecycleOrphanDeleteMarkers.js index b05050d30c..ae4224fbe7 100644 --- a/lib/api/backbeat/listLifecycleOrphanDeleteMarkers.js +++ b/lib/api/backbeat/listLifecycleOrphanDeleteMarkers.js @@ -1,7 +1,7 @@ const { errors } = require('arsenal'); const constants = require('../../../constants'); const services = require('../../services'); -const { metadataValidateBucket } = require('../../metadata/metadataUtils'); +const { standardMetadataValidateBucket } = require('../../metadata/metadataUtils'); const { pushMetric } = require('../../utapi/utilities'); const monitoring = require('../../utilities/metrics'); const { processOrphans, validateMaxScannedEntries } = require('../apiUtils/object/lifecycle'); @@ -68,7 +68,7 @@ function listLifecycleOrphanDeleteMarkers(authInfo, locationConstraints, request maxScannedLifecycleListingEntries, }; - return metadataValidateBucket(metadataValParams, log, (err, bucket) => { + return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => { if (err) { log.debug('error processing request', { method: 'metadataValidateBucket', error: err }); monitoring.promMetrics( diff --git a/lib/api/bucketDeleteTagging.js b/lib/api/bucketDeleteTagging.js index b452113fe8..ebea54b043 100644 --- a/lib/api/bucketDeleteTagging.js +++ b/lib/api/bucketDeleteTagging.js @@ -1,5 +1,5 @@ const collectCorsHeaders = require('../utilities/collectCorsHeaders'); -const { metadataValidateBucket } = require('../metadata/metadataUtils'); +const { standardMetadataValidateBucket } = require('../metadata/metadataUtils'); const { pushMetric } = require('../utapi/utilities'); const metadata = require('../metadata/wrapper'); const util = require('node:util'); @@ -19,18 +19,18 @@ async function bucketDeleteTagging(authInfo, request, log, callback) { log.debug('processing request', { method: 'bucketDeleteTagging', bucketName }); let bucket; - const metadataValidateBucketPromise = util.promisify(metadataValidateBucket); + const metadataValidateBucketPromise = util.promisify(standardMetadataValidateBucket); let updateBucketPromise = util.promisify(metadata.updateBucket); // necessary to bind metadata as updateBucket calls 'this', causing undefined otherwise updateBucketPromise = updateBucketPromise.bind(metadata); const metadataValParams = { authInfo, bucketName, - requestType: 'bucketDeleteTagging', + requestType: request.apiMethods || 'bucketDeleteTagging', }; try { - bucket = await metadataValidateBucketPromise(metadataValParams, log); + bucket = await metadataValidateBucketPromise(metadataValParams, request.actionImplicitDenies, log); bucket.setTags([]); // eslint-disable-next-line no-unused-expressions await updateBucketPromise(bucket.getName(), bucket, log); diff --git a/lib/api/bucketGetTagging.js b/lib/api/bucketGetTagging.js index 4e6a255959..9e9d48889c 100644 --- a/lib/api/bucketGetTagging.js +++ b/lib/api/bucketGetTagging.js @@ -1,4 +1,4 @@ -const { metadataValidateBucket } = require('../metadata/metadataUtils'); +const { standardMetadataValidateBucket } = require('../metadata/metadataUtils'); const util = require('node:util'); const collectCorsHeaders = require('../utilities/collectCorsHeaders'); const { checkExpectedBucketOwner } = require('./apiUtils/authorization/bucketOwner'); @@ -64,13 +64,13 @@ async function bucketGetTagging(authInfo, request, log, callback) { log.debug('processing request', { method: 'bucketGetTagging' }); const { bucketName, headers } = request; - const metadataValidateBucketPromise = util.promisify(metadataValidateBucket); + const metadataValidateBucketPromise = util.promisify(standardMetadataValidateBucket); const checkExpectedBucketOwnerPromise = util.promisify(checkExpectedBucketOwner); const metadataValParams = { authInfo, bucketName, - requestType: 'bucketGetTagging', + requestType: request.apiMethods || 'bucketGetTagging', request, }; @@ -78,7 +78,7 @@ async function bucketGetTagging(authInfo, request, log, callback) { let xml = null; try { - bucket = await metadataValidateBucketPromise(metadataValParams, log); + bucket = await metadataValidateBucketPromise(metadataValParams, request.actionImplicitDenies, log); // eslint-disable-next-line no-unused-expressions await checkExpectedBucketOwnerPromise(headers, bucket, log); const tags = bucket.getTags(); diff --git a/lib/api/bucketPutTagging.js b/lib/api/bucketPutTagging.js index eb8147c180..18a5a58674 100644 --- a/lib/api/bucketPutTagging.js +++ b/lib/api/bucketPutTagging.js @@ -3,7 +3,7 @@ const { s3middleware } = require('arsenal'); const collectCorsHeaders = require('../utilities/collectCorsHeaders'); -const { metadataValidateBucket } = require('../metadata/metadataUtils'); +const { standardMetadataValidateBucket } = require('../metadata/metadataUtils'); const metadata = require('../metadata/wrapper'); const { pushMetric } = require('../utapi/utilities'); const { checkExpectedBucketOwner } = require('./apiUtils/authorization/bucketOwner'); @@ -38,11 +38,11 @@ function bucketPutTagging(authInfo, request, log, callback) { const metadataValParams = { authInfo, bucketName, - requestType: 'bucketPutTagging', + requestType: request.apiMethods || 'bucketPutTagging', }; let bucket = null; return waterfall([ - next => metadataValidateBucket(metadataValParams, log, + next => standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, b) => { bucket = b; return next(err); diff --git a/lib/metadata/metadataUtils.js b/lib/metadata/metadataUtils.js index d3eb365007..16c1a1f91f 100644 --- a/lib/metadata/metadataUtils.js +++ b/lib/metadata/metadataUtils.js @@ -169,70 +169,6 @@ function validateBucket(bucket, params, log, actionImplicitDenies = {}) { } return null; } - -/** metadataValidateBucketAndObj - retrieve bucket and object md from metadata - * and check if user is authorized to access them. - * @param {object} params - function parameters - * @param {AuthInfo} params.authInfo - AuthInfo class instance, requester's info - * @param {string} params.bucketName - name of bucket - * @param {string} params.objectKey - name of object - * @param {string} [params.versionId] - version id if getting specific version - * @param {string} params.requestType - type of request - * @param {object} params.request - http request object - * @param {RequestLogger} log - request logger - * @param {function} callback - callback - * @return {undefined} - and call callback with params err, bucket md - */ -function metadataValidateBucketAndObj(params, log, callback) { - const { authInfo, bucketName, objectKey, versionId, getDeleteMarker, - requestType, request } = params; - async.waterfall([ - next => { - // versionId may be 'null', which asks metadata to fetch the null key specifically - const getOptions = { versionId }; - if (getDeleteMarker) { - getOptions.getDeleteMarker = true; - } - return metadata.getBucketAndObjectMD(bucketName, objectKey, getOptions, log, next); - }, - (getResult, next) => { - const bucket = getResult.bucket ? - BucketInfo.deSerialize(getResult.bucket) : undefined; - if (!bucket) { - log.debug('bucketAttrs is undefined', { - bucket: bucketName, - method: 'metadataValidateBucketAndObj', - }); - return next(errors.NoSuchBucket); - } - const validationError = validateBucket(bucket, params, log); - if (validationError) { - return next(validationError, bucket); - } - const objMD = getResult.obj ? JSON.parse(getResult.obj) : undefined; - if (!objMD && versionId === 'null') { - return getNullVersionFromMaster(bucketName, objectKey, log, - (err, nullVer) => next(err, bucket, nullVer)); - } - return next(null, bucket, objMD); - }, - (bucket, objMD, next) => { - const canonicalID = authInfo.getCanonicalID(); - if (!isObjAuthorized(bucket, objMD, requestType, canonicalID, authInfo, log, request)) { - log.debug('access denied for user on object', { requestType }); - return next(errors.AccessDenied, bucket); - } - return next(null, bucket, objMD); - }, - ], (err, bucket, objMD) => { - if (err) { - // still return bucket for cors headers - return callback(err, bucket); - } - return callback(null, bucket, objMD); - }); -} - /** standardMetadataValidateBucketAndObj - retrieve bucket and object md from metadata * and check if user is authorized to access them. * @param {object} params - function parameters @@ -310,30 +246,6 @@ function standardMetadataValidateBucketAndObj(params, actionImplicitDenies, log, return callback(null, bucket, objMD); }); } - -/** metadataValidateBucket - retrieve bucket from metadata and check if user - * is authorized to access it - * @param {object} params - function parameters - * @param {AuthInfo} params.authInfo - AuthInfo class instance, requester's info - * @param {string} params.bucketName - name of bucket - * @param {string} params.requestType - type of request - * @param {string} params.request - http request object - * @param {RequestLogger} log - request logger - * @param {function} callback - callback - * @return {undefined} - and call callback with params err, bucket md - */ -function metadataValidateBucket(params, log, callback) { - const { bucketName } = params; - return metadata.getBucket(bucketName, log, (err, bucket) => { - if (err) { - log.debug('metadata getbucket failed', { error: err }); - return callback(err); - } - const validationError = validateBucket(bucket, params, log); - return callback(validationError, bucket); - }); -} - /** standardMetadataValidateBucket - retrieve bucket from metadata and check if user * is authorized to access it * @param {object} params - function parameters @@ -367,8 +279,6 @@ module.exports = { validateBucket, metadataGetObject, metadataGetObjects, - metadataValidateBucketAndObj, - metadataValidateBucket, standardMetadataValidateBucketAndObj, standardMetadataValidateBucket, }; From 717228bdfc25b7bf9ab0b072882998deaaebfd49 Mon Sep 17 00:00:00 2001 From: Maha Benzekri Date: Thu, 14 Dec 2023 16:59:10 +0100 Subject: [PATCH 2/2] CLDSRV-451: bump Cloudserver version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4ad1ecd06b..0d86f78db8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "s3", - "version": "7.70.35", + "version": "7.70.36", "description": "S3 connector", "main": "index.js", "engines": {