mirror of https://gitee.com/bigwinds/arangodb
296 lines
8.9 KiB
JavaScript
296 lines
8.9 KiB
JavaScript
/* jshint globalstrict:true, strict:true, maxlen: 5000 */
|
|
/* global assertTrue, assertFalse, assertEqual, require*/
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2018 ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// @author Dan Larkin-York
|
|
/// @author Copyright 2018, ArangoDB GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
'use strict';
|
|
|
|
const jsunity = require("jsunity");
|
|
|
|
const base64Encode = require('internal').base64Encode;
|
|
const db = require("internal").db;
|
|
const request = require("@arangodb/request");
|
|
const url = require('url');
|
|
const userModule = require("@arangodb/users");
|
|
const _ = require("lodash");
|
|
|
|
|
|
function getCoordinators() {
|
|
const isCoordinator = (d) => (_.toLower(d.role) === 'coordinator');
|
|
const toEndpoint = (d) => (d.endpoint);
|
|
const endpointToURL = (endpoint) => {
|
|
if (endpoint.substr(0, 6) === 'ssl://') {
|
|
return 'https://' + endpoint.substr(6);
|
|
}
|
|
var pos = endpoint.indexOf('://');
|
|
if (pos === -1) {
|
|
return 'http://' + endpoint;
|
|
}
|
|
return 'http' + endpoint.substr(pos);
|
|
};
|
|
|
|
const instanceInfo = JSON.parse(require('internal').env.INSTANCEINFO);
|
|
return instanceInfo.arangods.filter(isCoordinator)
|
|
.map(toEndpoint)
|
|
.map(endpointToURL);
|
|
}
|
|
|
|
const servers = getCoordinators();
|
|
|
|
function CursorSyncAuthSuite () {
|
|
'use strict';
|
|
const cns = ["animals", "fruits"];
|
|
const keys = [
|
|
["ant", "bird", "cat", "dog"],
|
|
["apple", "banana", "coconut", "date"]
|
|
];
|
|
let cs = [];
|
|
let coordinators = [];
|
|
const users = [
|
|
{ username: 'alice', password: 'pass1' },
|
|
{ username: 'bob', password: 'pass2' },
|
|
];
|
|
const baseCursorUrl = `/_api/cursor`;
|
|
|
|
function sendRequest(auth, method, endpoint, body, usePrimary) {
|
|
let res;
|
|
const i = usePrimary ? 0 : 1;
|
|
|
|
try {
|
|
const envelope = {
|
|
body,
|
|
headers: {
|
|
authorization:
|
|
`Basic ${base64Encode(auth.username + ':' + auth.password)}`
|
|
},
|
|
json: true,
|
|
method,
|
|
url: `${coordinators[i]}${endpoint}`
|
|
};
|
|
res = request(envelope);
|
|
} catch(err) {
|
|
console.error(`Exception processing ${method} ${endpoint}`, err.stack);
|
|
return {};
|
|
}
|
|
|
|
var resultBody = res.body;
|
|
if (typeof resultBody === "string") {
|
|
resultBody = JSON.parse(resultBody);
|
|
}
|
|
return resultBody;
|
|
}
|
|
|
|
return {
|
|
setUp: function() {
|
|
coordinators = getCoordinators();
|
|
if (coordinators.length < 2) {
|
|
throw new Error('Expecting at least two coordinators');
|
|
}
|
|
|
|
cs = [];
|
|
for (let i = 0; i < cns.length; i++) {
|
|
db._drop(cns[i]);
|
|
cs.push(db._create(cns[i]));
|
|
assertTrue(cs[i].name() === cns[i]);
|
|
for (let key in keys[i]) {
|
|
cs[i].save({ _key: key });
|
|
}
|
|
}
|
|
|
|
try {
|
|
userModule.remove(users[0].username);
|
|
userModule.remove(users[1].username);
|
|
} catch (err) {}
|
|
userModule.save(users[0].username, users[0].password);
|
|
userModule.save(users[1].username, users[1].password);
|
|
|
|
userModule.grantDatabase(users[0].username, '_system', 'ro');
|
|
userModule.grantDatabase(users[1].username, '_system', 'ro');
|
|
userModule.grantCollection(users[0].username, '_system', cns[0], 'ro');
|
|
userModule.grantCollection(users[1].username, '_system', cns[0], 'ro');
|
|
userModule.grantCollection(users[0].username, '_system', cns[1], 'ro');
|
|
userModule.grantCollection(users[1].username, '_system', cns[1], 'none');
|
|
|
|
require("internal").wait(2);
|
|
},
|
|
|
|
tearDown: function() {
|
|
db._drop(cns[0]);
|
|
db._drop(cns[1]);
|
|
userModule.remove(users[0].username);
|
|
userModule.remove(users[1].username);
|
|
cs = [];
|
|
coordinators = [];
|
|
},
|
|
|
|
testCursorForwardingSameUserBasic: function() {
|
|
let url = baseCursorUrl;
|
|
const query = {
|
|
query: `FOR doc IN @@coll LIMIT 4 RETURN doc`,
|
|
count: true,
|
|
batchSize: 2,
|
|
bindVars: {
|
|
"@coll": cns[0]
|
|
}
|
|
};
|
|
let result = sendRequest(users[0], 'POST', url, query, true);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 201);
|
|
assertTrue(result.hasMore);
|
|
assertEqual(result.count, 4);
|
|
assertEqual(result.result.length, 2);
|
|
|
|
const cursorId = result.id;
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[0], 'PUT', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 200);
|
|
assertFalse(result.hasMore);
|
|
assertEqual(result.count, 4);
|
|
assertEqual(result.result.length, 2);
|
|
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[0], 'PUT', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertTrue(result.error);
|
|
assertEqual(result.code, 404);
|
|
},
|
|
|
|
testCursorForwardingSameUserDeletion: function() {
|
|
let url = baseCursorUrl;
|
|
const query = {
|
|
query: `FOR doc IN @@coll LIMIT 4 RETURN doc`,
|
|
count: true,
|
|
batchSize: 2,
|
|
bindVars: {
|
|
"@coll": cns[0]
|
|
}
|
|
};
|
|
let result = sendRequest(users[0], 'POST', url, query, true);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 201);
|
|
assertTrue(result.hasMore);
|
|
assertEqual(result.count, 4);
|
|
assertEqual(result.result.length, 2);
|
|
|
|
const cursorId = result.id;
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[0], 'DELETE', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 202);
|
|
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[0], 'PUT', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertTrue(result.error);
|
|
assertEqual(result.code, 404);
|
|
},
|
|
|
|
testCursorForwardingDifferentUser: function() {
|
|
let url = baseCursorUrl;
|
|
const query = {
|
|
query: `FOR doc IN @@coll LIMIT 4 RETURN doc`,
|
|
count: true,
|
|
batchSize: 2,
|
|
bindVars: {
|
|
"@coll": cns[0]
|
|
}
|
|
};
|
|
let result = sendRequest(users[0], 'POST', url, query, true);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 201);
|
|
assertTrue(result.hasMore);
|
|
assertEqual(result.count, 4);
|
|
assertEqual(result.result.length, 2);
|
|
|
|
const cursorId = result.id;
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[1], 'PUT', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertTrue(result.error);
|
|
assertEqual(result.code, 404);
|
|
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[0], 'DELETE', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 202);
|
|
},
|
|
|
|
testCursorForwardingDifferentUserDelete: function() {
|
|
let url = baseCursorUrl;
|
|
const query = {
|
|
query: `FOR doc IN @@coll LIMIT 4 RETURN doc`,
|
|
count: true,
|
|
batchSize: 2,
|
|
bindVars: {
|
|
"@coll": cns[0]
|
|
}
|
|
};
|
|
let result = sendRequest(users[0], 'POST', url, query, true);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 201);
|
|
assertTrue(result.hasMore);
|
|
assertEqual(result.count, 4);
|
|
assertEqual(result.result.length, 2);
|
|
|
|
const cursorId = result.id;
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[1], 'DELETE', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertTrue(result.error);
|
|
assertEqual(result.code, 404);
|
|
|
|
url = `${baseCursorUrl}/${cursorId}`;
|
|
result = sendRequest(users[0], 'DELETE', url, {}, false);
|
|
|
|
assertFalse(result === undefined || result === {});
|
|
assertFalse(result.error);
|
|
assertEqual(result.code, 202);
|
|
},
|
|
|
|
};
|
|
}
|
|
|
|
jsunity.run(CursorSyncAuthSuite);
|
|
|
|
return jsunity.done();
|