Compare commits
6 Commits
developmen
...
hotfix/7.5
Author | SHA1 | Date |
---|---|---|
Stephane-Scality | ec7b949a63 | |
Dora Korpar | 01041c1577 | |
Dora Korpar | 6e13781f2f | |
Dora Korpar | 53340a6aff | |
Dora Korpar | 65badcd71e | |
Dora Korpar | c4eb431c00 |
1
index.js
1
index.js
|
@ -107,6 +107,7 @@ module.exports = {
|
||||||
require('./lib/models/ReplicationConfiguration'),
|
require('./lib/models/ReplicationConfiguration'),
|
||||||
LifecycleConfiguration:
|
LifecycleConfiguration:
|
||||||
require('./lib/models/LifecycleConfiguration'),
|
require('./lib/models/LifecycleConfiguration'),
|
||||||
|
BucketPolicy: require('./lib/models/BucketPolicy'),
|
||||||
},
|
},
|
||||||
metrics: {
|
metrics: {
|
||||||
StatsClient: require('./lib/metrics/StatsClient'),
|
StatsClient: require('./lib/metrics/StatsClient'),
|
||||||
|
|
|
@ -2,6 +2,7 @@ const assert = require('assert');
|
||||||
const { WebsiteConfiguration } = require('./WebsiteConfiguration');
|
const { WebsiteConfiguration } = require('./WebsiteConfiguration');
|
||||||
const ReplicationConfiguration = require('./ReplicationConfiguration');
|
const ReplicationConfiguration = require('./ReplicationConfiguration');
|
||||||
const LifecycleConfiguration = require('./LifecycleConfiguration');
|
const LifecycleConfiguration = require('./LifecycleConfiguration');
|
||||||
|
const BucketPolicy = require('./BucketPolicy');
|
||||||
|
|
||||||
// WHEN UPDATING THIS NUMBER, UPDATE MODELVERSION.MD CHANGELOG
|
// WHEN UPDATING THIS NUMBER, UPDATE MODELVERSION.MD CHANGELOG
|
||||||
const modelVersion = 6;
|
const modelVersion = 6;
|
||||||
|
@ -47,12 +48,14 @@ class BucketInfo {
|
||||||
* @param {string[]} [cors[].exposeHeaders] - headers expose to applications
|
* @param {string[]} [cors[].exposeHeaders] - headers expose to applications
|
||||||
* @param {object} [replicationConfiguration] - replication configuration
|
* @param {object} [replicationConfiguration] - replication configuration
|
||||||
* @param {object} [lifecycleConfiguration] - lifecycle configuration
|
* @param {object} [lifecycleConfiguration] - lifecycle configuration
|
||||||
|
* @param {object} [bucketPolicy] - bucket policy
|
||||||
*/
|
*/
|
||||||
constructor(name, owner, ownerDisplayName, creationDate,
|
constructor(name, owner, ownerDisplayName, creationDate,
|
||||||
mdBucketModelVersion, acl, transient, deleted,
|
mdBucketModelVersion, acl, transient, deleted,
|
||||||
serverSideEncryption, versioningConfiguration,
|
serverSideEncryption, versioningConfiguration,
|
||||||
locationConstraint, websiteConfiguration, cors,
|
locationConstraint, websiteConfiguration, cors,
|
||||||
replicationConfiguration, lifecycleConfiguration) {
|
replicationConfiguration, lifecycleConfiguration,
|
||||||
|
bucketPolicy) {
|
||||||
assert.strictEqual(typeof name, 'string');
|
assert.strictEqual(typeof name, 'string');
|
||||||
assert.strictEqual(typeof owner, 'string');
|
assert.strictEqual(typeof owner, 'string');
|
||||||
assert.strictEqual(typeof ownerDisplayName, 'string');
|
assert.strictEqual(typeof ownerDisplayName, 'string');
|
||||||
|
@ -112,6 +115,9 @@ class BucketInfo {
|
||||||
if (lifecycleConfiguration) {
|
if (lifecycleConfiguration) {
|
||||||
LifecycleConfiguration.validateConfig(lifecycleConfiguration);
|
LifecycleConfiguration.validateConfig(lifecycleConfiguration);
|
||||||
}
|
}
|
||||||
|
if (bucketPolicy) {
|
||||||
|
BucketPolicy.validatePolicy(bucketPolicy);
|
||||||
|
}
|
||||||
const aclInstance = acl || {
|
const aclInstance = acl || {
|
||||||
Canned: 'private',
|
Canned: 'private',
|
||||||
FULL_CONTROL: [],
|
FULL_CONTROL: [],
|
||||||
|
@ -137,6 +143,7 @@ class BucketInfo {
|
||||||
this._replicationConfiguration = replicationConfiguration || null;
|
this._replicationConfiguration = replicationConfiguration || null;
|
||||||
this._cors = cors || null;
|
this._cors = cors || null;
|
||||||
this._lifecycleConfiguration = lifecycleConfiguration || null;
|
this._lifecycleConfiguration = lifecycleConfiguration || null;
|
||||||
|
this._bucketPolicy = bucketPolicy || null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -160,6 +167,7 @@ class BucketInfo {
|
||||||
cors: this._cors,
|
cors: this._cors,
|
||||||
replicationConfiguration: this._replicationConfiguration,
|
replicationConfiguration: this._replicationConfiguration,
|
||||||
lifecycleConfiguration: this._lifecycleConfiguration,
|
lifecycleConfiguration: this._lifecycleConfiguration,
|
||||||
|
bucketPolicy: this._bucketPolicy,
|
||||||
};
|
};
|
||||||
if (this._websiteConfiguration) {
|
if (this._websiteConfiguration) {
|
||||||
bucketInfos.websiteConfiguration =
|
bucketInfos.websiteConfiguration =
|
||||||
|
@ -180,7 +188,8 @@ class BucketInfo {
|
||||||
obj.creationDate, obj.mdBucketModelVersion, obj.acl,
|
obj.creationDate, obj.mdBucketModelVersion, obj.acl,
|
||||||
obj.transient, obj.deleted, obj.serverSideEncryption,
|
obj.transient, obj.deleted, obj.serverSideEncryption,
|
||||||
obj.versioningConfiguration, obj.locationConstraint, websiteConfig,
|
obj.versioningConfiguration, obj.locationConstraint, websiteConfig,
|
||||||
obj.cors, obj.replicationConfiguration, obj.lifecycleConfiguration);
|
obj.cors, obj.replicationConfiguration, obj.lifecycleConfiguration,
|
||||||
|
obj.bucketPolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,7 +212,8 @@ class BucketInfo {
|
||||||
data._transient, data._deleted, data._serverSideEncryption,
|
data._transient, data._deleted, data._serverSideEncryption,
|
||||||
data._versioningConfiguration, data._locationConstraint,
|
data._versioningConfiguration, data._locationConstraint,
|
||||||
data._websiteConfiguration, data._cors,
|
data._websiteConfiguration, data._cors,
|
||||||
data._replicationConfiguration, data._lifecycleConfiguration);
|
data._replicationConfiguration, data._lifecycleConfiguration,
|
||||||
|
data._bucketPolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,6 +341,23 @@ class BucketInfo {
|
||||||
this._lifecycleConfiguration = lifecycleConfiguration;
|
this._lifecycleConfiguration = lifecycleConfiguration;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Get bucket policy statement
|
||||||
|
* @return {object|null} bucket policy statement or `null` if the bucket
|
||||||
|
* does not have a bucket policy
|
||||||
|
*/
|
||||||
|
getBucketPolicy() {
|
||||||
|
return this._bucketPolicy;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set bucket policy statement
|
||||||
|
* @param {object} bucketPolicy - bucket policy
|
||||||
|
* @return {BucketInfo} - bucket info instance
|
||||||
|
*/
|
||||||
|
setBucketPolicy(bucketPolicy) {
|
||||||
|
this._bucketPolicy = bucketPolicy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Get cors resource
|
* Get cors resource
|
||||||
* @return {object[]} cors
|
* @return {object[]} cors
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const errors = require('../errors');
|
||||||
|
const { validateResourcePolicy } = require('../policy/policyValidator');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format of json policy:
|
||||||
|
* {
|
||||||
|
* "Id": "Policy id",
|
||||||
|
* "Version": "version date",
|
||||||
|
* "Statement": [
|
||||||
|
* {
|
||||||
|
* "Sid": "Statement id",
|
||||||
|
* "Effect": "Allow",
|
||||||
|
* "Principal": "*",
|
||||||
|
* "Action": "s3:*",
|
||||||
|
* "Resource": "arn:aws:s3:::examplebucket/bucket2/object"
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* "Sid": "Statement id",
|
||||||
|
* "Effect": "Deny",
|
||||||
|
* "Principal": {
|
||||||
|
* "AWS": ["arn:aws:iam::<account_id>", "different_account_id"]
|
||||||
|
* },
|
||||||
|
* "Action": [ "s3:*" ],
|
||||||
|
* "Resource": [
|
||||||
|
* "arn:aws:s3:::examplebucket", "arn:aws:s3:::otherbucket/*"],
|
||||||
|
* "Condition": {
|
||||||
|
* "StringNotLike": {
|
||||||
|
* "aws:Referer": [
|
||||||
|
* "http://www.example.com/", "http://example.com/*"]
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
const objectActions = [
|
||||||
|
's3:AbortMultipartUpload',
|
||||||
|
's3:DeleteObject',
|
||||||
|
's3:DeleteObjectTagging',
|
||||||
|
's3:GetObject',
|
||||||
|
's3:GetObjectAcl',
|
||||||
|
's3:GetObjectTagging',
|
||||||
|
's3:ListMultipartUploadParts',
|
||||||
|
's3:PutObject',
|
||||||
|
's3:PutObjectAcl',
|
||||||
|
's3:PutObjectTagging',
|
||||||
|
];
|
||||||
|
|
||||||
|
class BucketPolicy {
|
||||||
|
/**
|
||||||
|
* Create a Bucket Policy instance
|
||||||
|
* @param {string} json - the json policy
|
||||||
|
* @return {object} - BucketPolicy instance
|
||||||
|
*/
|
||||||
|
constructor(json) {
|
||||||
|
this._json = json;
|
||||||
|
this._policy = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bucket policy
|
||||||
|
* @return {object} - the bucket policy or error
|
||||||
|
*/
|
||||||
|
getBucketPolicy() {
|
||||||
|
const policy = this._getPolicy();
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bucket policy array
|
||||||
|
* @return {object} - contains error if policy validation fails
|
||||||
|
*/
|
||||||
|
_getPolicy() {
|
||||||
|
if (!this._json || this._json === '') {
|
||||||
|
return { error: errors.MalformedPolicy.customizeDescription(
|
||||||
|
'request json is empty or undefined') };
|
||||||
|
}
|
||||||
|
const validSchema = validateResourcePolicy(this._json);
|
||||||
|
if (validSchema.error) {
|
||||||
|
return validSchema;
|
||||||
|
}
|
||||||
|
this._setStatementArray();
|
||||||
|
const valAcRes = this._validateActionResource();
|
||||||
|
if (valAcRes.error) {
|
||||||
|
return valAcRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
_setStatementArray() {
|
||||||
|
this._policy = JSON.parse(this._json);
|
||||||
|
if (!Array.isArray(this._policy.Statement)) {
|
||||||
|
const statement = this._policy.Statement;
|
||||||
|
this._policy.Statement = [statement];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate action and resource are compatible
|
||||||
|
* @return {error} - contains error or empty obj
|
||||||
|
*/
|
||||||
|
_validateActionResource() {
|
||||||
|
const invalid = this._policy.Statement.every(s => {
|
||||||
|
const actions = typeof s.Action === 'string' ?
|
||||||
|
[s.Action] : s.Action;
|
||||||
|
const resources = typeof s.Resource === 'string' ?
|
||||||
|
[s.Resource] : s.Resource;
|
||||||
|
const objectAction = actions.some(a =>
|
||||||
|
a.includes('Object') || objectActions.includes(a));
|
||||||
|
// wildcardObjectAction checks for actions such as 's3:*' or
|
||||||
|
// 's3:Put*' but will return false for actions such as
|
||||||
|
// 's3:PutBucket*'
|
||||||
|
const wildcardObjectAction = actions.some(
|
||||||
|
a => a.includes('*') && !a.includes('Bucket'));
|
||||||
|
const objectResource = resources.some(r => r.includes('/'));
|
||||||
|
return ((objectAction && !objectResource) ||
|
||||||
|
(objectResource && !objectAction && !wildcardObjectAction));
|
||||||
|
});
|
||||||
|
if (invalid) {
|
||||||
|
return { error: errors.MalformedPolicy.customizeDescription(
|
||||||
|
'Action does not apply to any resource(s) in statement') };
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call resource policy schema validation function
|
||||||
|
* @param {object} policy - the bucket policy object to validate
|
||||||
|
* @return {undefined}
|
||||||
|
*/
|
||||||
|
static validatePolicy(policy) {
|
||||||
|
// only the BucketInfo constructor calls this function
|
||||||
|
// and BucketInfo will always be passed an object
|
||||||
|
const validated = validateResourcePolicy(JSON.stringify(policy));
|
||||||
|
assert.deepStrictEqual(validated, { error: null, valid: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BucketPolicy;
|
|
@ -67,7 +67,7 @@ function isResourceApplicable(requestContext, statementResource, log) {
|
||||||
* @param {Object} log - logger
|
* @param {Object} log - logger
|
||||||
* @return {boolean} true if applicable, false if not
|
* @return {boolean} true if applicable, false if not
|
||||||
*/
|
*/
|
||||||
function isActionApplicable(requestAction, statementAction, log) {
|
evaluators.isActionApplicable = (requestAction, statementAction, log) => {
|
||||||
if (!Array.isArray(statementAction)) {
|
if (!Array.isArray(statementAction)) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
statementAction = [statementAction];
|
statementAction = [statementAction];
|
||||||
|
@ -89,7 +89,7 @@ function isActionApplicable(requestAction, statementAction, log) {
|
||||||
{ requestAction });
|
{ requestAction });
|
||||||
// If no match found, return false
|
// If no match found, return false
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether request meets policy conditions
|
* Check whether request meets policy conditions
|
||||||
|
@ -209,14 +209,14 @@ evaluators.evaluatePolicy = (requestContext, policy, log) => {
|
||||||
// If affirmative action is in policy and request action is not
|
// If affirmative action is in policy and request action is not
|
||||||
// applicable, move on to next statement
|
// applicable, move on to next statement
|
||||||
if (currentStatement.Action &&
|
if (currentStatement.Action &&
|
||||||
!isActionApplicable(requestContext.getAction(),
|
!evaluators.isActionApplicable(requestContext.getAction(),
|
||||||
currentStatement.Action, log)) {
|
currentStatement.Action, log)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If NotAction is in policy and action matches NotAction in policy,
|
// If NotAction is in policy and action matches NotAction in policy,
|
||||||
// move on to next statement
|
// move on to next statement
|
||||||
if (currentStatement.NotAction &&
|
if (currentStatement.NotAction &&
|
||||||
isActionApplicable(requestContext.getAction(),
|
evaluators.isActionApplicable(requestContext.getAction(),
|
||||||
currentStatement.NotAction, log)) {
|
currentStatement.NotAction, log)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,9 +73,9 @@ function routerGET(request, response, api, log, statsClient, dataRetrievalFn) {
|
||||||
});
|
});
|
||||||
} else if (request.query.policy !== undefined) {
|
} else if (request.query.policy !== undefined) {
|
||||||
api.callApiMethod('bucketGetPolicy', request, response, log,
|
api.callApiMethod('bucketGetPolicy', request, response, log,
|
||||||
(err, json, corsHeaders) => {
|
(err, xml, corsHeaders) => {
|
||||||
routesUtils.statsReport500(err, statsClient);
|
routesUtils.statsReport500(err, statsClient);
|
||||||
return routesUtils.responseJSONBody(err, json, response,
|
return routesUtils.responseXMLBody(err, xml, response,
|
||||||
log, corsHeaders);
|
log, corsHeaders);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -115,6 +115,18 @@ const testLifecycleConfiguration = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const testBucketPolicy = {
|
||||||
|
Version: '2012-10-17',
|
||||||
|
Statement: [
|
||||||
|
{
|
||||||
|
Effect: 'Allow',
|
||||||
|
Principal: '*',
|
||||||
|
Resource: 'arn:aws:s3:::examplebucket',
|
||||||
|
Action: 's3:*',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
// create a dummy bucket to test getters and setters
|
// create a dummy bucket to test getters and setters
|
||||||
|
|
||||||
Object.keys(acl).forEach(
|
Object.keys(acl).forEach(
|
||||||
|
@ -132,7 +144,8 @@ Object.keys(acl).forEach(
|
||||||
testWebsiteConfiguration,
|
testWebsiteConfiguration,
|
||||||
testCorsConfiguration,
|
testCorsConfiguration,
|
||||||
testReplicationConfiguration,
|
testReplicationConfiguration,
|
||||||
testLifecycleConfiguration);
|
testLifecycleConfiguration,
|
||||||
|
testBucketPolicy);
|
||||||
|
|
||||||
describe('serialize/deSerialize on BucketInfo class', () => {
|
describe('serialize/deSerialize on BucketInfo class', () => {
|
||||||
const serialized = dummyBucket.serialize();
|
const serialized = dummyBucket.serialize();
|
||||||
|
@ -158,6 +171,7 @@ Object.keys(acl).forEach(
|
||||||
dummyBucket._replicationConfiguration,
|
dummyBucket._replicationConfiguration,
|
||||||
lifecycleConfiguration:
|
lifecycleConfiguration:
|
||||||
dummyBucket._lifecycleConfiguration,
|
dummyBucket._lifecycleConfiguration,
|
||||||
|
bucketPolicy: dummyBucket._bucketPolicy,
|
||||||
};
|
};
|
||||||
assert.strictEqual(serialized, JSON.stringify(bucketInfos));
|
assert.strictEqual(serialized, JSON.stringify(bucketInfos));
|
||||||
done();
|
done();
|
||||||
|
@ -257,6 +271,10 @@ Object.keys(acl).forEach(
|
||||||
assert.deepStrictEqual(dummyBucket.getLifecycleConfiguration(),
|
assert.deepStrictEqual(dummyBucket.getLifecycleConfiguration(),
|
||||||
testLifecycleConfiguration);
|
testLifecycleConfiguration);
|
||||||
});
|
});
|
||||||
|
it('getBucketPolicy should return policy', () => {
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
dummyBucket.getBucketPolicy(), testBucketPolicy);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setters on BucketInfo class', () => {
|
describe('setters on BucketInfo class', () => {
|
||||||
|
@ -378,6 +396,22 @@ Object.keys(acl).forEach(
|
||||||
assert.deepStrictEqual(dummyBucket.getLifecycleConfiguration(),
|
assert.deepStrictEqual(dummyBucket.getLifecycleConfiguration(),
|
||||||
newLifecycleConfig);
|
newLifecycleConfig);
|
||||||
});
|
});
|
||||||
|
it('setBucketPolicy should set bucket policy', () => {
|
||||||
|
const newBucketPolicy = {
|
||||||
|
Version: '2012-10-17',
|
||||||
|
Statement: [
|
||||||
|
{
|
||||||
|
Effect: 'Deny',
|
||||||
|
Principal: '*',
|
||||||
|
Resource: 'arn:aws:s3:::examplebucket',
|
||||||
|
Action: 's3:*',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
dummyBucket.setBucketPolicy(newBucketPolicy);
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
dummyBucket.getBucketPolicy(), newBucketPolicy);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const BucketPolicy = require('../../../lib/models/BucketPolicy');
|
||||||
|
|
||||||
|
const testBucketPolicy = {
|
||||||
|
Version: '2012-10-17',
|
||||||
|
Statement: [
|
||||||
|
{
|
||||||
|
Effect: 'Allow',
|
||||||
|
Principal: '*',
|
||||||
|
Resource: 'arn:aws:s3:::examplebucket',
|
||||||
|
Action: 's3:GetBucketLocation',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const mismatchErr = 'Action does not apply to any resource(s) in statement';
|
||||||
|
|
||||||
|
function createPolicy(key, value) {
|
||||||
|
const newPolicy = Object.assign({}, testBucketPolicy);
|
||||||
|
newPolicy.Statement[0][key] = value;
|
||||||
|
return newPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkErr(policy, err, message) {
|
||||||
|
assert.strictEqual(policy.error[err], true);
|
||||||
|
assert.strictEqual(policy.error.description, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('BucketPolicy class getBucketPolicy', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
testBucketPolicy.Statement[0].Resource = 'arn:aws:s3:::examplebucket';
|
||||||
|
testBucketPolicy.Statement[0].Action = 's3:GetBucketLocation';
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return MalformedPolicy error if request json is empty', done => {
|
||||||
|
const bucketPolicy = new BucketPolicy('').getBucketPolicy();
|
||||||
|
const errMessage = 'request json is empty or undefined';
|
||||||
|
checkErr(bucketPolicy, 'MalformedPolicy', errMessage);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return MalformedPolicy error if request action is for objects ' +
|
||||||
|
'but resource refers to bucket', done => {
|
||||||
|
const newPolicy = createPolicy('Action', 's3:GetObject');
|
||||||
|
const bucketPolicy = new BucketPolicy(JSON.stringify(newPolicy))
|
||||||
|
.getBucketPolicy();
|
||||||
|
checkErr(bucketPolicy, 'MalformedPolicy', mismatchErr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return MalformedPolicy error if request action is for objects ' +
|
||||||
|
'but does\'t include \'Object\' and resource refers to bucket', done => {
|
||||||
|
const newPolicy = createPolicy('Action', 's3:AbortMultipartUpload');
|
||||||
|
const bucketPolicy = new BucketPolicy(JSON.stringify(newPolicy))
|
||||||
|
.getBucketPolicy();
|
||||||
|
checkErr(bucketPolicy, 'MalformedPolicy', mismatchErr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return MalformedPolicy error if request action is for objects ' +
|
||||||
|
'(with wildcard) but resource refers to bucket', done => {
|
||||||
|
const newPolicy = createPolicy('Action', 's3:GetObject*');
|
||||||
|
const bucketPolicy = new BucketPolicy(JSON.stringify(newPolicy))
|
||||||
|
.getBucketPolicy();
|
||||||
|
checkErr(bucketPolicy, 'MalformedPolicy', mismatchErr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return MalformedPolicy error if request resource refers to ' +
|
||||||
|
'object but action is for buckets', done => {
|
||||||
|
const newPolicy = createPolicy('Resource',
|
||||||
|
'arn:aws:s3:::examplebucket/*');
|
||||||
|
const bucketPolicy = new BucketPolicy(JSON.stringify(newPolicy))
|
||||||
|
.getBucketPolicy();
|
||||||
|
checkErr(bucketPolicy, 'MalformedPolicy', mismatchErr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return MalformedPolicy error if request resource refers to ' +
|
||||||
|
'object but action is for buckets (with wildcard)', done => {
|
||||||
|
const newPolicy = createPolicy('Resource',
|
||||||
|
'arn:aws:s3:::examplebucket/*');
|
||||||
|
newPolicy.Statement[0].Action = 's3:GetBucket*';
|
||||||
|
const bucketPolicy = new BucketPolicy(JSON.stringify(newPolicy))
|
||||||
|
.getBucketPolicy();
|
||||||
|
checkErr(bucketPolicy, 'MalformedPolicy', mismatchErr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should successfully get a valid policy', done => {
|
||||||
|
const bucketPolicy = new BucketPolicy(JSON.stringify(testBucketPolicy))
|
||||||
|
.getBucketPolicy();
|
||||||
|
assert.deepStrictEqual(bucketPolicy, testBucketPolicy);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should successfully get a valid policy with wildcard in action',
|
||||||
|
done => {
|
||||||
|
const newPolicy = createPolicy('Action', 's3:Get*');
|
||||||
|
const bucketPolicy = new BucketPolicy(JSON.stringify(newPolicy))
|
||||||
|
.getBucketPolicy();
|
||||||
|
assert.deepStrictEqual(bucketPolicy, newPolicy);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue