Skip to content

Commit

Permalink
CLDSRV-429: update get apis with impDeny logic
Browse files Browse the repository at this point in the history
  • Loading branch information
benzekrimaha committed Nov 29, 2023
1 parent 2596f3f commit 924374e
Show file tree
Hide file tree
Showing 33 changed files with 86 additions and 43 deletions.
7 changes: 3 additions & 4 deletions lib/api/bucketGet.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { errors, versioning, s3middleware } = require('arsenal');

const constants = require('../../constants');
const services = require('../services');
const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');
const escapeForXml = s3middleware.escapeForXml;
const { pushMetric } = require('../utapi/utilities');
Expand Down Expand Up @@ -345,9 +345,8 @@ function bucketGet(authInfo, request, log, callback) {
listParams.marker = params.marker;
}

metadataValidateBucket(metadataValParams, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(request.headers.origin,
request.method, bucket);
standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(request.headers.origin, request.method, bucket);
if (err) {
log.debug('error processing request', { error: err });
return callback(err, null, corsHeaders);
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetACL.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const aclUtils = require('../utilities/aclUtils');
const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const vault = require('../auth/vault');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');
const { pushMetric } = require('../utapi/utilities');
Expand Down Expand Up @@ -54,7 +54,7 @@ function bucketGetACL(authInfo, request, log, callback) {
},
};

metadataValidateBucket(metadataValParams, log, (err, bucket) => {
standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(request.headers.origin,
request.method, bucket);
if (err) {
Expand Down
3 changes: 2 additions & 1 deletion lib/api/bucketGetCors.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ function bucketGetCors(authInfo, request, log, callback) {
const corsHeaders = collectCorsHeaders(request.headers.origin,
request.method, bucket);

if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request,
request.actionImplicitDenies)) {
log.debug('access denied for user on bucket', {
requestType,
method: 'bucketGetCors',
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetEncryption.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const async = require('async');
const { pushMetric } = require('../utapi/utilities');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');
const { checkExpectedBucketOwner } = require('./apiUtils/authorization/bucketOwner');
const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const escapeForXml = s3middleware.escapeForXml;

/**
Expand All @@ -27,7 +27,7 @@ function bucketGetEncryption(authInfo, request, log, callback) {
};

return async.waterfall([
next => metadataValidateBucket(metadataValParams, log, next),
next => standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, 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
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetLifecycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { errors } = require('arsenal');
const LifecycleConfiguration =
require('arsenal').models.LifecycleConfiguration;

const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const { pushMetric } = require('../utapi/utilities');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');

Expand All @@ -23,7 +23,7 @@ function bucketGetLifecycle(authInfo, request, log, callback) {
requestType: 'bucketGetLifecycle',
request,
};
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
if (err) {
log.debug('error processing request', {
Expand Down
3 changes: 2 additions & 1 deletion lib/api/bucketGetLocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ function bucketGetLocation(authInfo, request, log, callback) {
const corsHeaders = collectCorsHeaders(request.headers.origin,
request.method, bucket);

if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request,
request.actionImplicitDenies)) {
log.debug('access denied for account on bucket', {
requestType,
method: 'bucketGetLocation',
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetNotification.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const { pushMetric } = require('../utapi/utilities');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');
const { NotificationConfiguration } = require('arsenal').models;
Expand Down Expand Up @@ -41,7 +41,7 @@ function bucketGetNotification(authInfo, request, log, callback) {
request,
};

return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
if (err) {
log.debug('error processing request', {
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetObjectLock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { errors } = require('arsenal');
const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const { pushMetric } = require('../utapi/utilities');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');
const ObjectLockConfiguration =
Expand Down Expand Up @@ -36,7 +36,7 @@ function bucketGetObjectLock(authInfo, request, log, callback) {
requestType: 'bucketGetObjectLock',
request,
};
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
if (err) {
log.debug('error processing request', {
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetPolicy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { errors } = require('arsenal');

const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');

/**
Expand All @@ -21,7 +21,7 @@ function bucketGetPolicy(authInfo, request, log, callback) {
request,
};

return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
if (err) {
log.debug('error processing request', {
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetReplication.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { errors } = require('arsenal');

const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const { pushMetric } = require('../utapi/utilities');
const { getReplicationConfigurationXML } =
require('./apiUtils/bucket/getReplicationConfiguration');
Expand All @@ -23,7 +23,7 @@ function bucketGetReplication(authInfo, request, log, callback) {
requestType: 'bucketGetReplication',
request,
};
return metadataValidateBucket(metadataValParams, log, (err, bucket) => {
return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(headers.origin, method, bucket);
if (err) {
log.debug('error processing request', {
Expand Down
4 changes: 2 additions & 2 deletions lib/api/bucketGetVersioning.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { metadataValidateBucket } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucket } = require('../metadata/metadataUtils');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');
const { pushMetric } = require('../utapi/utilities');

Expand Down Expand Up @@ -57,7 +57,7 @@ function bucketGetVersioning(authInfo, request, log, callback) {
request,
};

metadataValidateBucket(metadataValParams, log, (err, bucket) => {
standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
const corsHeaders = collectCorsHeaders(request.headers.origin,
request.method, bucket);
if (err) {
Expand Down
3 changes: 2 additions & 1 deletion lib/api/bucketGetWebsite.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ function bucketGetWebsite(authInfo, request, log, callback) {

const corsHeaders = collectCorsHeaders(request.headers.origin,
request.method, bucket);
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request)) {
if (!isBucketAuthorized(bucket, requestType, canonicalID, authInfo, log, request,
request.actionImplicitDenies)) {
log.debug('access denied for user on bucket', {
requestType,
method: 'bucketGetWebsite',
Expand Down
4 changes: 2 additions & 2 deletions lib/api/objectGet.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const collectResponseHeaders = require('../utilities/collectResponseHeaders');
const { pushMetric } = require('../utapi/utilities');
const { getVersionIdResHeader } = require('./apiUtils/object/versioning');
const setPartRanges = require('./apiUtils/object/setPartRanges');
const { metadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { getPartCountFromMd5 } = require('./apiUtils/object/partInfo');
const { setExpirationHeaders } = require('./apiUtils/object/expirationHeaders');

Expand Down Expand Up @@ -48,7 +48,7 @@ function objectGet(authInfo, request, returnTagCount, log, callback) {
request,
};

return metadataValidateBucketAndObj(mdValParams, log,
return standardMetadataValidateBucketAndObj(mdValParams, request.actionImplicitDenies, log,
(err, bucket, objMD) => {
const corsHeaders = collectCorsHeaders(request.headers.origin,
request.method, bucket);
Expand Down
4 changes: 2 additions & 2 deletions lib/api/objectGetACL.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const { pushMetric } = require('../utapi/utilities');
const { decodeVersionId, getVersionIdResHeader }
= require('./apiUtils/object/versioning');
const vault = require('../auth/vault');
const { metadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucketAndObj } = require('../metadata/metadataUtils');

// Sample XML response:
/*
Expand Down Expand Up @@ -71,7 +71,7 @@ function objectGetACL(authInfo, request, log, callback) {

return async.waterfall([
function validateBucketAndObj(next) {
return metadataValidateBucketAndObj(metadataValParams, log,
return standardMetadataValidateBucketAndObj(metadataValParams, request.actionImplicitDenies, log,
(err, bucket, objectMD) => {
if (err) {
log.trace('request authorization failed',
Expand Down
4 changes: 2 additions & 2 deletions lib/api/objectGetLegalHold.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { errors, s3middleware } = require('arsenal');
const { decodeVersionId, getVersionIdResHeader }
= require('./apiUtils/object/versioning');

const { metadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { pushMetric } = require('../utapi/utilities');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');

Expand Down Expand Up @@ -43,7 +43,7 @@ function objectGetLegalHold(authInfo, request, log, callback) {
};

return async.waterfall([
next => metadataValidateBucketAndObj(metadataValParams, log,
next => standardMetadataValidateBucketAndObj(metadataValParams, request.actionImplicitDenies, log,
(err, bucket, objectMD) => {
if (err) {
log.trace('request authorization failed',
Expand Down
4 changes: 2 additions & 2 deletions lib/api/objectGetRetention.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { errors, s3middleware } = require('arsenal');
const { decodeVersionId, getVersionIdResHeader }
= require('./apiUtils/object/versioning');

const { metadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { pushMetric } = require('../utapi/utilities');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');

Expand Down Expand Up @@ -43,7 +43,7 @@ function objectGetRetention(authInfo, request, log, callback) {
};

return async.waterfall([
next => metadataValidateBucketAndObj(metadataValParams, log,
next => standardMetadataValidateBucketAndObj(metadataValParams, request.actionImplicitDenies, log,
(err, bucket, objectMD) => {
if (err) {
log.trace('request authorization failed',
Expand Down
4 changes: 2 additions & 2 deletions lib/api/objectGetTagging.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { errors, s3middleware } = require('arsenal');
const { decodeVersionId, getVersionIdResHeader }
= require('./apiUtils/object/versioning');

const { metadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { standardMetadataValidateBucketAndObj } = require('../metadata/metadataUtils');
const { pushMetric } = require('../utapi/utilities');
const collectCorsHeaders = require('../utilities/collectCorsHeaders');
const { convertToXml } = s3middleware.tagging;
Expand Down Expand Up @@ -43,7 +43,7 @@ function objectGetTagging(authInfo, request, log, callback) {
};

return async.waterfall([
next => metadataValidateBucketAndObj(metadataValParams, log,
next => standardMetadataValidateBucketAndObj(metadataValParams, request.actionImplicitDenies, log,
(err, bucket, objectMD) => {
if (err) {
log.trace('request authorization failed',
Expand Down
21 changes: 11 additions & 10 deletions lib/api/websiteGet.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ const { pushMetric } = require('../utapi/utilities');
* @param {string} objectKey - object key from request (or as translated in
* websiteGet)
* @param {object} corsHeaders - CORS-related response headers
* @param {object} request - normalized request object
* @param {object} log - Werelogs instance
* @param {function} callback - callback to function in route
* @return {undefined}
*/
function _errorActions(err, errorDocument, routingRules,
bucket, objectKey, corsHeaders, log, callback) {
bucket, objectKey, corsHeaders, request, log, callback) {
const bucketName = bucket.getName();
const errRoutingRule = findRoutingRule(routingRules,
objectKey, err.code);
Expand All @@ -46,8 +47,8 @@ function _errorActions(err, errorDocument, routingRules,
}
// return the default error message if the object is private
// rather than sending a stored error file
if (!isObjAuthorized(bucket, errObjMD, 'objectGet',
constants.publicId, null, log)) {
if (!isObjAuthorized(bucket, errObjMD, request.apiMethods || 'objectGet',
constants.publicId, null, log, null, request.actionImplicitDenies)) {
log.trace('errorObj not authorized', { error: err });
return callback(err, true, null, corsHeaders);
}
Expand Down Expand Up @@ -143,25 +144,25 @@ function websiteGet(request, log, callback) {
log.trace('error retrieving object metadata',
{ error: err });
let returnErr = err;
const bucketAuthorized = isBucketAuthorized(bucket,
'bucketGet', constants.publicId, null, log, request);
const bucketAuthorized = isBucketAuthorized(bucket, request.apiMethods || 'bucketGet',
constants.publicId, null, log, request, request.actionImplicitDenies);
// if index object does not exist and bucket is private AWS
// returns 403 - AccessDenied error.
if (err.is.NoSuchKey && !bucketAuthorized) {
returnErr = errors.AccessDenied;
}
return _errorActions(returnErr,
websiteConfig.getErrorDocument(), routingRules,
bucket, reqObjectKey, corsHeaders, log,
bucket, reqObjectKey, corsHeaders, request, log,
callback);
}
if (!isObjAuthorized(bucket, objMD, 'objectGet',
constants.publicId, null, log, request)) {
if (!isObjAuthorized(bucket, objMD, request.apiMethods || 'objectGet',
constants.publicId, null, log, request, request.actionImplicitDenies)) {
const err = errors.AccessDenied;
log.trace('request not authorized', { error: err });
return _errorActions(err, websiteConfig.getErrorDocument(),
routingRules, bucket,
reqObjectKey, corsHeaders, log, callback);
reqObjectKey, corsHeaders, request, log, callback);
}

const headerValResult = validateHeaders(request.headers,
Expand All @@ -171,7 +172,7 @@ function websiteGet(request, log, callback) {
log.trace('header validation error', { error: err });
return _errorActions(err, websiteConfig.getErrorDocument(),
routingRules, bucket, reqObjectKey,
corsHeaders, log, callback);
corsHeaders, request, log, callback);
}
// check if object to serve has website redirect header
// Note: AWS prioritizes website configuration rules over
Expand Down
1 change: 1 addition & 0 deletions tests/unit/api/bucketGet.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const baseGetRequest = {
bucketName,
namespace,
headers: { host: '/' },
actionImplicitDenies: false,
};
const baseUrl = `/${bucketName}`;

Expand Down
Loading

0 comments on commit 924374e

Please sign in to comment.