Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 8 additions & 32 deletions lib/api/apiUtils/object/versioning.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,47 +494,23 @@ function restoreMetadata(objMD, metadataStoreParams) {
}
});

// System metadata, object lock info, ACL and replication info come from the
// archived object only, not from the restore request or the bucket config
metadataStoreParams.acl = objMD.acl;
metadataStoreParams.contentType = objMD['content-type'];
metadataStoreParams.cacheControl = objMD['cache-control'];
metadataStoreParams.contentDisposition = objMD['content-disposition'];
metadataStoreParams.contentEncoding = objMD['content-encoding'];
metadataStoreParams.expires = objMD.expires;
metadataStoreParams.replicationInfo = objMD.replicationInfo;
metadataStoreParams.retentionMode = objMD.retentionMode;
metadataStoreParams.retentionDate = objMD.retentionDate;

// Object lock info and ACL come from the archived object only, not from
// the restore request or the bucket default retention
metadataStoreParams.legalHold = objMD.legalHold;
delete metadataStoreParams.defaultRetention;
if (metadataStoreParams.headers) {
metadataStoreParams.headers = { ...metadataStoreParams.headers };
delete metadataStoreParams.headers['x-amz-object-lock-mode'];
delete metadataStoreParams.headers['x-amz-object-lock-retain-until-date'];
delete metadataStoreParams.headers['x-amz-object-lock-legal-hold'];
delete metadataStoreParams.headers['x-amz-acl'];
delete metadataStoreParams.headers['x-amz-grant-full-control'];
delete metadataStoreParams.headers['x-amz-grant-read'];
delete metadataStoreParams.headers['x-amz-grant-read-acp'];
delete metadataStoreParams.headers['x-amz-grant-write-acp'];
}

if (objMD['x-amz-website-redirect-location']) {
if (!metadataStoreParams.headers) {
metadataStoreParams.headers = {};
}
metadataStoreParams.headers['x-amz-website-redirect-location'] = objMD['x-amz-website-redirect-location'];
}

if (objMD.replicationInfo) {
metadataStoreParams.replicationInfo = objMD.replicationInfo;
}

if (objMD.legalHold) {
metadataStoreParams.legalHold = objMD.legalHold;
}

if (objMD.acl) {
metadataStoreParams.acl = objMD.acl;
}
metadataStoreParams.headers = {
'x-amz-website-redirect-location': objMD['x-amz-website-redirect-location'],
};

metadataStoreParams.creationTime = objMD['creation-time'];
metadataStoreParams.lastModifiedDate = objMD['last-modified'];
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenko/cloudserver",
"version": "9.4.6",
"version": "9.4.7",
"description": "Zenko CloudServer, an open-source Node.js implementation of a server handling the Amazon S3 protocol",
"main": "index.js",
"engines": {
Expand Down
69 changes: 57 additions & 12 deletions tests/unit/api/apiUtils/versioning.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,8 +705,12 @@ describe('versioning helpers', () => {
contentDisposition: undefined,
contentEncoding: undefined,
expires: undefined,
headers: { 'x-amz-website-redirect-location': undefined },
retentionMode: undefined,
retentionDate: undefined,
legalHold: undefined,
acl: undefined,
replicationInfo: undefined,
};
let clock;

Expand Down Expand Up @@ -970,7 +974,6 @@ describe('versioning helpers', () => {
},
metadataStoreParams: {
contentType: 'binary/octet-stream',
headers: {},
},
expectedRes: {
creationTime: now,
Expand Down Expand Up @@ -1103,7 +1106,7 @@ describe('versioning helpers', () => {
},
},
{
description: 'Should drop object lock headers',
description: 'Should drop the restore request headers',
objMD: {
versionId: '2345678',
'creation-time': now,
Expand All @@ -1119,13 +1122,18 @@ describe('versioning helpers', () => {
metadataStoreParams: {
headers: {
host: 'localhost',
'x-amz-website-redirect-location': '/elsewhere',
'x-amz-object-lock-mode': 'GOVERNANCE',
'x-amz-object-lock-retain-until-date': new Date(now).toISOString(),
'x-amz-object-lock-legal-hold': 'ON',
'x-amz-acl': 'public-read-write',
'x-amz-grant-full-control': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
'x-amz-grant-read': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
'x-amz-grant-read-acp': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
'x-amz-grant-write-acp': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
},
},
expectedRes: {
headers: { host: 'localhost' },
creationTime: now,
lastModifiedDate: now,
updateMicroVersionId: true,
Expand All @@ -1142,7 +1150,7 @@ describe('versioning helpers', () => {
},
},
{
description: 'Should drop ACL headers',
description: 'Should not take legal hold from the restore request',
objMD: {
versionId: '2345678',
'creation-time': now,
Expand All @@ -1156,17 +1164,51 @@ describe('versioning helpers', () => {
},
},
metadataStoreParams: {
headers: {
host: 'localhost',
'x-amz-acl': 'public-read-write',
'x-amz-grant-full-control': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
'x-amz-grant-read': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
'x-amz-grant-read-acp': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
'x-amz-grant-write-acp': 'uri=http://acs.amazonaws.com/groups/global/AllUsers',
legalHold: true,
},
expectedRes: {
creationTime: now,
lastModifiedDate: now,
updateMicroVersionId: true,
originOp: 's3:ObjectRestore:Completed',
taggingCopy: undefined,
amzStorageClass: 'cold-location',
archive: {
archiveInfo,
restoreRequestedDays: days,
restoreRequestedAt: now,
restoreCompletedAt: new Date(now),
restoreWillExpireAt: new Date(now + days * scaledMsPerDay),
},
},
},
{
description: 'Should not take replication info from the bucket',
objMD: {
versionId: '2345678',
'creation-time': now,
'last-modified': now,
originOp: 's3:PutObject',
'x-amz-storage-class': 'cold-location',
archive: {
restoreRequestedDays: days,
restoreRequestedAt: now,
archiveInfo,
},
},
metadataStoreParams: {
replicationInfo: {
status: 'PENDING',
backends: [{ site: 'azure-blob', status: 'PENDING', dataStoreVersionId: '' }],
content: ['DATA', 'METADATA'],
destination: 'arn:aws:s3:::replicate-cold',
storageClass: 'azure-blob',
role: 'arn:aws:iam::root:role/s3-replication-role',
storageType: 'azure',
dataStoreVersionId: '',
},
},
expectedRes: {
headers: { host: 'localhost' },
creationTime: now,
lastModifiedDate: now,
updateMicroVersionId: true,
Expand Down Expand Up @@ -1273,9 +1315,12 @@ describe('versioning helpers', () => {
if (testCase.metadataStoreParams) {
Object.assign(metadataStoreParams, testCase.metadataStoreParams);
}
const requestHeaders = { ...testCase.metadataStoreParams?.headers };
const options = overwritingVersioning(testCase.objMD, metadataStoreParams);
assert.deepStrictEqual(options.versionId, testCase.objMD.versionId);
assert.deepStrictEqual(metadataStoreParams, { ...clearedSystemMD, ...testCase.expectedRes });
// request headers are shared with the request, they must not be modified
assert.deepStrictEqual({ ...testCase.metadataStoreParams?.headers }, requestHeaders);

if (testCase.objMD.isNull) {
assert.deepStrictEqual(options.extraMD.nullVersionId, 'vnull');
Expand Down
Loading