Compare commits
4 Commits
developmen
...
task/poc-b
Author | SHA1 | Date |
---|---|---|
williamlardier | f6ab312c46 | |
williamlardier | 89805212c9 | |
williamlardier | 503dc74f4b | |
williamlardier | 65b409fff2 |
|
@ -139,9 +139,10 @@ const api = {
|
|||
|
||||
function checkAuthResults(authResults) {
|
||||
let returnTagCount = true;
|
||||
let isImplicitDeny = true;
|
||||
if (apiMethod === 'objectGet') {
|
||||
// first item checks s3:GetObject(Version) action
|
||||
if (!authResults[0].isAllowed) {
|
||||
if (!authResults[0].isAllowed && !authResults[0].isImplicit) {
|
||||
log.trace('get object authorization denial from Vault');
|
||||
return errors.AccessDenied;
|
||||
}
|
||||
|
@ -153,13 +154,18 @@ const api = {
|
|||
}
|
||||
} else {
|
||||
for (let i = 0; i < authResults.length; i++) {
|
||||
if (!authResults[i].isAllowed) {
|
||||
if (!authResults[i].isAllowed && !authResults[i].isImplicit) {
|
||||
// Any explicit deny rejects the current APÏ call
|
||||
log.trace('authorization denial from Vault');
|
||||
return errors.AccessDenied;
|
||||
} else if (authResults[i].isAllowed) {
|
||||
// If the action is allowed, the result is not implicit
|
||||
// Deny.
|
||||
isImplicitDeny = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnTagCount;
|
||||
return { returnTagCount, isImplicitDeny };
|
||||
}
|
||||
|
||||
return async.waterfall([
|
||||
|
@ -237,7 +243,8 @@ const api = {
|
|||
if (checkedResults instanceof Error) {
|
||||
return callback(checkedResults);
|
||||
}
|
||||
returnTagCount = checkedResults;
|
||||
returnTagCount = checkedResults.returnTagCount;
|
||||
request.isImplicitIdentityDeny = checkedResults.isImplicitDeny;
|
||||
}
|
||||
if (apiMethod === 'objectPut' || apiMethod === 'objectPutPart') {
|
||||
request._response = response;
|
||||
|
|
|
@ -8,7 +8,7 @@ const { allAuthedUsersId, bucketOwnerActions, logId, publicId,
|
|||
const publicReadBuckets = process.env.ALLOW_PUBLIC_READ_BUCKETS ?
|
||||
process.env.ALLOW_PUBLIC_READ_BUCKETS.split(',') : [];
|
||||
|
||||
function checkBucketAcls(bucket, requestType, canonicalID) {
|
||||
function checkBucketAcls(bucket, requestType, canonicalID, requesterIsNotUser) {
|
||||
if (bucket.getOwner() === canonicalID) {
|
||||
return true;
|
||||
}
|
||||
|
@ -268,7 +268,18 @@ function checkBucketPolicy(policy, requestType, canonicalID, arn, bucketOwner, l
|
|||
return permission;
|
||||
}
|
||||
|
||||
function isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request) {
|
||||
function isIdentityAndResourceAuthorized(isImplicitIdentityDeny, resourceAuthzResult) {
|
||||
// If resourceAuthzResult is true, the the IAM result is either Allow or
|
||||
// implicit Deny (nothing applicable): in this case, we allow the request.
|
||||
if (resourceAuthzResult === true) {
|
||||
return true;
|
||||
}
|
||||
// If resourceAuthzResult is false, we only return true if IAM result is
|
||||
// Allow. Otherwise we default to an implicit Deny.
|
||||
return isImplicitIdentityDeny === false;
|
||||
}
|
||||
|
||||
function isBucketAuthorized(bucket, requestType, canonicalID, authInfo, isImplicitIdentityDeny, log, request) {
|
||||
// Check to see if user is authorized to perform a
|
||||
// particular action on bucket based on ACLs.
|
||||
// TODO: Add IAM checks
|
||||
|
@ -280,32 +291,34 @@ function isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, req
|
|||
}
|
||||
// if the bucket owner is an account, users should not have default access
|
||||
if ((bucket.getOwner() === canonicalID) && requesterIsNotUser) {
|
||||
return true;
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny, true);
|
||||
}
|
||||
const aclPermission = checkBucketAcls(bucket, requestType, canonicalID);
|
||||
const aclPermission = checkBucketAcls(bucket, requestType, canonicalID, requesterIsNotUser);
|
||||
const bucketPolicy = bucket.getBucketPolicy();
|
||||
if (!bucketPolicy) {
|
||||
return aclPermission;
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny, aclPermission);
|
||||
}
|
||||
const bucketPolicyPermission = checkBucketPolicy(bucketPolicy, requestType,
|
||||
canonicalID, arn, bucket.getOwner(), log, request);
|
||||
if (bucketPolicyPermission === 'explicitDeny') {
|
||||
return false;
|
||||
}
|
||||
return (aclPermission || (bucketPolicyPermission === 'allow'));
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny,
|
||||
(aclPermission || (bucketPolicyPermission === 'allow')));
|
||||
}
|
||||
|
||||
function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, log, request) {
|
||||
function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, isImplicitIdentityDeny, log, request) {
|
||||
const bucketOwner = bucket.getOwner();
|
||||
if (!objectMD) {
|
||||
// User is already authorized on the bucket for FULL_CONTROL or WRITE or
|
||||
// bucket has canned ACL public-read-write
|
||||
if (requestType === 'objectPut' || requestType === 'objectDelete') {
|
||||
return true;
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny, true);
|
||||
}
|
||||
// check bucket has read access
|
||||
// 'bucketGet' covers listObjects and listMultipartUploads, bucket read actions
|
||||
return isBucketAuthorized(bucket, 'bucketGet', canonicalID, authInfo, log, request);
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny,
|
||||
isBucketAuthorized(bucket, 'bucketGet', canonicalID, authInfo, log, isImplicitIdentityDeny, request));
|
||||
}
|
||||
let requesterIsNotUser = true;
|
||||
let arn = null;
|
||||
|
@ -314,7 +327,7 @@ function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, l
|
|||
arn = authInfo.getArn();
|
||||
}
|
||||
if (objectMD['owner-id'] === canonicalID && requesterIsNotUser) {
|
||||
return true;
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny, true);
|
||||
}
|
||||
// account is authorized if:
|
||||
// - requesttype is included in bucketOwnerActions and
|
||||
|
@ -323,20 +336,21 @@ function isObjAuthorized(bucket, objectMD, requestType, canonicalID, authInfo, l
|
|||
if (bucketOwnerActions.includes(requestType)
|
||||
&& (bucketOwner === canonicalID)
|
||||
&& requesterIsNotUser) {
|
||||
return true;
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny, true);
|
||||
}
|
||||
const aclPermission = checkObjectAcls(bucket, objectMD, requestType,
|
||||
canonicalID);
|
||||
const bucketPolicy = bucket.getBucketPolicy();
|
||||
if (!bucketPolicy) {
|
||||
return aclPermission;
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny, aclPermission);
|
||||
}
|
||||
const bucketPolicyPermission = checkBucketPolicy(bucketPolicy, requestType,
|
||||
canonicalID, arn, bucket.getOwner(), log, request);
|
||||
if (bucketPolicyPermission === 'explicitDeny') {
|
||||
return false;
|
||||
}
|
||||
return (aclPermission || (bucketPolicyPermission === 'allow'));
|
||||
return isIdentityAndResourceAuthorized(isImplicitIdentityDeny,
|
||||
(aclPermission || (bucketPolicyPermission === 'allow')));
|
||||
}
|
||||
|
||||
function _checkResource(resource, bucketArn) {
|
||||
|
|
|
@ -22,10 +22,11 @@ function abortMultipartUpload(authInfo, bucketName, objectKey, uploadId, log,
|
|||
// but the requestType is the more general 'objectDelete'
|
||||
const metadataValParams = Object.assign({}, metadataValMPUparams);
|
||||
metadataValParams.requestType = 'objectPut';
|
||||
const authzIdentityResult = request ? request.isImplicitIdentityDeny : true;
|
||||
|
||||
async.waterfall([
|
||||
function checkDestBucketVal(next) {
|
||||
metadataValidateBucketAndObj(metadataValParams, log,
|
||||
metadataValidateBucketAndObj(metadataValParams, authzIdentityResult, log,
|
||||
(err, destinationBucket) => {
|
||||
if (err) {
|
||||
return next(err, destinationBucket);
|
||||
|
|
|
@ -34,7 +34,7 @@ function bucketDelete(authInfo, request, log, cb) {
|
|||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucket(metadataValParams, log,
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucketMD) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucketMD);
|
||||
|
|
|
@ -26,7 +26,7 @@ function bucketDeleteEncryption(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucket(metadataValParams, log, next),
|
||||
next => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, next),
|
||||
(bucket, next) => checkExpectedBucketOwner(request.headers, bucket, log, err => next(err, bucket)),
|
||||
(bucket, next) => {
|
||||
const sseConfig = bucket.getServerSideEncryption();
|
||||
|
|
|
@ -21,7 +21,7 @@ function bucketDeleteLifecycle(authInfo, request, log, callback) {
|
|||
requestType: 'bucketDeleteLifecycle',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -19,7 +19,7 @@ function bucketDeletePolicy(authInfo, request, log, callback) {
|
|||
requestType: 'bucketDeletePolicy',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -21,7 +21,7 @@ function bucketDeleteReplication(authInfo, request, log, callback) {
|
|||
requestType: 'bucketDeleteReplication',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -351,7 +351,7 @@ function bucketGet(authInfo, request, log, callback) {
|
|||
listParams.marker = params.marker;
|
||||
}
|
||||
|
||||
metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
if (err) {
|
||||
|
|
|
@ -55,7 +55,7 @@ function bucketGetACL(authInfo, request, log, callback) {
|
|||
},
|
||||
};
|
||||
|
||||
metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
if (err) {
|
||||
|
|
|
@ -27,7 +27,7 @@ function bucketGetEncryption(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucket(metadataValParams, log, next),
|
||||
next => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, next),
|
||||
(bucket, next) => checkExpectedBucketOwner(request.headers, bucket, log, err => next(err, bucket)),
|
||||
(bucket, next) => {
|
||||
// If sseInfo is present but the `mandatory` flag is not set
|
||||
|
|
|
@ -24,7 +24,7 @@ function bucketGetLifecycle(authInfo, request, log, callback) {
|
|||
requestType: 'bucketGetLifecycle',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -41,7 +41,7 @@ function bucketGetNotification(authInfo, request, log, callback) {
|
|||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -36,7 +36,7 @@ function bucketGetObjectLock(authInfo, request, log, callback) {
|
|||
requestType: 'bucketGetObjectLock',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -21,7 +21,7 @@ function bucketGetPolicy(authInfo, request, log, callback) {
|
|||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -24,7 +24,7 @@ function bucketGetReplication(authInfo, request, log, callback) {
|
|||
requestType: 'bucketGetReplication',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
return metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
|
||||
if (err) {
|
||||
log.debug('error processing request', {
|
||||
|
|
|
@ -58,7 +58,7 @@ function bucketGetVersioning(authInfo, request, log, callback) {
|
|||
request,
|
||||
};
|
||||
|
||||
metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
metadataValidateBucket(metadataValParams, log, request.isImplicitIdentityDeny, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
if (err) {
|
||||
|
|
|
@ -22,7 +22,7 @@ function bucketHead(authInfo, request, log, callback) {
|
|||
requestType: 'bucketHead',
|
||||
request,
|
||||
};
|
||||
metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
if (err) {
|
||||
|
|
|
@ -105,7 +105,7 @@ function bucketPutACL(authInfo, request, log, callback) {
|
|||
|
||||
return async.waterfall([
|
||||
function waterfall1(next) {
|
||||
metadataValidateBucket(metadataValParams, log,
|
||||
metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed', {
|
||||
|
|
|
@ -28,7 +28,7 @@ function bucketPutEncryption(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucket(metadataValParams, log, next),
|
||||
next => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, next),
|
||||
(bucket, next) => checkExpectedBucketOwner(request.headers, bucket, log, err => next(err, bucket)),
|
||||
(bucket, next) => {
|
||||
log.trace('parsing encryption config', { method: 'bucketPutEncryption' });
|
||||
|
|
|
@ -43,7 +43,7 @@ function bucketPutLifecycle(authInfo, request, log, callback) {
|
|||
return next(null, configObj);
|
||||
});
|
||||
},
|
||||
(lcConfig, next) => metadataValidateBucket(metadataValParams, log,
|
||||
(lcConfig, next) => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket) => {
|
||||
if (err) {
|
||||
return next(err, bucket);
|
||||
|
|
|
@ -34,7 +34,7 @@ function bucketPutNotification(authInfo, request, log, callback) {
|
|||
const notifConfig = notificationConfig.error ? undefined : notificationConfig;
|
||||
process.nextTick(() => next(notificationConfig.error, notifConfig));
|
||||
},
|
||||
(notifConfig, next) => metadataValidateBucket(metadataValParams, log,
|
||||
(notifConfig, next) => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket) => next(err, bucket, notifConfig)),
|
||||
(bucket, notifConfig, next) => {
|
||||
bucket.setNotificationConfiguration(notifConfig);
|
||||
|
|
|
@ -41,7 +41,7 @@ function bucketPutObjectLock(authInfo, request, log, callback) {
|
|||
return next(configObj.error || null, configObj);
|
||||
});
|
||||
},
|
||||
(objectLockConfig, next) => metadataValidateBucket(metadataValParams,
|
||||
(objectLockConfig, next) => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny,
|
||||
log, (err, bucket) => {
|
||||
if (err) {
|
||||
return next(err, bucket);
|
||||
|
|
|
@ -70,7 +70,7 @@ function bucketPutPolicy(authInfo, request, log, callback) {
|
|||
return next(null, bucketPolicy);
|
||||
});
|
||||
},
|
||||
(bucketPolicy, next) => metadataValidateBucket(metadataValParams, log,
|
||||
(bucketPolicy, next) => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket) => {
|
||||
if (err) {
|
||||
return next(err, bucket);
|
||||
|
|
|
@ -37,7 +37,7 @@ function bucketPutReplication(authInfo, request, log, callback) {
|
|||
// Check bucket user privileges and ensure versioning is 'Enabled'.
|
||||
(config, next) =>
|
||||
// TODO: Validate that destination bucket exists and has versioning.
|
||||
metadataValidateBucket(metadataValParams, log, (err, bucket) => {
|
||||
metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log, (err, bucket) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ function bucketPutTagging(authInfo, request, log, callback) {
|
|||
};
|
||||
let bucket = null;
|
||||
return waterfall([
|
||||
next => metadataValidateBucket(metadataValParams, log,
|
||||
next => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, b) => {
|
||||
bucket = b;
|
||||
return next(err);
|
||||
|
|
|
@ -94,7 +94,7 @@ function bucketPutVersioning(authInfo, request, log, callback) {
|
|||
|
||||
return waterfall([
|
||||
next => _parseXML(request, log, next),
|
||||
next => metadataValidateBucket(metadataValParams, log,
|
||||
next => metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket) => next(err, bucket)), // ignore extra null object,
|
||||
(bucket, next) => parseString(request.post, (err, result) => {
|
||||
// just for linting; there should not be any parsing error here
|
||||
|
|
|
@ -120,7 +120,7 @@ function completeMultipartUpload(authInfo, request, log, callback) {
|
|||
// at the destinationBucket level are same as objectPut
|
||||
requestType: 'objectPut',
|
||||
};
|
||||
metadataValidateBucketAndObj(metadataValParams, log, next);
|
||||
metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log, next);
|
||||
},
|
||||
function validateMultipart(destBucket, objMD, next) {
|
||||
if (objMD) {
|
||||
|
|
|
@ -262,7 +262,7 @@ function initiateMultipartUpload(authInfo, request, log, callback) {
|
|||
}
|
||||
|
||||
async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(error, destinationBucket) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, destinationBucket);
|
||||
|
|
|
@ -105,7 +105,7 @@ function listMultipartUploads(authInfo, request, log, callback) {
|
|||
function waterfall1(next) {
|
||||
// Check final destination bucket for authorization rather
|
||||
// than multipart upload bucket
|
||||
metadataValidateBucket(metadataValParams, log,
|
||||
metadataValidateBucket(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket) => next(err, bucket));
|
||||
},
|
||||
function getMPUBucket(bucket, next) {
|
||||
|
|
|
@ -115,7 +115,7 @@ function listParts(authInfo, request, log, callback) {
|
|||
|
||||
async.waterfall([
|
||||
function checkDestBucketVal(next) {
|
||||
metadataValidateBucketAndObj(metadataValParams, log,
|
||||
metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, destinationBucket) => {
|
||||
if (err) {
|
||||
return next(err, destinationBucket, null);
|
||||
|
|
|
@ -249,7 +249,7 @@ function objectCopy(authInfo, request, sourceBucket,
|
|||
}
|
||||
return async.waterfall([
|
||||
function checkDestAuth(next) {
|
||||
return metadataValidateBucketAndObj(valPutParams, log,
|
||||
return metadataValidateBucketAndObj(valPutParams, request.isImplicitIdentityDeny, log,
|
||||
(err, destBucketMD, destObjMD) => {
|
||||
if (err) {
|
||||
log.debug('error validating put part of request',
|
||||
|
@ -267,7 +267,7 @@ function objectCopy(authInfo, request, sourceBucket,
|
|||
});
|
||||
},
|
||||
function checkSourceAuthorization(destBucketMD, destObjMD, next) {
|
||||
return metadataValidateBucketAndObj(valGetParams, log,
|
||||
return metadataValidateBucketAndObj(valGetParams, request.isImplicitIdentityDeny, log,
|
||||
(err, sourceBucketMD, sourceObjMD) => {
|
||||
if (err) {
|
||||
log.debug('error validating get part of request',
|
||||
|
|
|
@ -59,7 +59,7 @@ function objectDelete(authInfo, request, log, cb) {
|
|||
const canonicalID = authInfo.getCanonicalID();
|
||||
return async.waterfall([
|
||||
function validateBucketAndObj(next) {
|
||||
return metadataValidateBucketAndObj(valParams, log,
|
||||
return metadataValidateBucketAndObj(valParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucketMD, objMD) => {
|
||||
if (err) {
|
||||
return next(err, bucketMD);
|
||||
|
|
|
@ -49,7 +49,7 @@ function objectDeleteTagging(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -50,7 +50,7 @@ function objectGet(authInfo, request, returnTagCount, log, callback) {
|
|||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucketAndObj(mdValParams, log,
|
||||
return metadataValidateBucketAndObj(mdValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objMD) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
|
|
|
@ -74,7 +74,7 @@ function objectGetACL(authInfo, request, log, callback) {
|
|||
|
||||
return async.waterfall([
|
||||
function validateBucketAndObj(next) {
|
||||
return metadataValidateBucketAndObj(metadataValParams, log,
|
||||
return metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -45,7 +45,7 @@ function objectGetLegalHold(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -45,7 +45,7 @@ function objectGetRetention(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -46,7 +46,7 @@ function objectGetTagging(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -50,7 +50,7 @@ function objectHead(authInfo, request, log, callback) {
|
|||
request,
|
||||
};
|
||||
|
||||
return metadataValidateBucketAndObj(mdValParams, log,
|
||||
return metadataValidateBucketAndObj(mdValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objMD) => {
|
||||
const corsHeaders = collectCorsHeaders(request.headers.origin,
|
||||
request.method, bucket);
|
||||
|
|
|
@ -71,7 +71,7 @@ function objectPut(authInfo, request, streamingV4Params, log, callback) {
|
|||
|
||||
log.trace('owner canonicalID to send to data', { canonicalID });
|
||||
|
||||
return metadataValidateBucketAndObj(valParams, log,
|
||||
return metadataValidateBucketAndObj(valParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objMD) => {
|
||||
const responseHeaders = collectCorsHeaders(headers.origin,
|
||||
method, bucket);
|
||||
|
|
|
@ -112,7 +112,7 @@ function objectPutACL(authInfo, request, log, cb) {
|
|||
|
||||
return async.waterfall([
|
||||
function validateBucketAndObj(next) {
|
||||
return metadataValidateBucketAndObj(metadataValParams, log,
|
||||
return metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
|
|
|
@ -93,7 +93,7 @@ function objectPutCopyPart(authInfo, request, sourceBucket,
|
|||
|
||||
return async.waterfall([
|
||||
function checkDestAuth(next) {
|
||||
return metadataValidateBucketAndObj(valPutParams, log,
|
||||
return metadataValidateBucketAndObj(valPutParams, request.isImplicitIdentityDeny, log,
|
||||
(err, destBucketMD) => {
|
||||
if (err) {
|
||||
log.debug('error validating authorization for ' +
|
||||
|
@ -112,7 +112,7 @@ function objectPutCopyPart(authInfo, request, sourceBucket,
|
|||
});
|
||||
},
|
||||
function checkSourceAuthorization(destBucketMD, next) {
|
||||
return metadataValidateBucketAndObj(valGetParams, log,
|
||||
return metadataValidateBucketAndObj(valGetParams, request.isImplicitIdentityDeny, log,
|
||||
(err, sourceBucketMD, sourceObjMD) => {
|
||||
if (err) {
|
||||
log.debug('error validating get part of request',
|
||||
|
|
|
@ -48,7 +48,7 @@ function objectPutLegalHold(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -49,7 +49,7 @@ function objectPutRetention(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -50,7 +50,7 @@ function objectPutTagging(authInfo, request, log, callback) {
|
|||
};
|
||||
|
||||
return async.waterfall([
|
||||
next => metadataValidateBucketAndObj(metadataValParams, log,
|
||||
next => metadataValidateBucketAndObj(metadataValParams, request.isImplicitIdentityDeny, log,
|
||||
(err, bucket, objectMD) => {
|
||||
if (err) {
|
||||
log.trace('request authorization failed',
|
||||
|
|
|
@ -94,6 +94,7 @@ function metadataGetObject(bucketName, objectKey, versionId, log, cb) {
|
|||
* @param {string} params.requestType - type of request
|
||||
* @param {string} [params.preciseRequestType] - precise type of request
|
||||
* @param {object} params.request - http request object
|
||||
* @param {object} isImplicitIdentityDeny - identity authorization results
|
||||
* @param {RequestLogger} log - request logger
|
||||
* @return {ArsenalError|null} returns a validation error, or null if validation OK
|
||||
* The following errors may be returned:
|
||||
|
@ -102,7 +103,7 @@ function metadataGetObject(bucketName, objectKey, versionId, log, cb) {
|
|||
* bucket policy operation
|
||||
* - AccessDenied: bucket is not authorized
|
||||
*/
|
||||
function validateBucket(bucket, params, log) {
|
||||
function validateBucket(bucket, params, isImplicitIdentityDeny, log) {
|
||||
const { authInfo, requestType, preciseRequestType, request } = params;
|
||||
if (bucketShield(bucket, requestType)) {
|
||||
log.debug('bucket is shielded from request', {
|
||||
|
@ -119,7 +120,7 @@ function validateBucket(bucket, params, log) {
|
|||
return errors.MethodNotAllowed;
|
||||
}
|
||||
if (!isBucketAuthorized(bucket, (preciseRequestType || requestType), canonicalID,
|
||||
authInfo, log, request)) {
|
||||
authInfo, isImplicitIdentityDeny, log, request)) {
|
||||
log.debug('access denied for user on bucket', { requestType });
|
||||
return errors.AccessDenied;
|
||||
}
|
||||
|
@ -135,11 +136,12 @@ function validateBucket(bucket, params, log) {
|
|||
* @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 {boolean} isImplicitIdentityDeny - identity authorization results
|
||||
* @param {RequestLogger} log - request logger
|
||||
* @param {function} callback - callback
|
||||
* @return {undefined} - and call callback with params err, bucket md
|
||||
*/
|
||||
function metadataValidateBucketAndObj(params, log, callback) {
|
||||
function metadataValidateBucketAndObj(params, isImplicitIdentityDeny, log, callback) {
|
||||
const { authInfo, bucketName, objectKey, versionId, getDeleteMarker,
|
||||
requestType, request } = params;
|
||||
async.waterfall([
|
||||
|
@ -161,7 +163,7 @@ function metadataValidateBucketAndObj(params, log, callback) {
|
|||
});
|
||||
return next(errors.NoSuchBucket);
|
||||
}
|
||||
const validationError = validateBucket(bucket, params, log);
|
||||
const validationError = validateBucket(bucket, params, isImplicitIdentityDeny, log);
|
||||
if (validationError) {
|
||||
return next(validationError, bucket);
|
||||
}
|
||||
|
@ -174,7 +176,8 @@ function metadataValidateBucketAndObj(params, log, callback) {
|
|||
},
|
||||
(bucket, objMD, next) => {
|
||||
const canonicalID = authInfo.getCanonicalID();
|
||||
if (!isObjAuthorized(bucket, objMD, requestType, canonicalID, authInfo, log, request)) {
|
||||
if (!isObjAuthorized(bucket, objMD, requestType, canonicalID, authInfo, isImplicitIdentityDeny,
|
||||
log, request)) {
|
||||
log.debug('access denied for user on object', { requestType });
|
||||
return next(errors.AccessDenied, bucket);
|
||||
}
|
||||
|
@ -196,18 +199,19 @@ function metadataValidateBucketAndObj(params, log, callback) {
|
|||
* @param {string} params.bucketName - name of bucket
|
||||
* @param {string} params.requestType - type of request
|
||||
* @param {string} params.request - http request object
|
||||
* @param {boolean} isImplicitIdentityDeny - identity authorization results
|
||||
* @param {RequestLogger} log - request logger
|
||||
* @param {function} callback - callback
|
||||
* @return {undefined} - and call callback with params err, bucket md
|
||||
*/
|
||||
function metadataValidateBucket(params, log, callback) {
|
||||
function metadataValidateBucket(params, isImplicitIdentityDeny, log, callback) {
|
||||
const { bucketName } = params;
|
||||
return metadata.getBucket(bucketName, log, (err, bucket) => {
|
||||
if (err) {
|
||||
log.debug('metadata getbucket failed', { error: err });
|
||||
return callback(err);
|
||||
}
|
||||
const validationError = validateBucket(bucket, params, log);
|
||||
const validationError = validateBucket(bucket, params, isImplicitIdentityDeny, log);
|
||||
return callback(validationError, bucket);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1271,7 +1271,7 @@ function routeBackbeat(clientIP, request, response, log) {
|
|||
requestType: 'ReplicateObject',
|
||||
request,
|
||||
};
|
||||
return metadataValidateBucketAndObj(mdValParams, log, next);
|
||||
return metadataValidateBucketAndObj(mdValParams, false, log, next);
|
||||
},
|
||||
(bucketInfo, objMd, next) => {
|
||||
if (useMultipleBackend) {
|
||||
|
|
|
@ -244,7 +244,7 @@ describe('bucket policy authorization', () => {
|
|||
describe('isBucketAuthorized with no policy set', () => {
|
||||
it('should allow access to bucket owner', done => {
|
||||
const allowed = isBucketAuthorized(bucket, 'bucketPut',
|
||||
bucketOwnerCanonicalId, null, log);
|
||||
bucketOwnerCanonicalId, null, true, log);
|
||||
assert.equal(allowed, true);
|
||||
done();
|
||||
});
|
||||
|
@ -252,7 +252,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should deny access to non-bucket owner',
|
||||
done => {
|
||||
const allowed = isBucketAuthorized(bucket, 'bucketPut',
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, false);
|
||||
done();
|
||||
});
|
||||
|
@ -268,7 +268,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should allow access to non-bucket owner if principal is set to "*"',
|
||||
done => {
|
||||
const allowed = isBucketAuthorized(bucket, bucAction,
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, true);
|
||||
done();
|
||||
});
|
||||
|
@ -276,7 +276,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should allow access to public user if principal is set to "*"',
|
||||
done => {
|
||||
const allowed = isBucketAuthorized(bucket, bucAction,
|
||||
constants.publicId, null, log);
|
||||
constants.publicId, null, true, log);
|
||||
assert.equal(allowed, true);
|
||||
done();
|
||||
});
|
||||
|
@ -287,7 +287,7 @@ describe('bucket policy authorization', () => {
|
|||
newPolicy.Statement[0][t.keyToChange] = t.bucketValue;
|
||||
bucket.setBucketPolicy(newPolicy);
|
||||
const allowed = isBucketAuthorized(bucket, bucAction,
|
||||
t.bucketId, t.bucketAuthInfo, log);
|
||||
t.bucketId, t.bucketAuthInfo, true, log);
|
||||
assert.equal(allowed, t.expected);
|
||||
done();
|
||||
});
|
||||
|
@ -304,7 +304,7 @@ describe('bucket policy authorization', () => {
|
|||
};
|
||||
bucket.setBucketPolicy(newPolicy);
|
||||
const allowed = isBucketAuthorized(bucket, bucAction,
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, false);
|
||||
done();
|
||||
});
|
||||
|
@ -312,7 +312,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should deny access to non-bucket owner with an unsupported action type',
|
||||
done => {
|
||||
const allowed = isBucketAuthorized(bucket, 'unsupportedAction',
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, false);
|
||||
done();
|
||||
});
|
||||
|
@ -325,7 +325,7 @@ describe('bucket policy authorization', () => {
|
|||
|
||||
it('should allow access to object owner', done => {
|
||||
const allowed = isObjAuthorized(bucket, object, objAction,
|
||||
objectOwnerCanonicalId, null, log);
|
||||
objectOwnerCanonicalId, null, true, log);
|
||||
assert.equal(allowed, true);
|
||||
done();
|
||||
});
|
||||
|
@ -333,7 +333,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should deny access to non-object owner',
|
||||
done => {
|
||||
const allowed = isObjAuthorized(bucket, object, objAction,
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, false);
|
||||
done();
|
||||
});
|
||||
|
@ -352,7 +352,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should allow access to non-object owner if principal is set to "*"',
|
||||
done => {
|
||||
const allowed = isObjAuthorized(bucket, object, objAction,
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, true);
|
||||
done();
|
||||
});
|
||||
|
@ -360,7 +360,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should allow access to public user if principal is set to "*"',
|
||||
done => {
|
||||
const allowed = isObjAuthorized(bucket, object, objAction,
|
||||
constants.publicId, null, log);
|
||||
constants.publicId, null, true, log);
|
||||
assert.equal(allowed, true);
|
||||
done();
|
||||
});
|
||||
|
@ -371,7 +371,7 @@ describe('bucket policy authorization', () => {
|
|||
newPolicy.Statement[0][t.keyToChange] = t.objectValue;
|
||||
bucket.setBucketPolicy(newPolicy);
|
||||
const allowed = isObjAuthorized(bucket, object, objAction,
|
||||
t.objectId, t.objectAuthInfo, log);
|
||||
t.objectId, t.objectAuthInfo, true, log);
|
||||
assert.equal(allowed, t.expected);
|
||||
done();
|
||||
});
|
||||
|
@ -383,7 +383,7 @@ describe('bucket policy authorization', () => {
|
|||
newPolicy.Statement[0].Action = ['s3:GetObject'];
|
||||
bucket.setBucketPolicy(newPolicy);
|
||||
const allowed = isObjAuthorized(bucket, object, 'objectHead',
|
||||
altAcctCanonicalId, altAcctAuthInfo, log);
|
||||
altAcctCanonicalId, altAcctAuthInfo, true, log);
|
||||
assert.equal(allowed, true);
|
||||
done();
|
||||
});
|
||||
|
@ -393,7 +393,7 @@ describe('bucket policy authorization', () => {
|
|||
newPolicy.Statement[0].Action = ['s3:PutObject'];
|
||||
bucket.setBucketPolicy(newPolicy);
|
||||
const allowed = isObjAuthorized(bucket, object, 'objectHead',
|
||||
altAcctCanonicalId, altAcctAuthInfo, log);
|
||||
altAcctCanonicalId, altAcctAuthInfo, true, log);
|
||||
assert.equal(allowed, false);
|
||||
done();
|
||||
});
|
||||
|
@ -408,7 +408,7 @@ describe('bucket policy authorization', () => {
|
|||
};
|
||||
bucket.setBucketPolicy(newPolicy);
|
||||
const allowed = isObjAuthorized(bucket, object, objAction,
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, false);
|
||||
done();
|
||||
});
|
||||
|
@ -416,7 +416,7 @@ describe('bucket policy authorization', () => {
|
|||
it('should deny access to non-object owner with an unsupported action type',
|
||||
done => {
|
||||
const allowed = isObjAuthorized(bucket, object, 'unsupportedAction',
|
||||
altAcctCanonicalId, null, log);
|
||||
altAcctCanonicalId, null, true, log);
|
||||
assert.equal(allowed, false);
|
||||
done();
|
||||
});
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('validateBucket', () => {
|
|||
authInfo: otherAuthInfo,
|
||||
requestType: 'bucketGet',
|
||||
request: null,
|
||||
}, log);
|
||||
}, true, log);
|
||||
assert(validationResult);
|
||||
assert(validationResult.is.AccessDenied);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue