diff --git a/lib/api/apiUtils/bucket/updateEncryption.js b/lib/api/apiUtils/bucket/updateEncryption.js index 5db3152423..f2d90d2906 100644 --- a/lib/api/apiUtils/bucket/updateEncryption.js +++ b/lib/api/apiUtils/bucket/updateEncryption.js @@ -108,7 +108,7 @@ function updateObjectEncryption(bucket, objMD, objectKey, log, keyArnPrefix, opt function updateEncryption(err, bucket, objMD, objectKey, log, opts, cb) { // Error passed here to call the function inbetween the metadataValidate and its callback if (err) { - return cb(err); + return cb(err, bucket); } // if objMD missing, still try updateBucketEncryption if (!config.sseMigration) { diff --git a/tests/unit/api/objectGet.js b/tests/unit/api/objectGet.js index 261bc149e0..25060022e4 100644 --- a/tests/unit/api/objectGet.js +++ b/tests/unit/api/objectGet.js @@ -4,7 +4,8 @@ const crypto = require('crypto'); const { parseString } = require('xml2js'); const { bucketPut } = require('../../../lib/api/bucketPut'); -const { cleanup, DummyRequestLogger, makeAuthInfo } = require('../helpers'); +const bucketPutCors = require('../../../lib/api/bucketPutCors'); +const { cleanup, DummyRequestLogger, makeAuthInfo, CorsConfigTester } = require('../helpers'); const completeMultipartUpload = require('../../../lib/api/completeMultipartUpload'); const DummyRequest = require('../DummyRequest'); @@ -518,3 +519,106 @@ describe('objectGet API', () => { }); }); }); + +describe('objectGet API - CORS headers on 403 responses', () => { + const ownerAuthInfo = makeAuthInfo('accessKey1'); + const otherAuthInfo = makeAuthInfo('accessKey2'); + const corsTestBucket = 'corsbucket'; + const corsTestObject = 'corsObject'; + const postBody = Buffer.from('body content', 'utf8'); + const corsConfig = new CorsConfigTester(); + + const putBucketRequest = { + bucketName: corsTestBucket, + namespace, + headers: {}, + url: `/${corsTestBucket}`, + actionImplicitDenies: false, + }; + + beforeEach(done => { + cleanup(); + const putObjectRequest = new DummyRequest({ + bucketName: corsTestBucket, + namespace, + objectKey: corsTestObject, + headers: { 'content-length': String(postBody.length) }, + parsedContentLength: postBody.length, + url: `/${corsTestBucket}/${corsTestObject}`, + }, postBody); + bucketPut(ownerAuthInfo, putBucketRequest, log, err => { + assert.ifError(err); + const putCorsRequest = corsConfig + .createBucketCorsRequest('PUT', corsTestBucket); + bucketPutCors(ownerAuthInfo, putCorsRequest, log, err => { + assert.ifError(err); + objectPut(ownerAuthInfo, putObjectRequest, undefined, log, err => { + assert.ifError(err); + done(); + }); + }); + }); + }); + + afterEach(() => cleanup()); + + it('should return CORS headers on a 403 AccessDenied response for objectGet', done => { + const origin = 'http://www.example.com'; + const getRequest = { + bucketName: corsTestBucket, + namespace, + objectKey: corsTestObject, + headers: { origin }, + method: 'GET', + url: `/${corsTestBucket}/${corsTestObject}`, + actionImplicitDenies: false, + }; + objectGet(otherAuthInfo, getRequest, false, log, (err, _data, corsHeaders) => { + assert(err, 'expected AccessDenied error'); + assert(err.is.AccessDenied, `expected AccessDenied, got ${err}`); + assert(corsHeaders, 'expected CORS headers to be present'); + assert.strictEqual(corsHeaders['access-control-allow-origin'], origin, + 'expected access-control-allow-origin header'); + done(); + }); + }); + + it('should return CORS headers with wildcard origin on a 403 response', done => { + const getRequest = { + bucketName: corsTestBucket, + namespace, + objectKey: corsTestObject, + headers: { origin: 'http://any-origin.com' }, + method: 'GET', + url: `/${corsTestBucket}/${corsTestObject}`, + actionImplicitDenies: false, + }; + objectGet(otherAuthInfo, getRequest, false, log, (err, _data, corsHeaders) => { + assert(err, 'expected AccessDenied error'); + assert(err.is.AccessDenied, `expected AccessDenied, got ${err}`); + assert(corsHeaders, 'expected CORS headers to be present'); + assert.strictEqual(corsHeaders['access-control-allow-origin'], '*', + 'expected wildcard access-control-allow-origin header'); + done(); + }); + }); + + it('should not return CORS headers when no origin header is present', done => { + const getRequest = { + bucketName: corsTestBucket, + namespace, + objectKey: corsTestObject, + headers: {}, + method: 'GET', + url: `/${corsTestBucket}/${corsTestObject}`, + actionImplicitDenies: false, + }; + objectGet(otherAuthInfo, getRequest, false, log, (err, _data, corsHeaders) => { + assert(err, 'expected AccessDenied error'); + assert(err.is.AccessDenied, `expected AccessDenied, got ${err}`); + assert.deepStrictEqual(corsHeaders, {}, + 'expected no CORS headers when no origin header'); + done(); + }); + }); +});