diff --git a/lib/api/apiUtils/object/objectRestore.js b/lib/api/apiUtils/object/objectRestore.js index cf4c66e88d..6a402da70a 100644 --- a/lib/api/apiUtils/object/objectRestore.js +++ b/lib/api/apiUtils/object/objectRestore.js @@ -64,7 +64,8 @@ function objectRestore(metadata, mdUtils, userInfo, request, log, callback) { return async.waterfall([ // get metadata of bucket and object function validateBucketAndObject(next) { - return mdUtils.metadataValidateBucketAndObj(mdValueParams, log, (err, bucketMD, objectMD) => { + return mdUtils.standardMetadataValidateBucketAndObj(mdValueParams, request.actionImplicitDenies, + log, (err, bucketMD, objectMD) => { if (err) { log.trace('request authorization failed', { method: METHOD, error: err }); return next(err); diff --git a/lib/api/backbeat/listLifecycleCurrents.js b/lib/api/backbeat/listLifecycleCurrents.js index 73dc53aba6..10b6f74254 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/monitoringHandler'); 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 81ac851f97..f48c62037f 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/monitoringHandler'); @@ -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 bee6b9562c..a9eea07c33 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/monitoringHandler'); 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 360119f6c2..f662d23b61 100644 --- a/lib/api/bucketDeleteTagging.js +++ b/lib/api/bucketDeleteTagging.js @@ -1,6 +1,6 @@ const { waterfall } = require('async'); const collectCorsHeaders = require('../utilities/collectCorsHeaders'); -const { metadataValidateBucket } = require('../metadata/metadataUtils'); +const { standardMetadataValidateBucket } = require('../metadata/metadataUtils'); const { pushMetric } = require('../utapi/utilities'); const monitoring = require('../utilities/monitoringHandler'); const metadata = require('../metadata/wrapper'); @@ -20,12 +20,12 @@ function bucketDeleteTagging(authInfo, request, log, callback) { const metadataValParams = { authInfo, bucketName, - requestType: 'bucketDeleteTagging', + requestType: request.apiMethods || 'bucketDeleteTagging', }; let bucket = null; return waterfall([ - next => metadataValidateBucket(metadataValParams, log, + next => standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, b) => { bucket = b; bucket.setTags([]); diff --git a/lib/api/bucketGetTagging.js b/lib/api/bucketGetTagging.js index 9daeb9526f..5776c8a341 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 collectCorsHeaders = require('../utilities/collectCorsHeaders'); const { checkExpectedBucketOwner } = require('./apiUtils/authorization/bucketOwner'); const { pushMetric } = require('../utapi/utilities'); @@ -67,7 +67,7 @@ function bucketGetTagging(authInfo, request, log, callback) { const metadataValParams = { authInfo, bucketName, - requestType: 'bucketGetTagging', + requestType: request.apiMethods || 'bucketGetTagging', request, }; let bucket = null; @@ -75,7 +75,7 @@ function bucketGetTagging(authInfo, request, log, callback) { let tags = null; return waterfall([ - next => metadataValidateBucket(metadataValParams, log, + next => standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, b) => { bucket = b; return next(err); diff --git a/lib/api/bucketPutTagging.js b/lib/api/bucketPutTagging.js index 5a3452e03c..3c6670e09d 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/api/metadataSearch.js b/lib/api/metadataSearch.js index 7c18969899..12a9f049a2 100644 --- a/lib/api/metadataSearch.js +++ b/lib/api/metadataSearch.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 collectCorsHeaders = require('../utilities/collectCorsHeaders'); const { pushMetric } = require('../utapi/utilities'); const validateSearchParams = require('../api/apiUtils/bucket/validateSearch'); @@ -103,7 +103,7 @@ function metadataSearch(authInfo, request, log, callback) { listParams.marker = params.marker; } - metadataValidateBucket(metadataValParams, log, (err, bucket) => { + standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => { const corsHeaders = collectCorsHeaders(request.headers.origin, request.method, bucket); if (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, }; diff --git a/package.json b/package.json index e59bf3ea63..131199e781 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@zenko/cloudserver", - "version": "8.6.16", + "version": "8.6.17", "description": "Zenko CloudServer, an open-source Node.js implementation of a server handling the Amazon S3 protocol", "main": "index.js", "engines": { diff --git a/tests/unit/api/objectRestore.js b/tests/unit/api/objectRestore.js index 4997c074ef..7e461fa76b 100644 --- a/tests/unit/api/objectRestore.js +++ b/tests/unit/api/objectRestore.js @@ -20,6 +20,7 @@ const bucketPutRequest = { bucketName, headers: { host: `${bucketName}.s3.amazonaws.com` }, url: '/', + actionImplicitDenies: false, }; const putObjectRequest = new DummyRequest({