Skip to content

Commit 11b219b

Browse files
committed
Merge remote-tracking branch 'origin/improvement/CLDSRV-868/user-metadata' into w/9.4/improvement/CLDSRV-868/user-metadata
2 parents 6b4bc39 + 29f89da commit 11b219b

File tree

10 files changed

+972
-743
lines changed

10 files changed

+972
-743
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"homepage": "https://github.com/scality/S3#readme",
2121
"dependencies": {
2222
"@aws-sdk/client-iam": "^3.930.0",
23-
"@aws-sdk/client-s3": "^3.908.0",
23+
"@aws-sdk/client-s3": "^3.1013.0",
2424
"@aws-sdk/client-sts": "^3.930.0",
2525
"@aws-sdk/credential-providers": "^3.864.0",
2626
"@aws-sdk/middleware-retry": "^3.374.0",
@@ -65,6 +65,7 @@
6565
},
6666
"devDependencies": {
6767
"@eslint/compat": "^1.2.2",
68+
"@scality/cloudserverclient": "1.0.7",
6869
"@scality/eslint-config-scality": "scality/Guidelines#8.3.0",
6970
"eslint": "^9.14.0",
7071
"eslint-plugin-import": "^2.31.0",
@@ -87,7 +88,7 @@
8788
"resolutions": {
8889
"jsonwebtoken": "^9.0.0",
8990
"nan": "v2.22.0",
90-
"fast-xml-parser": "^5.3.8"
91+
"fast-xml-parser": "^5.5.6"
9192
},
9293
"mocha": {
9394
"recursive": true,

tests/functional/aws-node-sdk/test/bucket/get.js

Lines changed: 10 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const {
66
ListObjectsV2Command,
77
S3Client,
88
} = require('@aws-sdk/client-s3');
9-
const { streamCollector } = require('@smithy/node-http-handler');
9+
const { ListObjectsV2ExtendedCommand } = require('@scality/cloudserverclient');
1010
const {
1111
IAMClient,
1212
CreatePolicyCommand,
@@ -17,8 +17,6 @@ const {
1717
DeletePolicyCommand,
1818
DeleteUserCommand,
1919
} = require('@aws-sdk/client-iam');
20-
const { parseStringPromise } = require('xml2js');
21-
2220
const withV4 = require('../support/withV4');
2321
const BucketUtility = require('../../lib/utility/bucket-util');
2422
const bucketSchema = require('../../schema/bucket');
@@ -609,75 +607,6 @@ describe('GET Bucket - AWS.S3.listObjects', () => {
609607
await iamClient.send(new DeleteUserCommand({ UserName: userWithoutPermission.UserName }));
610608
});
611609

612-
const listObjectsV2WithOptionalAttributes = async (s3, bucket, headerValue) => {
613-
const localS3 = s3;
614-
let rawXml = '';
615-
616-
const addHeaderMiddleware = next => async args => {
617-
const localArgs = args;
618-
localArgs.request.headers['x-amz-optional-object-attributes'] = headerValue;
619-
return next(localArgs);
620-
};
621-
622-
const originalHandler = s3.config.requestHandler;
623-
const wrappedHandler = {
624-
async handle(request, options) {
625-
const { response } = await originalHandler.handle(request, options);
626-
627-
if (response && response.body) {
628-
const collected = await streamCollector(response.body);
629-
const buffer = Buffer.from(collected);
630-
rawXml = buffer.toString('utf-8');
631-
632-
const { Readable } = require('stream');
633-
response.body = Readable.from([buffer]);
634-
}
635-
636-
return { response };
637-
},
638-
destroy() {
639-
if (originalHandler.destroy) {
640-
originalHandler.destroy();
641-
}
642-
}
643-
};
644-
645-
localS3.config.requestHandler = wrappedHandler;
646-
localS3.middlewareStack.add(addHeaderMiddleware, {
647-
step: 'build',
648-
name: 'addOptionalAttributesHeader',
649-
});
650-
651-
try {
652-
const result = await s3.send(new ListObjectsV2Command({ Bucket: bucket }));
653-
654-
if (!rawXml) {
655-
return result;
656-
}
657-
658-
const parsedXml = await parseStringPromise(rawXml);
659-
const contents = result.Contents;
660-
const parsedContents = parsedXml?.ListBucketResult?.Contents;
661-
662-
if (!contents || !parsedContents) {
663-
return result;
664-
}
665-
666-
if (parsedContents[0]?.['x-amz-meta-department']) {
667-
contents[0]['x-amz-meta-department'] = parsedContents[0]['x-amz-meta-department'][0];
668-
}
669-
670-
if (parsedContents[0]?.['x-amz-meta-hr']) {
671-
contents[0]['x-amz-meta-hr'] = parsedContents[0]['x-amz-meta-hr'][0];
672-
}
673-
674-
return result;
675-
} finally {
676-
localS3.config.requestHandler = originalHandler;
677-
localS3.middlewareStack.remove('addOptionalAttributesHeader');
678-
}
679-
};
680-
681610
it('should return an XML if the header is set', async () => {
682611
const s3 = bucketUtil.s3;
683612
const Bucket = bucketName;
@@ -690,11 +619,10 @@ describe('GET Bucket - AWS.S3.listObjects', () => {
690619
hr: 'true',
691620
},
692621
}));
693-
const result = await listObjectsV2WithOptionalAttributes(
694-
s3,
622+
const result = await s3.send(new ListObjectsV2ExtendedCommand({
695623
Bucket,
696-
'x-amz-meta-*,RestoreStatus,x-amz-meta-department',
697-
);
624+
ObjectAttributes: ['x-amz-meta-*', 'RestoreStatus', 'x-amz-meta-department'],
625+
}));
698626

699627
assert.strictEqual(result.Contents.length, 1);
700628
assert.strictEqual(result.Contents[0].Key, 'super-power-object');
@@ -716,11 +644,10 @@ describe('GET Bucket - AWS.S3.listObjects', () => {
716644
}));
717645

718646
try {
719-
await listObjectsV2WithOptionalAttributes(
720-
s3ClientWithoutPermission,
647+
await s3ClientWithoutPermission.send(new ListObjectsV2ExtendedCommand({
721648
Bucket,
722-
'x-amz-meta-*,RestoreStatus,x-amz-meta-department',
723-
);
649+
ObjectAttributes: ['x-amz-meta-*', 'RestoreStatus', 'x-amz-meta-department'],
650+
}));
724651
throw new Error('Request should have been rejected');
725652
} catch (err) {
726653
if (err.message === 'Request should have been rejected') {
@@ -743,11 +670,10 @@ describe('GET Bucket - AWS.S3.listObjects', () => {
743670
hr: 'true',
744671
},
745672
}));
746-
const result = await listObjectsV2WithOptionalAttributes(
747-
s3ClientWithoutPermission,
673+
const result = await s3ClientWithoutPermission.send(new ListObjectsV2ExtendedCommand({
748674
Bucket,
749-
'RestoreStatus',
750-
);
675+
ObjectAttributes: ['RestoreStatus'],
676+
}));
751677

752678
assert.strictEqual(result.Contents.length, 1);
753679
assert.strictEqual(result.Contents[0].Key, 'super-power-object');

tests/functional/aws-node-sdk/test/bucket/head.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ describe('HEAD bucket', () => {
2121
await s3.send(new HeadBucketCommand({ Bucket: '' }));
2222
assert.fail('Expected failure but got success');
2323
} catch (err) {
24-
assert.strictEqual(err.message, 'Empty value provided for input HTTP label: Bucket.');
24+
assert.strictEqual(err.$metadata.httpStatusCode, 405);
25+
assert.strictEqual(err.name, 'Unknown');
2526
}
2627
});
2728
});

tests/functional/aws-node-sdk/test/multipleBackend/unknownEndpoint.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ let s3;
2121
describe('Requests to ip endpoint not in config', () => {
2222
withV4(sigCfg => {
2323
before(() => {
24-
bucketUtil = new BucketUtility('default', sigCfg);
25-
// change endpoint to endpoint with ip address
26-
// not in config
27-
bucketUtil.s3.config.endpoint = specifiedEndpoint;
24+
bucketUtil = new BucketUtility('default', { ...sigCfg, endpoint: specifiedEndpoint });
2825
s3 = bucketUtil.s3;
2926
});
3027

tests/functional/aws-node-sdk/test/object/deleteObject.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ describe('DELETE object', () => {
113113
const bucketName = 'testdeleteobjectlockbucket';
114114
let versionIdOne;
115115
let versionIdTwo;
116-
const retainDate = moment().add(10, 'days');
116+
const retainDate = moment().add(10, 'days').toDate();
117117

118118
before(async () => {
119119
try {

tests/functional/aws-node-sdk/test/object/get.js

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -224,18 +224,6 @@ describe('GET object', () => {
224224
await s3.send(new DeleteBucketCommand({ Bucket: bucketName }));
225225
});
226226

227-
228-
it('should return an error to get request without a valid ' +
229-
'bucket name',
230-
done => {
231-
s3.send(new GetObjectCommand({ Bucket: '', Key: 'somekey' })).then(() => {
232-
assert.fail('Expected failure but got success');
233-
}).catch(err => {
234-
assert.strictEqual(err.message, 'Empty value provided for input HTTP label: Bucket.');
235-
return done();
236-
});
237-
});
238-
239227
it('should return NoSuchKey error when no such object',
240228
done => {
241229
s3.send(new GetObjectCommand({ Bucket: bucketName, Key: 'nope' })).then(() => {
@@ -1073,7 +1061,7 @@ describeSkipIfCeph('GET object with object lock', () => {
10731061
const params = {
10741062
Bucket: bucket,
10751063
Key: key,
1076-
ObjectLockRetainUntilDate: mockDate,
1064+
ObjectLockRetainUntilDate: mockDate.toDate(),
10771065
ObjectLockMode: mockMode,
10781066
ObjectLockLegalHoldStatus: 'ON',
10791067
};

0 commit comments

Comments
 (0)