diff --git a/src/endpoint/s3/ops/s3_put_bucket_lifecycle.js b/src/endpoint/s3/ops/s3_put_bucket_lifecycle.js index b54024cc4f..b079d2b151 100644 --- a/src/endpoint/s3/ops/s3_put_bucket_lifecycle.js +++ b/src/endpoint/s3/ops/s3_put_bucket_lifecycle.js @@ -2,6 +2,7 @@ 'use strict'; const _ = require('lodash'); +const s3_const = require('../s3_constants'); const { v4: uuid } = require('uuid'); const dbg = require('../../../util/debug_module')(__filename); const S3Error = require('../s3_errors').S3Error; @@ -88,7 +89,12 @@ async function put_bucket_lifecycle(req) { }; if (rule.ID?.length === 1) { - current_rule.id = rule.ID[0]; + if (rule.ID[0].length > s3_const.MAX_RULE_ID_LENGTH) { + dbg.error('Rule should not have ID length exceed allowed limit of ', s3_const.MAX_RULE_ID_LENGTH, ' characters', rule); + throw new S3Error({ ...S3Error.InvalidArgument, message: `ID length should not exceed allowed limit of ${s3_const.MAX_RULE_ID_LENGTH}` }); + } else { + current_rule.id = rule.ID[0]; + } } else { // Generate a random ID if missing current_rule.id = uuid(); diff --git a/src/endpoint/s3/s3_constants.js b/src/endpoint/s3/s3_constants.js new file mode 100644 index 0000000000..7399f6039f --- /dev/null +++ b/src/endpoint/s3/s3_constants.js @@ -0,0 +1,12 @@ +/* Copyright (C) 2016 NooBaa */ +'use strict'; + +// `s3_const` serves as an alias for `exports` which expose constants related to s3 operations +// keeping name referencing consistent to s3_const.NAME for easier imports and searches +const s3_const = exports; + +/////////////// +// LIFECYCLE // +/////////////// + +s3_const.MAX_RULE_ID_LENGTH = 255; diff --git a/src/test/lifecycle/common.js b/src/test/lifecycle/common.js index acc8a971ad..c4a2001287 100644 --- a/src/test/lifecycle/common.js +++ b/src/test/lifecycle/common.js @@ -2,6 +2,7 @@ 'use strict'; const assert = require('assert'); +const s3_const = require('../../endpoint/s3/s3_constants'); /* * https://docs.aws.amazon.com/AmazonS3/latest/userguide/intro-lifecycle-rules.html @@ -512,3 +513,18 @@ exports.test_and_prefix_size = async function(Bucket, Key, s3) { assert(actualFilter.ObjectSizeGreaterThan === expectedFilter.ObjectSizeGreaterThan, 'and prefix size filter - ObjectSizeGreaterThan'); assert(actualFilter.ObjectSizeLessThan === expectedFilter.ObjectSizeLessThan, 'and prefix size filter - ObjectSizeLessThan'); }; + +exports.test_rule_id_length = async function(Bucket, Key, s3) { + const putLifecycleParams = id_lifecycle_configuration(Bucket, Key); + + // set the ID to a value with more than 'MAX_RULE_ID_LENGTH' characters + const ID = 'A'.repeat(s3_const.MAX_RULE_ID_LENGTH + 5); + putLifecycleParams.LifecycleConfiguration.Rules[0].ID = ID; + + try { + await s3.putBucketLifecycleConfiguration(putLifecycleParams); + assert.fail(`Expected error for ID length exceeding maximum allowed characters ${s3_const.MAX_RULE_ID_LENGTH}, but request was successful`); + } catch (error) { + assert(error.code === 'InvalidArgument', `Expected InvalidArgument: id length exceeding ${s3_const.MAX_RULE_ID_LENGTH} characters`); + } +}; diff --git a/src/test/system_tests/test_lifecycle.js b/src/test/system_tests/test_lifecycle.js index e30acde165..ea00ee0d69 100644 --- a/src/test/system_tests/test_lifecycle.js +++ b/src/test/system_tests/test_lifecycle.js @@ -54,6 +54,7 @@ async function main() { await commonTests.test_rule_id(Bucket, Key, s3); await commonTests.test_filter_size(Bucket, s3); await commonTests.test_and_prefix_size(Bucket, Key, s3); + await commonTests.test_rule_id_length(Bucket, Key, s3); const getObjectParams = { Bucket,