Skip to content

Commit ca67f3f

Browse files
author
Kerkesni
committed
[FIXUP] add more test cases
1 parent 3501047 commit ca67f3f

File tree

1 file changed

+106
-93
lines changed

1 file changed

+106
-93
lines changed

tests/unit/routes/routeBackbeat.js

Lines changed: 106 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const { promisify } = require('util');
55
const metadataUtils = require('../../../lib/metadata/metadataUtils');
66
const storeObject = require('../../../lib/api/apiUtils/object/storeObject');
77
const metadata = require('../../../lib/metadata/wrapper');
8-
const { routeBackbeat, backbeatRoutes } = require('../../../lib/routes/routeBackbeat');
8+
const { routeBackbeat } = require('../../../lib/routes/routeBackbeat');
99
const { DummyRequestLogger, versioningTestUtils, makeAuthInfo } = require('../helpers');
1010
const dataWrapper = require('../../../lib/data/wrapper');
1111
const DummyRequest = require('../DummyRequest');
@@ -14,8 +14,10 @@ const AuthInfo = auth.AuthInfo;
1414
const { config } = require('../../../lib/Config');
1515
const quotaUtils = require('../../../lib/api/apiUtils/quotas/quotaUtils');
1616
const { bucketPut } = require('../../../lib/api/bucketPut');
17-
const objectPut = require('../../../lib/api/objectPut');
17+
const bucketDelete = require('../../../lib/api/bucketDelete');
1818
const bucketPutVersioning = require('../../../lib/api/bucketPutVersioning');
19+
const objectPut = require('../../../lib/api/objectPut');
20+
const { objectDelete } = require('../../../lib/api/objectDelete');
1921

2022
const log = new DummyRequestLogger();
2123

@@ -702,12 +704,12 @@ describe('routeBackbeat', () => {
702704
});
703705

704706
describe('routeBackbeat authorization', () => {
707+
let endPromise;
708+
let resolveEnd;
705709
const bucketName = 'bucketname';
706-
const canonicalID = 'accessKey1';
707-
const authInfo = makeAuthInfo(canonicalID);
710+
const authInfo = makeAuthInfo('cannonicalID',);
708711
const namespace = 'default';
709712
const objectName = 'objectName';
710-
const postBody = Buffer.from('I am a body', 'utf8');
711713

712714
const testBucket = {
713715
bucketName,
@@ -729,49 +731,14 @@ describe('routeBackbeat authorization', () => {
729731
},
730732
parsedContentLength: 12,
731733
url: `/${bucketName}/${objectName}`,
732-
}, postBody);
734+
}, Buffer.from('I am a body', 'utf8'));
733735

734736
let request;
735737
let response;
736738

737739
beforeEach(() => {
738-
sinon.stub(backbeatRoutes, 'PUT').returns({
739-
data: sinon.stub(),
740-
metadata: sinon.stub(),
741-
multiplebackenddata: {
742-
putobject: sinon.stub(),
743-
putpart: sinon.stub(),
744-
},
745-
});
746-
747-
sinon.stub(backbeatRoutes, 'POST').returns({
748-
multiplebackenddata: {
749-
initiatempu: sinon.stub(),
750-
completempu: sinon.stub(),
751-
puttagging: sinon.stub(),
752-
},
753-
batchdelete: sinon.stub(),
754-
index: {
755-
add: sinon.stub(),
756-
delete: sinon.stub(),
757-
},
758-
});
759-
760-
sinon.stub(backbeatRoutes, 'DELETE').returns({
761-
expiration: sinon.stub(),
762-
multiplebackenddata: {
763-
deleteobject: sinon.stub(),
764-
deleteobjecttagging: sinon.stub(),
765-
abortmpu: sinon.stub(),
766-
},
767-
});
768-
769-
sinon.stub(backbeatRoutes, 'GET').returns({
770-
metadata: sinon.stub(),
771-
multiplebackendmetadata: sinon.stub(),
772-
lifecycle: sinon.stub(),
773-
index: sinon.stub(),
774-
});
740+
// create a Promise that resolves when response.end is called
741+
endPromise = new Promise(resolve => { resolveEnd = resolve; });
775742

776743
request = new DummyRequest(
777744
{
@@ -784,7 +751,10 @@ describe('routeBackbeat authorization', () => {
784751
response = {
785752
setHeader: sinon.stub(),
786753
writeHead: sinon.stub(),
787-
end: sinon.stub(),
754+
end: sinon.stub().callsFake((body, encoding, callback) => {
755+
resolveEnd();
756+
callback();
757+
})
788758
};
789759
});
790760

@@ -953,74 +923,117 @@ describe('routeBackbeat authorization', () => {
953923
expect: errors.NotImplemented,
954924
}
955925
].forEach(testCase => {
956-
it(`should call method ${testCase.method} ${testCase.resourceType}`, done => {
957-
let hasQuery = false;
926+
describe(`${testCase.method} ${testCase.resourceType}`, () => {
958927
let versionIdParsed = null;
959-
request.method = testCase.method;
960-
request.url = `/_/backbeat/${testCase.resourceType}/${testCase.target}`;
961-
if (testCase.operation) {
962-
request.url += `?operation=${testCase.operation}`;
963-
hasQuery = true;
964-
}
965-
966-
// Mock auth server to ignore auth in this test
967-
sinon.stub(auth.server, 'doAuth').callsFake((req, log, cb) =>
968-
cb(null, new AuthInfo({
928+
let hasQuery = false;
929+
930+
beforeEach(done => {
931+
hasQuery = false;
932+
versionIdParsed = null;
933+
request.method = testCase.method;
934+
request.url = `/_/backbeat/${testCase.resourceType}/${testCase.target}`;
935+
if (testCase.operation) {
936+
request.url += `?operation=${testCase.operation}`;
937+
hasQuery = true;
938+
}
939+
940+
const enableVersioningRequest =
941+
versioningTestUtils.createBucketPutVersioningReq(bucketName, 'Enabled');
942+
943+
return async.series([
944+
next => bucketPut(authInfo, testBucket, log, next),
945+
next => bucketPutVersioning(authInfo, enableVersioningRequest, log, next),
946+
next => objectPut(authInfo, testObject, undefined, log, (err, res) => {
947+
if (!err && res) {
948+
versionIdParsed = res['x-amz-version-id'];
949+
if (testCase.versionId) {
950+
request.url += `${(hasQuery ? '&' : '?')}&versionId=${versionIdParsed}`;
951+
}
952+
}
953+
next(err);
954+
}),
955+
], done);
956+
});
957+
958+
afterEach(done => {
959+
async.series([
960+
next => {
961+
const deleteRequest = {
962+
bucketName,
963+
objectKey: objectName,
964+
headers: {},
965+
query: versionIdParsed ? { versionId: versionIdParsed } : {},
966+
};
967+
objectDelete(authInfo, deleteRequest, log, next);
968+
},
969+
next => {
970+
bucketDelete(authInfo, testBucket, log, next);
971+
}
972+
], done);
973+
});
974+
975+
it('should call method successfully', async () => {
976+
// Mock auth server to ignore auth in this test
977+
sinon.stub(auth.server, 'doAuth').yields(null, new AuthInfo({
969978
canonicalID: 'abcdef/lifecycle',
970979
accountDisplayName: 'Lifecycle Service Account',
971980
}), undefined, undefined, {
972981
accountQuota: 1000,
973-
})
974-
);
982+
});
975983

976-
const enableVersioningRequest =
977-
versioningTestUtils.createBucketPutVersioningReq(bucketName, 'Enabled');
984+
routeBackbeat('127.0.0.1', request, response, log);
985+
986+
void await endPromise;
978987

979-
response.end.callsFake((body, format, cb) => {
980988
if (testCase.expect) {
981989
const errCode = response.writeHead.getCall(0).args[0];
982990
assert.strictEqual(errCode, testCase.expect.code);
983-
cb();
984-
return done();
985991
}
986992
assert.strictEqual(Array.isArray(request.finalizerHooks), true);
987993
assert.strictEqual(request.apiMethods[0], 'objectReplicate');
988994
assert.strictEqual(request.apiMethods.length, 1);
989995
assert.strictEqual(request.accountQuotas, 1000);
990-
cb();
991-
return done();
992996
});
993997

994-
return async.series([
995-
next => bucketPut(authInfo, testBucket, log, next),
996-
next => bucketPutVersioning(authInfo, enableVersioningRequest, log, next),
997-
next => objectPut(authInfo, testObject, undefined, log, (err, res) => {
998-
versionIdParsed = res['x-amz-version-id'];
999-
if (testCase.versionId) {
1000-
request.url += `${(hasQuery ? '&' : '?')}&versionId=${versionIdParsed}`;
1001-
}
1002-
next(err);
1003-
}),
1004-
next => routeBackbeat('127.0.0.1', request, response, log, next),
1005-
], err => {
1006-
assert.ifError(err);
998+
it('should return access denied user is not authorized', async () => {
999+
sinon.stub(auth.server, 'doAuth').yields(null, new AuthInfo({
1000+
canonicalID: '123456789',
1001+
accountDisplayName: 'user1',
1002+
}), [{
1003+
isAllowed: false,
1004+
implicitDeny: true,
1005+
action: 'objectReplicate',
1006+
}], undefined, undefined);
1007+
1008+
routeBackbeat('127.0.0.1', request, response, log);
1009+
1010+
void await endPromise;
1011+
1012+
const err = JSON.parse(response.end.getCall(0).args[0]);
1013+
assert.strictEqual(err.code, 'AccessDenied');
10071014
});
1008-
});
1009-
});
10101015

1011-
// Although the authz result is by default an implicit deny, the
1012-
// ACL should prevent any further processing for non-service or
1013-
// non-account identities.
1014-
it('should return access denied if doAuth returns an error', done => {
1015-
request.method = 'PUT';
1016-
request.url = `/_/backbeat/metadata/${bucketName}/${objectName}?operation=putobject`;
1017-
response.end.callsFake((body, format, cb) => {
1018-
const err = JSON.parse(response.end.getCall(0).args[0]);
1019-
assert.strictEqual(err.code, 'AccessDenied');
1020-
cb();
1021-
return done();
1022-
});
1016+
it('should bypass policy evaluation', async () => {
1017+
sinon.stub(auth.server, 'doAuth').yields(null, new AuthInfo({
1018+
canonicalID: 'abcdef/lifecycle',
1019+
accountDisplayName: 'Lifecycle Service Account',
1020+
}), [{
1021+
isAllowed: false,
1022+
implicitDeny: true,
1023+
action: 'objectReplicate',
1024+
}], undefined, undefined);
10231025

1024-
routeBackbeat('127.0.0.1', request, response, log);
1026+
request.bypassUserBucketPolicies = true;
1027+
1028+
routeBackbeat('127.0.0.1', request, response, log);
1029+
1030+
void await endPromise;
1031+
1032+
if (testCase.expect) {
1033+
const errCode = response.writeHead.getCall(0).args[0];
1034+
assert.strictEqual(errCode, testCase.expect.code);
1035+
}
1036+
});
1037+
});
10251038
});
10261039
});

0 commit comments

Comments
 (0)