Compare commits
1 Commits
developmen
...
bugfix/CLD
Author | SHA1 | Date |
---|---|---|
naren-scality | 034436f13d |
|
@ -1,4 +1,4 @@
|
|||
const { evaluators, actionMaps } = require('arsenal').policies;
|
||||
const { evaluators, actionMaps, RequestContext } = require('arsenal').policies;
|
||||
const constants = require('../../../../constants');
|
||||
|
||||
const { allAuthedUsersId, bucketOwnerActions, logId, publicId } = constants;
|
||||
|
@ -182,6 +182,17 @@ function _checkBucketPolicyActions(requestType, actions, log) {
|
|||
return evaluators.isActionApplicable(mappedAction, actions, log);
|
||||
}
|
||||
|
||||
function _checkBucketPolicyResources(request, resource, log) {
|
||||
if (!request || (Array.isArray(resource) && resource.length === 0)) {
|
||||
return true;
|
||||
}
|
||||
// build request context from the request!
|
||||
const requestContext = new RequestContext(request.headers, request.query,
|
||||
request.bucketName, request.objectKey, null,
|
||||
request.connection.encrypted, request.resourceType, 's3');
|
||||
return evaluators.isResourceApplicable(requestContext, resource, log);
|
||||
}
|
||||
|
||||
function _getAccountId(arn) {
|
||||
// account or user arn is of format 'arn:aws:iam::<12-digit-acct-id>:etc...
|
||||
return arn.substr(13, 12);
|
||||
|
@ -226,7 +237,7 @@ function _checkPrincipals(canonicalID, arn, principal) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function checkBucketPolicy(policy, requestType, canonicalID, arn, bucketOwner, log) {
|
||||
function checkBucketPolicy(policy, requestType, canonicalID, arn, bucketOwner, log, request) {
|
||||
let permission = 'defaultDeny';
|
||||
// if requester is user within bucket owner account, actions should be
|
||||
// allowed unless explicitly denied (assumes allowed by IAM policy)
|
||||
|
@ -238,12 +249,13 @@ function checkBucketPolicy(policy, requestType, canonicalID, arn, bucketOwner, l
|
|||
const s = copiedStatement[0];
|
||||
const principalMatch = _checkPrincipals(canonicalID, arn, s.Principal);
|
||||
const actionMatch = _checkBucketPolicyActions(requestType, s.Action, log);
|
||||
const resourceMatch = _checkBucketPolicyResources(request, s.Resource, log);
|
||||
|
||||
if (principalMatch && actionMatch && s.Effect === 'Deny') {
|
||||
if (principalMatch && actionMatch && resourceMatch && s.Effect === 'Deny') {
|
||||
// explicit deny trumps any allows, so return immediately
|
||||
return 'explicitDeny';
|
||||
}
|
||||
if (principalMatch && actionMatch && s.Effect === 'Allow') {
|
||||
if (principalMatch && actionMatch && resourceMatch && s.Effect === 'Allow') {
|
||||
permission = 'allow';
|
||||
}
|
||||
copiedStatement = copiedStatement.splice(1);
|
||||
|
@ -251,7 +263,7 @@ function checkBucketPolicy(policy, requestType, canonicalID, arn, bucketOwner, l
|
|||
return permission;
|
||||
}
|
||||
|
||||
function isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log) {
|
||||
function isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request) {
|
||||
// Check to see if user is authorized to perform a
|
||||
// particular action on bucket based on ACLs.
|
||||
// TODO: Add IAM checks
|
||||
|
@ -271,14 +283,14 @@ function isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log) {
|
|||
return aclPermission;
|
||||
}
|
||||
const bucketPolicyPermission = checkBucketPolicy(bucketPolicy, requestType,
|
||||
canonicalID, arn, bucket.getOwner(), log);
|
||||
canonicalID, arn, bucket.getOwner(), log, request);
|
||||
if (bucketPolicyPermission === 'explicitDeny') {
|
||||
return false;
|
||||
}
|
||||
return (aclPermission || (bucketPolicyPermission === 'allow'));
|
||||
}
|
||||
|
||||
function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, log) {
|
||||
function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, log, request) {
|
||||
const bucketOwner = bucket.getOwner();
|
||||
if (!objectMD) {
|
||||
// User is already authorized on the bucket for FULL_CONTROL or WRITE or
|
||||
|
@ -288,7 +300,7 @@ function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, l
|
|||
}
|
||||
// check bucket has read access
|
||||
// 'bucketGet' covers listObjects and listMultipartUploads, bucket read actions
|
||||
return isBucketAuthorized(bucket, 'bucketGet', canonicalID, authInfo, log);
|
||||
return isBucketAuthorized(bucket, 'bucketGet', canonicalID, authInfo, log, request);
|
||||
}
|
||||
let requesterIsNotUser = true;
|
||||
let arn = null;
|
||||
|
@ -315,7 +327,7 @@ function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, l
|
|||
return aclPermission;
|
||||
}
|
||||
const bucketPolicyPermission = checkBucketPolicy(bucketPolicy, requestType,
|
||||
canonicalID, arn, bucket.getOwner(), log);
|
||||
canonicalID, arn, bucket.getOwner(), log, request);
|
||||
if (bucketPolicyPermission === 'explicitDeny') {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ function abortMultipartUpload(authInfo, bucketName, objectKey, uploadId, log,
|
|||
objectKey,
|
||||
uploadId,
|
||||
preciseRequestType: 'multipartDelete',
|
||||
request,
|
||||
};
|
||||
// For validating the request at the destinationBucket level
|
||||
// params are the same as validating at the MPU level
|
||||
|
|
|
@ -28,6 +28,7 @@ function bucketDelete(authInfo, request, log, cb) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketDelete',
|
||||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucket(metadataValParams, log,
|
||||
|
|
|
@ -33,8 +33,7 @@ function bucketDeleteCors(authInfo, request, log, callback) {
|
|||
}
|
||||
log.trace('found bucket in metadata');
|
||||
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo,
|
||||
log)) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', {
|
||||
requestType,
|
||||
method: 'bucketDeleteCors',
|
||||
|
|
|
@ -22,6 +22,7 @@ function bucketDeleteEncryption(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketDeleteEncryption',
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -18,6 +18,7 @@ function bucketDeleteLifecycle(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketDeleteLifecycle',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
|
|
|
@ -17,6 +17,7 @@ function bucketDeletePolicy(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketDeletePolicy',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
|
|
|
@ -18,6 +18,7 @@ function bucketDeleteReplication(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketDeleteReplication',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
|
|
|
@ -25,8 +25,7 @@ function bucketDeleteWebsite(authInfo, request, log, callback) {
|
|||
}
|
||||
log.trace('found bucket in metadata');
|
||||
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo,
|
||||
log)) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', {
|
||||
requestType,
|
||||
method: 'bucketDeleteWebsite',
|
||||
|
|
|
@ -315,6 +315,7 @@ function bucketGet(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGet',
|
||||
request,
|
||||
};
|
||||
const listParams = {
|
||||
listingType: 'DelimiterMaster',
|
||||
|
|
|
@ -45,6 +45,7 @@ function bucketGetACL(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetACL',
|
||||
request,
|
||||
};
|
||||
const grantInfo = {
|
||||
grants: [],
|
||||
|
|
|
@ -34,8 +34,7 @@ function bucketGetCors(authInfo, request, log, callback) {
|
|||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo,
|
||||
log)) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', {
|
||||
requestType,
|
||||
method: 'bucketGetCors',
|
||||
|
|
|
@ -23,6 +23,7 @@ function bucketGetEncryption(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetEncryption',
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -21,6 +21,7 @@ function bucketGetLifecycle(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetLifecycle',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
|
|
|
@ -36,8 +36,7 @@ function bucketGetLocation(authInfo, request, log, callback) {
|
|||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo,
|
||||
log)) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for account on bucket', {
|
||||
requestType,
|
||||
method: 'bucketGetLocation',
|
||||
|
|
|
@ -38,6 +38,7 @@ function bucketGetNotification(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetNotification',
|
||||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
|
|
|
@ -34,6 +34,7 @@ function bucketGetObjectLock(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetObjectLock',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
|
|
|
@ -18,6 +18,7 @@ function bucketGetPolicy(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetPolicy',
|
||||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
|
|
|
@ -21,6 +21,7 @@ function bucketGetReplication(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetReplication',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
|
|
|
@ -54,6 +54,7 @@ function bucketGetVersioning(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketGetVersioning',
|
||||
request,
|
||||
};
|
||||
|
||||
metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
|
|
|
@ -34,8 +34,7 @@ function bucketGetWebsite(authInfo, request, log, callback) {
|
|||
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo,
|
||||
log)) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', {
|
||||
requestType,
|
||||
method: 'bucketGetWebsite',
|
||||
|
|
|
@ -19,6 +19,7 @@ function bucketHead(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketHead',
|
||||
request,
|
||||
};
|
||||
metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
|
|
|
@ -72,6 +72,7 @@ function bucketPutACL(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutACL',
|
||||
request,
|
||||
};
|
||||
const possibleGrants = ['FULL_CONTROL', 'WRITE',
|
||||
'WRITE_ACP', 'READ', 'READ_ACP'];
|
||||
|
|
|
@ -66,8 +66,7 @@ function bucketPutCors(authInfo, request, log, callback) {
|
|||
});
|
||||
},
|
||||
function validateBucketAuthorization(bucket, rules, corsHeaders, next) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID,
|
||||
authInfo, log)) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for account on bucket', {
|
||||
requestType,
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ function bucketPutEncryption(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutEncryption',
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -26,6 +26,7 @@ function bucketPutLifecycle(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutLifecycle',
|
||||
request,
|
||||
};
|
||||
return waterfall([
|
||||
next => parseXML(request.post, log, next),
|
||||
|
|
|
@ -24,6 +24,7 @@ function bucketPutNotification(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutNotification',
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -27,6 +27,7 @@ function bucketPutObjectLock(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutObjectLock',
|
||||
request,
|
||||
};
|
||||
return waterfall([
|
||||
next => parseXML(request.post, log, next),
|
||||
|
|
|
@ -38,6 +38,7 @@ function bucketPutPolicy(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutPolicy',
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -28,6 +28,7 @@ function bucketPutReplication(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutReplication',
|
||||
request,
|
||||
};
|
||||
return waterfall([
|
||||
// Validate the request XML and return the replication configuration.
|
||||
|
|
|
@ -88,6 +88,7 @@ function bucketPutVersioning(authInfo, request, log, callback) {
|
|||
authInfo,
|
||||
bucketName,
|
||||
requestType: 'bucketPutVersioning',
|
||||
request,
|
||||
};
|
||||
|
||||
return waterfall([
|
||||
|
|
|
@ -46,8 +46,7 @@ function bucketPutWebsite(authInfo, request, log, callback) {
|
|||
});
|
||||
},
|
||||
function validateBucketAuthorization(bucket, config, next) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID,
|
||||
authInfo, log)) {
|
||||
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', {
|
||||
requestType,
|
||||
method: 'bucketPutWebsite',
|
||||
|
|
|
@ -84,6 +84,7 @@ function completeMultipartUpload(authInfo, request, log, callback) {
|
|||
// same as putting a part.
|
||||
requestType: 'putPart or complete',
|
||||
log,
|
||||
request,
|
||||
};
|
||||
const xmlParams = {
|
||||
bucketName,
|
||||
|
|
|
@ -88,6 +88,7 @@ function initiateMultipartUpload(authInfo, request, log, callback) {
|
|||
bucketName,
|
||||
// Required permissions for this action are same as objectPut
|
||||
requestType: 'objectPut',
|
||||
request,
|
||||
};
|
||||
const accountCanonicalID = authInfo.getCanonicalID();
|
||||
let initiatorID = accountCanonicalID;
|
||||
|
|
|
@ -97,6 +97,7 @@ function listMultipartUploads(authInfo, request, log, callback) {
|
|||
// as listing objects in a bucket.
|
||||
requestType: 'bucketGet',
|
||||
preciseRequestType: 'listMultipartUploads',
|
||||
request,
|
||||
};
|
||||
|
||||
async.waterfall([
|
||||
|
|
|
@ -96,6 +96,7 @@ function listParts(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
uploadId,
|
||||
preciseRequestType: 'listParts',
|
||||
request,
|
||||
};
|
||||
// For validating the request at the destinationBucket level
|
||||
// params are the same as validating at the MPU level
|
||||
|
|
|
@ -460,8 +460,7 @@ function multiObjectDelete(authInfo, request, log, callback) {
|
|||
return next(null, quietSetting, errorResults, inPlay,
|
||||
bucketMD);
|
||||
}
|
||||
if (!isBucketAuthorized(bucketMD, 'objectDelete',
|
||||
canonicalID, authInfo, log)) {
|
||||
if (!isBucketAuthorized(bucketMD, 'objectDelete', canonicalID, authInfo, log, request)) {
|
||||
log.trace("access denied due to bucket acl's");
|
||||
// if access denied at the bucket level, no access for
|
||||
// any of the objects so all results will be error results
|
||||
|
|
|
@ -213,12 +213,14 @@ function objectCopy(authInfo, request, sourceBucket,
|
|||
objectKey: sourceObject,
|
||||
versionId: sourceVersionId,
|
||||
requestType: 'objectGet',
|
||||
request,
|
||||
};
|
||||
const valPutParams = {
|
||||
authInfo,
|
||||
bucketName: destBucketName,
|
||||
objectKey: destObjectKey,
|
||||
requestType: 'objectPut',
|
||||
request,
|
||||
};
|
||||
const dataStoreContext = {
|
||||
bucketName: destBucketName,
|
||||
|
|
|
@ -48,6 +48,7 @@ function objectDelete(authInfo, request, log, cb) {
|
|||
objectKey,
|
||||
versionId: reqVersionId,
|
||||
requestType: 'objectDelete',
|
||||
request,
|
||||
};
|
||||
|
||||
const canonicalID = authInfo.getCanonicalID();
|
||||
|
|
|
@ -43,6 +43,7 @@ function objectDeleteTagging(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
requestType: 'objectDeleteTagging',
|
||||
versionId: reqVersionId,
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -44,6 +44,7 @@ function objectGet(authInfo, request, returnTagCount, log, callback) {
|
|||
objectKey,
|
||||
versionId,
|
||||
requestType: 'objectGet',
|
||||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucketAndObj(mdValParams, log,
|
||||
|
|
|
@ -60,6 +60,7 @@ function objectGetACL(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
versionId,
|
||||
requestType: 'objectGetACL',
|
||||
request,
|
||||
};
|
||||
const grantInfo = {
|
||||
grants: [],
|
||||
|
|
|
@ -39,6 +39,7 @@ function objectGetLegalHold(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
requestType: 'objectGetLegalHold',
|
||||
versionId,
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -39,6 +39,7 @@ function objectGetRetention(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
requestType: 'objectGetRetention',
|
||||
versionId: reqVersionId,
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -39,6 +39,7 @@ function objectGetTagging(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
requestType: 'objectGetTagging',
|
||||
versionId: reqVersionId,
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -44,6 +44,7 @@ function objectHead(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
versionId,
|
||||
requestType: 'objectHead',
|
||||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucketAndObj(mdValParams, log,
|
||||
|
|
|
@ -56,7 +56,7 @@ function objectPut(authInfo, request, streamingV4Params, log, callback) {
|
|||
const invalidSSEError = errors.InvalidArgument.customizeDescription(
|
||||
'The encryption method specified is not supported');
|
||||
const requestType = 'objectPut';
|
||||
const valParams = { authInfo, bucketName, objectKey, requestType };
|
||||
const valParams = { authInfo, bucketName, objectKey, requestType, request };
|
||||
const canonicalID = authInfo.getCanonicalID();
|
||||
log.trace('owner canonicalID to send to data', { canonicalID });
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ function objectPutCopyPart(authInfo, request, sourceBucket,
|
|||
objectKey: sourceObject,
|
||||
versionId: reqVersionId,
|
||||
requestType: 'objectGet',
|
||||
request,
|
||||
};
|
||||
|
||||
const partNumber = Number.parseInt(request.query.partNumber, 10);
|
||||
|
@ -62,6 +63,7 @@ function objectPutCopyPart(authInfo, request, sourceBucket,
|
|||
bucketName: destBucketName,
|
||||
objectKey: destObjectKey,
|
||||
requestType: 'objectPut',
|
||||
request,
|
||||
};
|
||||
|
||||
// For validating the request at the MPU, the params are the same
|
||||
|
|
|
@ -42,6 +42,7 @@ function objectPutLegalHold(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
requestType: 'objectPutLegalHold',
|
||||
versionId,
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -110,8 +110,7 @@ function objectPutPart(authInfo, request, streamingV4Params, log,
|
|||
// For validating the request at the destinationBucket level the
|
||||
// `requestType` is the general 'objectPut'.
|
||||
const requestType = 'objectPut';
|
||||
if (!isBucketAuthorized(destinationBucket, requestType,
|
||||
canonicalID, authInfo, log)) {
|
||||
if (!isBucketAuthorized(destinationBucket, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', { requestType });
|
||||
return next(errors.AccessDenied, destinationBucket);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ function objectPutRetention(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
requestType: 'objectPutRetention',
|
||||
versionId: reqVersionId,
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -44,6 +44,7 @@ function objectPutTagging(authInfo, request, log, callback) {
|
|||
objectKey,
|
||||
requestType: 'objectPutTagging',
|
||||
versionId: reqVersionId,
|
||||
request,
|
||||
};
|
||||
|
||||
return async.waterfall([
|
||||
|
|
|
@ -144,7 +144,7 @@ function websiteGet(request, log, callback) {
|
|||
{ error: err });
|
||||
let returnErr = err;
|
||||
const bucketAuthorized = isBucketAuthorized(bucket,
|
||||
'bucketGet', constants.publicId, null, log);
|
||||
'bucketGet', constants.publicId, null, log, request);
|
||||
// if index object does not exist and bucket is private AWS
|
||||
// returns 403 - AccessDenied error.
|
||||
if (err === errors.NoSuchKey && !bucketAuthorized) {
|
||||
|
@ -156,7 +156,7 @@ function websiteGet(request, log, callback) {
|
|||
callback);
|
||||
}
|
||||
if (!isObjAuthorized(bucket, objMD, 'objectGet',
|
||||
constants.publicId, null, log)) {
|
||||
constants.publicId, null, log, request)) {
|
||||
const err = errors.AccessDenied;
|
||||
log.trace('request not authorized', { error: err });
|
||||
return _errorActions(err, websiteConfig.getErrorDocument(),
|
||||
|
|
|
@ -104,7 +104,7 @@ function websiteHead(request, log, callback) {
|
|||
{ error: err });
|
||||
let returnErr = err;
|
||||
const bucketAuthorized = isBucketAuthorized(bucket,
|
||||
'bucketGet', constants.publicId, null, log);
|
||||
'bucketGet', constants.publicId, null, log, request);
|
||||
// if index object does not exist and bucket is private AWS
|
||||
// returns 403 - AccessDenied error.
|
||||
if (err === errors.NoSuchKey && !bucketAuthorized) {
|
||||
|
@ -114,7 +114,7 @@ function websiteHead(request, log, callback) {
|
|||
reqObjectKey, corsHeaders, log, callback);
|
||||
}
|
||||
if (!isObjAuthorized(bucket, objMD, 'objectGet',
|
||||
constants.publicId, null, log)) {
|
||||
constants.publicId, null, log, request)) {
|
||||
const err = errors.AccessDenied;
|
||||
log.trace('request not authorized', { error: err });
|
||||
return _errorActions(err, routingRules, reqObjectKey,
|
||||
|
|
|
@ -169,12 +169,13 @@ function metadataGetObject(bucketName, objectKey, versionId, log, cb) {
|
|||
* @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, requestType, preciseRequestType } = params;
|
||||
const { authInfo, bucketName, objectKey, versionId, requestType, preciseRequestType, request } = params;
|
||||
const canonicalID = authInfo.getCanonicalID();
|
||||
async.waterfall([
|
||||
function getBucketAndObjectMD(next) {
|
||||
|
@ -189,7 +190,7 @@ function metadataValidateBucketAndObj(params, log, callback) {
|
|||
return next(errors.MethodNotAllowed, bucket);
|
||||
}
|
||||
if (!isBucketAuthorized(bucket, (preciseRequestType || requestType), canonicalID,
|
||||
authInfo, log)) {
|
||||
authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', { requestType });
|
||||
return next(errors.AccessDenied, bucket);
|
||||
}
|
||||
|
@ -203,8 +204,7 @@ function metadataValidateBucketAndObj(params, log, callback) {
|
|||
return next(null, bucket, objMD);
|
||||
},
|
||||
function checkObjectAuth(bucket, objMD, next) {
|
||||
if (!isObjAuthorized(bucket, objMD, requestType, canonicalID,
|
||||
authInfo, log)) {
|
||||
if (!isObjAuthorized(bucket, objMD, requestType, canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on object', { requestType });
|
||||
return next(errors.AccessDenied, bucket);
|
||||
}
|
||||
|
@ -251,12 +251,13 @@ function metadataGetBucket(requestType, bucketName, log, cb) {
|
|||
* @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 { authInfo, bucketName, requestType, preciseRequestType } = params;
|
||||
const { authInfo, bucketName, requestType, preciseRequestType, request } = params;
|
||||
const canonicalID = authInfo.getCanonicalID();
|
||||
return metadataGetBucket(requestType, bucketName, log, (err, bucket) => {
|
||||
if (err) {
|
||||
|
@ -269,7 +270,7 @@ function metadataValidateBucket(params, log, callback) {
|
|||
return callback(errors.MethodNotAllowed, bucket);
|
||||
}
|
||||
// still return bucket for cors headers
|
||||
if (!isBucketAuthorized(bucket, (preciseRequestType || requestType), canonicalID, authInfo, log)) {
|
||||
if (!isBucketAuthorized(bucket, (preciseRequestType || requestType), canonicalID, authInfo, log, request)) {
|
||||
log.debug('access denied for user on bucket', { requestType });
|
||||
return callback(errors.AccessDenied, bucket);
|
||||
}
|
||||
|
|
|
@ -808,11 +808,14 @@ function routeBackbeat(clientIP, request, response, log) {
|
|||
// Bucket and object do not exist in metadata.
|
||||
return next(null, null, null);
|
||||
}
|
||||
const mdValParams = { bucketName: request.bucketName,
|
||||
const mdValParams = {
|
||||
bucketName: request.bucketName,
|
||||
objectKey: request.objectKey,
|
||||
authInfo: userInfo,
|
||||
versionId,
|
||||
requestType: 'ReplicateObject' };
|
||||
requestType: 'ReplicateObject',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucketAndObj(mdValParams, log, next);
|
||||
},
|
||||
(bucketInfo, objMd, next) => {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"homepage": "https://github.com/scality/S3#readme",
|
||||
"dependencies": {
|
||||
"@hapi/joi": "^17.1.0",
|
||||
"arsenal": "github:scality/Arsenal#9aa8710",
|
||||
"arsenal": "github:scality/Arsenal#db7d8b0",
|
||||
"async": "~2.5.0",
|
||||
"aws-sdk": "2.905.0",
|
||||
"azure-storage": "^2.1.0",
|
||||
|
@ -77,7 +77,7 @@
|
|||
"install_ft_deps": "yarn install aws-sdk@2.28.0 bluebird@3.3.1 mocha@2.3.4 mocha-junit-reporter@1.23.1 tv4@1.2.7",
|
||||
"lint": "eslint $(git ls-files '*.js')",
|
||||
"lint_md": "mdlint $(git ls-files '*.md')",
|
||||
"mem_backend": "S3BACKEND=mem node index.js",
|
||||
"mem_backend": "S3BACKEND=mem node --inspect index.js",
|
||||
"start": "npm-run-all --parallel start_dmd start_s3server",
|
||||
"start_mdserver": "node mdserver.js",
|
||||
"start_dataserver": "node dataserver.js",
|
||||
|
|
|
@ -650,9 +650,9 @@ arraybuffer.slice@~0.0.7:
|
|||
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
|
||||
integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
|
||||
|
||||
"arsenal@github:scality/Arsenal#9aa8710":
|
||||
"arsenal@github:scality/Arsenal#db7d8b0":
|
||||
version "7.7.2"
|
||||
resolved "https://codeload.github.com/scality/Arsenal/tar.gz/9aa8710a57b037685ad2851543808df3a41476b2"
|
||||
resolved "https://codeload.github.com/scality/Arsenal/tar.gz/db7d8b0b4536653361d8e22092c09b87563d6901"
|
||||
dependencies:
|
||||
"@hapi/joi" "^15.1.0"
|
||||
JSONStream "^1.0.0"
|
||||
|
|
Loading…
Reference in New Issue