Skip to content

Commit 43860fe

Browse files
committed
Merge remote-tracking branch 'origin/bugfix/CLDSRV-729-rm-md5-requirement-backport-7.70' into w/7.70/bugfix/CLDSRV-729-rm-md5-requirement-backport-7.70
2 parents 7709f0d + afe844d commit 43860fe

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

tests/unit/api/multiObjectDelete.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,3 +481,122 @@ describe('multiObjectDelete function', () => {
481481
});
482482
});
483483
});
484+
485+
describe('multiObjectDelete function', () => {
486+
afterEach(() => {
487+
sinon.restore();
488+
});
489+
490+
it('should not authorize the bucket and initial IAM authorization results', done => {
491+
const post = '<Delete><Object><Key>objectname</Key></Object></Delete>';
492+
const request = new DummyRequest({
493+
bucketName: 'bucketname',
494+
objectKey: 'objectname',
495+
parsedHost: 'localhost',
496+
headers: {
497+
'content-md5': crypto.createHash('md5').update(post, 'utf8').digest('base64'),
498+
},
499+
post,
500+
socket: {
501+
remoteAddress: '127.0.0.1',
502+
},
503+
url: '/bucketname',
504+
});
505+
const authInfo = makeAuthInfo('123456');
506+
507+
sinon.stub(metadataWrapper, 'getBucket').callsFake((bucketName, log, cb) =>
508+
cb(null, new BucketInfo(
509+
'bucketname',
510+
'123456',
511+
'accountA',
512+
new Date().toISOString(),
513+
15,
514+
)));
515+
516+
multiObjectDelete.multiObjectDelete(authInfo, request, log, (err, res) => {
517+
// Expected result is an access denied on the object, and no error, as the API was authorized
518+
assert.strictEqual(err, null);
519+
assert.strictEqual(
520+
res.includes('<Error><Key>objectname</Key><Code>AccessDenied</Code>'),
521+
true
522+
);
523+
done();
524+
});
525+
});
526+
527+
it('should accept request when content-md5 header is missing', done => {
528+
const post = '<Delete><Object><Key>objectname</Key></Object></Delete>';
529+
const testObjectKey = 'objectname';
530+
const testBucketName = 'test-bucket';
531+
const request = new DummyRequest({
532+
bucketName: testBucketName,
533+
objectKey: testObjectKey,
534+
parsedHost: 'localhost',
535+
headers: {
536+
// No content-md5 header
537+
},
538+
post,
539+
socket: {
540+
remoteAddress: '127.0.0.1',
541+
},
542+
url: `/${testBucketName}`,
543+
});
544+
// Use the same canonicalID for both authInfo and bucket owner to avoid AccessDenied
545+
const testAuthInfo = makeAuthInfo(canonicalID);
546+
547+
// Create bucket with proper ownership
548+
const testBucketRequest = new DummyRequest({
549+
bucketName: testBucketName,
550+
namespace,
551+
headers: {},
552+
url: `/${testBucketName}`,
553+
});
554+
// Create object to delete
555+
const testObjectRequest = new DummyRequest({
556+
bucketName: testBucketName,
557+
namespace,
558+
objectKey: testObjectKey,
559+
headers: {},
560+
url: `/${testBucketName}/${testObjectKey}`,
561+
}, postBody);
562+
563+
bucketPut(testAuthInfo, testBucketRequest, log, () => {
564+
objectPut(testAuthInfo, testObjectRequest, undefined, log, () => {
565+
multiObjectDelete.multiObjectDelete(testAuthInfo, request, log, (err, res) => {
566+
// Request should succeed even without content-md5 header
567+
assert.strictEqual(err, null);
568+
assert.strictEqual(typeof res, 'string');
569+
// Should contain successful deletion response
570+
assert.strictEqual(res.includes('<Deleted><Key>objectname</Key></Deleted>'), true);
571+
done();
572+
});
573+
});
574+
});
575+
});
576+
577+
it('should reject request with BadDigest error when content-md5 header mismatches', done => {
578+
const post = '<Delete><Object><Key>objectname</Key></Object></Delete>';
579+
const incorrectMd5 = 'incorrectMd5Hash';
580+
const request = new DummyRequest({
581+
bucketName: 'bucketname',
582+
objectKey: 'objectname',
583+
parsedHost: 'localhost',
584+
headers: {
585+
'content-md5': incorrectMd5,
586+
},
587+
post,
588+
socket: {
589+
remoteAddress: '127.0.0.1',
590+
},
591+
url: '/bucketname',
592+
});
593+
const authInfo = makeAuthInfo('123456');
594+
595+
multiObjectDelete.multiObjectDelete(authInfo, request, log, (err, res) => {
596+
// Should return BadDigest error for mismatched content-md5
597+
assert.strictEqual(err.is.BadDigest, true);
598+
assert.strictEqual(res, undefined);
599+
done();
600+
});
601+
});
602+
});

0 commit comments

Comments
 (0)