first commit

This commit is contained in:
2023-05-19 00:42:48 +08:00
commit 53de9c6c51
243 changed files with 39485 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
'use strict';
require('../helper');
var ApikeyAuth = require('../../app/auth/apikey');
var assert = require('assert');
describe.skip('has credentials', function() {
var noCredentialsRequests = [
{
des: 'there is not api_key/map_key in the request query',
req: {query:{}}
},
{
des: 'api_key is undefined`ish in the request query',
req: {query:{api_key:null}}
},
{
des: 'map_key is undefined`ish in the request query',
req: {query:{map_key:null}}
},
{
des: 'there is not api_key/map_key in the request body',
req: {query:{}, body:{}}
},
{
des: 'api_key is undefined`ish in the request body',
req: {query:{}, body:{api_key:null}}
},
{
des: 'map_key is undefined`ish in the request body',
req: {query:{}, body:{map_key:null}}
}
];
noCredentialsRequests.forEach(function(request) {
it('has no credentials if ' + request.des, function() {
testCredentials(request.req, false);
});
});
var credentialsRequests = [
{
des: 'there is api_key in the request query',
req: {query:{api_key: 'foo'}}
},
{
des: 'there is api_key in the request query',
req: {query:{map_key: 'foo'}}
},
{
des: 'there is api_key in the request body',
req: {query:{}, body:{api_key:'foo'}}
},
{
des: 'there is map_key in the request body',
req: {query:{}, body:{map_key:'foo'}}
}
];
credentialsRequests.forEach(function(request) {
it('has credentials if ' + request.des, function() {
testCredentials(request.req, true);
});
});
function testCredentials(req, hasCredentials) {
var apiKeyAuth = new ApikeyAuth(req);
assert.equal(apiKeyAuth.hasCredentials(), hasCredentials);
}
});
describe.skip('verifyCredentials', function() {
it('callbacks with true value when request api_key is the same', function(done) {
testVerifyCredentials({query:{api_key: 'foo'}}, {apiKey: 'foo'}, true, done);
});
it('callbacks with false value when request api_key is different', function(done) {
testVerifyCredentials({query:{api_key: 'foo'}}, {apiKey: 'bar'}, false, done);
});
function testVerifyCredentials(req, options, shouldBeValid, done) {
var apiKeyAuth = new ApikeyAuth(req);
apiKeyAuth.verifyCredentials(options, function(err, validCredentials) {
assert.equal(validCredentials, shouldBeValid);
done();
});
}
});

View File

@@ -0,0 +1,39 @@
'use strict';
var Channel = require('../../../batch/pubsub/channel');
var JobPublisher = require('../../../batch/pubsub/job-publisher');
var assert = require('assert');
describe('batch API job publisher', function () {
beforeEach(function () {
var self = this;
this.host = 'irrelevantHost';
this.redis = {
createClient: function () {
return this;
},
publish: function () {
var isValidFirstArg = arguments[0] === Channel.NAME;
var isValidSecondArg = arguments[1] === self.host;
self.redis.publishIsCalledWithValidArgs = isValidFirstArg && isValidSecondArg;
},
on: function () {},
ping: function (cb) {
cb();
}
};
this.pool = {
acquire: function (db, cb) {
cb(null, self.redis);
}
};
this.jobPublisher = new JobPublisher(this.pool);
});
it('.publish() should publish new messages', function () {
this.jobPublisher.publish(this.host);
assert.ok(this.redis.publishIsCalledWithValidArgs);
});
});

View File

@@ -0,0 +1,49 @@
'use strict';
var JobQueue = require('../../../batch/job_queue');
var assert = require('assert');
describe('batch API job queue', function () {
beforeEach(function () {
this.metadataBackend = {
redisCmd: function () {
var callback = arguments[arguments.length -1];
process.nextTick(function () {
callback(null, 'irrelevantJob');
});
},
redisMultiCmd: function () {
var callback = arguments[arguments.length -1];
process.nextTick(function () {
callback(null, 'irrelevantJob');
});
}
};
this.jobPublisher = {
publish: function () {}
};
this.jobQueue = new JobQueue(this.metadataBackend, this.jobPublisher);
});
it('.enqueue() should enqueue the provided job', function (done) {
this.jobQueue.enqueue('irrelevantJob', 'irrelevantHost', function (err) {
assert.ok(!err);
done();
});
});
it('.dequeue() should dequeue the next job', function (done) {
this.jobQueue.dequeue('irrelevantHost', function (err) {
assert.ok(!err);
done();
});
});
it('.enqueueFirst() should dequeue the next job', function (done) {
this.jobQueue.enqueueFirst('irrelevantJob', 'irrelevantHost', function (err) {
assert.ok(!err);
done();
});
});
});

View File

@@ -0,0 +1,71 @@
'use strict';
var Channel = require('../../../batch/pubsub/channel');
var JobSubscriber = require('../../../batch/pubsub/job-subscriber');
var assert = require('assert');
describe('batch API job subscriber', function () {
beforeEach(function () {
var self = this;
this.onMessageListener = function () {};
this.redis = {
createClient: function () {
return this;
},
subscribe: function () {
var isValidFirstArg = arguments[0] === Channel.NAME;
self.redis.subscribeIsCalledWithValidArgs = isValidFirstArg;
},
on: function () {
if (arguments[0] === 'message') {
self.redis.onIsCalledWithValidArgs = true;
}
},
unsubscribe: function () {
var isValidFirstArg = arguments[0] === Channel.NAME;
self.redis.unsubscribeIsCalledWithValidArgs = isValidFirstArg;
},
scan: function(params, callback) {
return callback(null, ['0']);
},
removeAllListeners: function () {
return this;
},
smembers: function (key, callback) {
callback(null, []);
},
connected: true,
};
this.pool = {
acquire: function (db, cb) {
cb(null, self.redis);
},
release: function(/*db, client*/) {
}
};
this.queueSeeker = {
seek: function () {
var callback = arguments[1];
callback(null, []);
}
};
this.jobSubscriber = new JobSubscriber(this.pool, this.queueSeeker);
});
it('.subscribe() should listen for incoming messages', function () {
this.jobSubscriber.subscribe(this.onMessageListener);
assert.ok(this.redis.onIsCalledWithValidArgs);
assert.ok(this.redis.subscribeIsCalledWithValidArgs);
});
it('.unsubscribe() should stop listening for incoming messages', function () {
this.jobSubscriber.subscribe(this.onMessageListener);
this.jobSubscriber.unsubscribe();
assert.ok(this.redis.unsubscribeIsCalledWithValidArgs);
});
});

View File

@@ -0,0 +1,143 @@
'use strict';
var assert = require('assert');
var errorMiddleware = require('../../app/middlewares/error');
require('../helper');
const req = { query: { callback: true } };
const getRes = () => {
return {
headers: {},
set (key, value) {
this.headers[key] = value;
},
header (key, value) {
this.set(key, value);
},
statusCode: 0,
status (status) {
this.statusCode = status;
},
json () {},
jsonp () {}
};
};
const getErrorHeader = (context, detail, hint, message) => {
return {
context,
detail,
hint,
statusCode: 400,
message
};
};
describe('error-handler', function() {
it('should return a header with errors', function (done) {
let error = new Error('error test');
error.detail = 'test detail';
error.hint = 'test hint';
error.context = 'test context';
const errorHeader = getErrorHeader(
error.context,
error.detail,
error.hint,
error.message
);
const res = getRes();
errorMiddleware()(error, req, res, function next () {
assert.ok(res.headers['X-SQLAPI-Errors'].length > 0);
assert.deepEqual(
res.headers['X-SQLAPI-Errors'],
JSON.stringify(errorHeader)
);
done();
});
});
it('JSONP should return a header with error statuscode', function (done) {
let error = new Error('error test');
error.detail = 'test detail';
error.hint = 'test hint';
error.context = 'test context';
const errorHeader = getErrorHeader(
error.context,
error.detail,
error.hint,
error.message
);
const res = getRes();
errorMiddleware()(error, req, res, function next () {
assert.ok(res.headers['X-SQLAPI-Errors'].length > 0);
assert.deepEqual(
res.headers['X-SQLAPI-Errors'],
JSON.stringify(errorHeader)
);
done();
});
});
it('should escape chars that broke logs regex', function (done) {
const badString = 'error: ( ) = " \" \' * $ & |';
const escapedString = 'error ';
let error = new Error(badString);
error.detail = badString;
error.hint = badString;
error.context = badString;
const errorHeader = getErrorHeader(
escapedString,
escapedString,
escapedString,
escapedString
);
const res = getRes();
errorMiddleware()(error, req, res, function () {
assert.ok(res.headers['X-SQLAPI-Errors'].length > 0);
assert.deepEqual(
res.headers['X-SQLAPI-Errors'],
JSON.stringify(errorHeader)
);
done();
});
});
it('should truncat too long error messages', function (done) {
const veryLongString = 'Very long error message '.repeat(1000);
const truncatedString = veryLongString.substring(0, 1024);
let error = new Error(veryLongString);
const expectedErrorHeader = {
statusCode: 400,
message: truncatedString
};
const res = getRes();
errorMiddleware()(error, req, res, function () {
assert.ok(res.headers['X-SQLAPI-Errors'].length > 0);
assert.deepEqual(
res.headers['X-SQLAPI-Errors'],
JSON.stringify(expectedErrorHeader)
);
done();
});
});
});

View File

@@ -0,0 +1,71 @@
'use strict';
const assert = require('assert');
const errorHandlerFactory = require('../../app/services/error_handler_factory');
const ErrorHandler = require('../../app/services/error_handler');
const { codeToCondition } = require('../../app/postgresql/error_codes');
let rateLimitError = new Error(
'You are over platform\'s limits. Please contact us to know more details'
);
rateLimitError.http_status = 429;
rateLimitError.context = 'limit';
rateLimitError.detail = 'rate-limit';
const cases = [
{
title: 'postgres error',
error: new Error(codeToCondition['02000'])
},
{
title: 'rate limit error',
error: rateLimitError
}
];
describe('error-handler-factory', function () {
cases.forEach(({ title, error }) => {
it(title, function () {
const errorHandler = errorHandlerFactory(error);
const expectedError = new ErrorHandler({
message: error.message,
context: error.context,
detail: error.detail,
hint: error.hint,
http_status: error.http_status,
name: codeToCondition[error.code] || error.name
});
assert.deepEqual(errorHandler, expectedError);
});
});
it('timeout error', function() {
const error = new Error('statement timeout');
const errorHandler = errorHandlerFactory(error);
const expectedError = new ErrorHandler({
message: 'You are over platform\'s limits: SQL query timeout error.' +
' Refactor your query before running again or contact CARTO support for more details.',
context: 'limit',
detail: 'datasource',
http_status: 429
});
assert.deepEqual(errorHandler, expectedError);
});
it('permission denied error', function() {
const error = new Error('permission denied');
const errorHandler = errorHandlerFactory(error);
const expectedError = new ErrorHandler({
message: error.message,
context: error.context,
detail: error.detail,
hint: error.hint,
http_status: 403,
name: codeToCondition[error.code] || error.name
});
assert.deepEqual(errorHandler, expectedError);
});
});

47
test/unit/health_check.js Normal file
View File

@@ -0,0 +1,47 @@
'use strict';
require('../helper');
var assert = require('assert');
var HealthCheck = require('../../app/monitoring/health_check');
var metadataBackend = {};
function PSQL(dbParams) {
this.params = dbParams;
}
var healthCheck = new HealthCheck(metadataBackend, PSQL);
describe('health checks', function() {
it('errors if disabled file exists', function(done) {
var fs = require('fs');
var readFileFn = fs.readFile;
fs.readFile = function(filename, callback) {
callback(null, "Maintenance");
};
healthCheck.check(function(err) {
assert.equal(err.message, "Maintenance");
assert.equal(err.http_status, 503);
fs.readFile = readFileFn;
done();
});
});
it('does not err if disabled file does not exists', function(done) {
var fs = require('fs');
var readFileFn = fs.readFile;
fs.readFile = function(filename, callback) {
callback(new Error("ENOENT"), null);
};
healthCheck.check(function(err) {
assert.equal(err, null);
fs.readFile = readFileFn;
done();
});
});
});

View File

@@ -0,0 +1,76 @@
'use strict';
require('../../helper');
var assert = require('assert');
var ArrayBufferSer = require('../../../app/models/bin_encoder');
describe('ArrayBufferSer', function() {
it('calculate size for basic types', function() {
var b = new ArrayBufferSer(ArrayBufferSer.INT16, [1,2,3,4]);
assert.equal(4*2, b.getDataSize());
b = new ArrayBufferSer(ArrayBufferSer.INT8, [1,2,3,4]);
assert.equal(4, b.getDataSize());
b = new ArrayBufferSer(ArrayBufferSer.INT32, [1,2,3,4]);
assert.equal(4*4, b.getDataSize());
});
it('calculate size for arrays', function() {
var b = new ArrayBufferSer(ArrayBufferSer.STRING, ["test","kease"]);
assert.equal((b.headerSize + 4 + 5)*2, b.getDataSize());
var ba = new ArrayBufferSer(ArrayBufferSer.INT16, [1,2,3,4]);
var bc = new ArrayBufferSer(ArrayBufferSer.INT16, [1,4]);
b = new ArrayBufferSer(ArrayBufferSer.BUFFER, [ba, bc]);
assert.equal((b.headerSize + 4 + 2)*2, b.getDataSize());
assert.equal(b.type, ArrayBufferSer.BUFFER);
});
function assert_buffer_equals(a, b) {
assert.equal(a.length, b.length);
for(var i = 0; i < a.length; ++i) {
assert.equal(a[i], b[i], "byte i " + i + " is different: " + a[i] + " != " + b[i]);
}
}
it('binary data is ok', function() {
var b = new ArrayBufferSer(ArrayBufferSer.INT16, [1,2,3,4]);
var bf = new Buffer([0, 0, 0, ArrayBufferSer.INT16, 0, 0, 0, 8, 1, 0, 2, 0, 3, 0, 4, 0]);
assert_buffer_equals(bf, b.buffer);
});
it('binary data is ok with arrays', function() {
var ba = new ArrayBufferSer(ArrayBufferSer.INT16, [1,2, 3, 4]);
var bc = new ArrayBufferSer(ArrayBufferSer.INT16, [1,4]);
var b = new ArrayBufferSer(ArrayBufferSer.BUFFER, [ba, bc]);
var bf = new Buffer([
0, 0, 0, ArrayBufferSer.BUFFER, // type
0, 0, 0, 28,
0, 0, 0, ArrayBufferSer.INT16, 0, 0, 0, 8, 1, 0, 2, 0, 3, 0, 4, 0,
0, 0, 0, ArrayBufferSer.INT16, 0, 0, 0, 4, 1, 0, 4, 0]);
assert_buffer_equals(bf, b.buffer);
});
it('binary data is ok with strings', function() {
var s = 'test';
var b = new ArrayBufferSer(ArrayBufferSer.STRING, [s]);
var bf = new Buffer([
0, 0, 0, ArrayBufferSer.STRING, // type
0, 0, 0, 16,
0, 0, 0, ArrayBufferSer.UINT16,
0, 0, 0, 8,
s.charCodeAt(0), 0,
s.charCodeAt(1), 0,
s.charCodeAt(2), 0,
s.charCodeAt(3), 0
]);
assert_buffer_equals(bf, b.buffer);
});
});

176
test/unit/oauth.test.js Normal file
View File

@@ -0,0 +1,176 @@
'use strict';
require('../helper');
var _ = require('underscore');
var OAuthAuth = require('../../app/auth/oauth');
var MetadataDB = require('cartodb-redis');
var oAuth = require('../../app/auth/oauth').backend;
var assert = require('assert');
var oauth_data_1 = {
oauth_consumer_key: "dpf43f3p2l4k3l03",
oauth_token: "nnch734d00sl2jdk",
oauth_signature_method: "HMAC-SHA1",
oauth_signature: "tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D",
oauth_timestamp:"1191242096",
oauth_nonce:"kllo9940pd9333jh"
};
var oauth_data_2 = { oauth_version:"1.0" };
var oauth_data = _.extend(oauth_data_1, oauth_data_2);
var real_oauth_header = 'OAuth ' +
'realm="http://vizzuality.testhost.lan/",' +
'oauth_consumer_key="fZeNGv5iYayvItgDYHUbot1Ukb5rVyX6QAg8GaY2",' +
'oauth_token="l0lPbtP68ao8NfStCiA3V3neqfM03JKhToxhUQTR",' +
'oauth_signature_method="HMAC-SHA1", ' +
'oauth_signature="o4hx4hWP6KtLyFwggnYB4yPK8xI%3D",' +
'oauth_timestamp="1313581372",' +
'oauth_nonce="W0zUmvyC4eVL8cBd4YwlH1nnPTbxW0QBYcWkXTwe4",' +
'oauth_version="1.0"';
var oauth_header_tokens = 'oauth_consumer_key="dpf43f3p2l4k3l03",' +
'oauth_token="nnch734d00sl2jdk",' +
'oauth_signature_method="HMAC-SHA1", ' +
'oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D",' +
'oauth_timestamp="1191242096",' +
'oauth_nonce="kllo9940pd9333jh",' +
'oauth_version="1.0"';
var full_oauth_header = 'OAuth realm="http://photos.example.net/"' + oauth_header_tokens;
var metadataBackend = new MetadataDB({
host: global.settings.redis_host,
port: global.settings.redis_port,
max: global.settings.redisPool,
idleTimeoutMillis: global.settings.redisIdleTimeoutMillis,
reapIntervalMillis: global.settings.redisReapIntervalMillis
});
describe('oauth', function() {
it('test database number', function(){
assert.equal(oAuth.oauth_database, 3);
});
it('test oauth database key', function(){
assert.equal(oAuth.oauth_user_key, "rails:oauth_access_tokens:<%= oauth_access_key %>");
});
it('test parse tokens from full headers does not raise exception', function(){
var req = {query:{}, headers:{authorization:full_oauth_header}};
assert.doesNotThrow(function(){ oAuth.parseTokens(req); }, /incomplete oauth tokens in request/);
});
it('test parse all normal tokens raises no exception', function(){
var req = {query:oauth_data, headers:{}};
assert.doesNotThrow(function(){ oAuth.parseTokens(req); }, /incomplete oauth tokens in request/);
});
it('test headers take presedence over query parameters', function(){
var req = {query:{oauth_signature_method: "MY_HASH"}, headers:{authorization:full_oauth_header}};
var tokens = oAuth.parseTokens(req);
assert.equal(tokens.oauth_signature_method, "HMAC-SHA1");
});
it('test can access oauth hash for a user based on access token (oauth_token)', function(done){
var req = {query:{}, headers:{authorization:real_oauth_header}};
var tokens = oAuth.parseTokens(req);
oAuth.getOAuthHash(metadataBackend, tokens.oauth_token, function(err, data){
assert.equal(tokens.oauth_consumer_key, data.consumer_key);
done();
});
});
it('test non existant oauth hash for a user based on oauth_token returns empty hash', function(done){
var req = {query:{}, params: { user: 'vizzuality' }, headers:{authorization:full_oauth_header}};
var tokens = oAuth.parseTokens(req);
oAuth.getOAuthHash(metadataBackend, tokens.oauth_token, function(err, data){
assert.ok(!err, err);
assert.deepEqual(data, {});
done();
});
});
it('can return user for verified signature', function(done){
var req = {query:{},
headers:{authorization:real_oauth_header, host: 'vizzuality.testhost.lan' },
params: { user: 'vizzuality' },
protocol: 'http',
method: 'GET',
path: '/api/v1/tables'
};
oAuth.verifyRequest(req, metadataBackend, function(err, data){
assert.ok(!err, err);
assert.equal(data, 'master');
done();
});
});
it('can return user for verified signature (for other allowed domains)', function(done){
var oAuthGetAllowedHostsFn = oAuth.getAllowedHosts;
oAuth.getAllowedHosts = function() {
return ['testhost.lan', 'testhostdb.lan'];
};
var req = {query:{},
headers:{authorization:real_oauth_header, host: 'vizzuality.testhostdb.lan' },
params: { user: 'vizzuality' },
protocol: 'http',
method: 'GET',
path: '/api/v1/tables'
};
oAuth.verifyRequest(req, metadataBackend, function(err, data){
oAuth.getAllowedHosts = oAuthGetAllowedHostsFn;
assert.ok(!err, err);
assert.equal(data, 'master');
done();
});
});
it('returns null user for unverified signatures', function(done){
var req = {query:{},
headers:{authorization:real_oauth_header, host: 'vizzuality.testyhost.lan' },
params: { user: 'vizzuality' },
protocol: 'http',
method: 'GET',
path: '/api/v1/tables'
};
oAuth.verifyRequest(req, metadataBackend, function(err, data){
assert.equal(data, null);
done();
});
});
it('returns null user for no oauth', function(done){
var req = {
query:{},
headers:{},
params: { user: 'vizzuality' },
protocol: 'http',
method: 'GET',
path: '/api/v1/tables'
};
oAuth.verifyRequest(req, metadataBackend, function(err,data){
assert.equal(data, null);
done();
});
});
it('OAuthAuth reports it has credentials', function(done) {
var req = {query:{}, headers:{authorization:real_oauth_header}};
var oAuthAuth = new OAuthAuth(req);
assert.ok(oAuthAuth.hasCredentials());
done();
});
it('OAuthAuth reports it has no credentials', function(done) {
var req = {query:{}, headers:{}};
var oAuthAuth = new OAuthAuth(req);
assert.equal(oAuthAuth.hasCredentials(), false);
done();
});
});

View File

@@ -0,0 +1,175 @@
'use strict';
const assert = require('assert');
const pgEntitiesAccessValidator = require('../../app/services/pg-entities-access-validator');
const fakeAffectedTables = [{
schema_name: 'schema',
table_name: 'untitled_table'
}];
const fakeAffectedTablesCarto = [{
schema_name: 'carto',
table_name: 'untitled_table'
}];
const fakeAffectedTablesCartodbOK = [{
schema_name: 'cartodb',
table_name: 'untitled_table'
}];
const fakeAffectedTablesCartodbKO = [
{
schema_name: 'cartodb',
table_name: 'untitled_table'
},
{
schema_name: 'cartodb',
table_name: 'cdb_tablemetadata'
}
];
const fakeAffectedTablesPgcatalog = [{
schema_name: 'pg_catalog',
table_name: 'pg_catalog'
}];
const fakeAffectedTablesInfo = [{
schema_name: 'information_schema',
table_name: 'untitled_table'
}];
const fakeAffectedTablesPublicOK = [{
schema_name: 'public',
table_name: 'untitled_table'
}];
const fakeAffectedTablesPublicKO = [
{
schema_name: 'public',
table_name: 'spatial_ref_sys'
},
{
schema_name: 'public',
table_name: 'untitled_table'
}
];
const fakeAffectedTablesTopologyOK = [{
schema_name: 'topology',
table_name: 'untitled_table'
}];
const fakeAffectedTablesTopologyKO = [
{
schema_name: 'topology',
table_name: 'layer'
},
{
schema_name: 'topology',
table_name: 'untitled_table'
}
];
describe('pg entities access validator with validatePGEntitiesAccess enabled', function () {
before(function() {
global.settings.validatePGEntitiesAccess = true;
});
after(function() {
global.settings.validatePGEntitiesAccess = false;
});
it('validate function: bad parameters', function () {
assert.strictEqual(pgEntitiesAccessValidator.validate(), true);
assert.strictEqual(pgEntitiesAccessValidator.validate(null), true);
assert.strictEqual(pgEntitiesAccessValidator.validate(null, null), true);
assert.strictEqual(pgEntitiesAccessValidator.validate([]), true);
assert.strictEqual(pgEntitiesAccessValidator.validate([], 3), true);
assert.strictEqual(pgEntitiesAccessValidator.validate({ tables: [] }, false), true);
});
it('validate function: should be validated', function () {
assert.strictEqual(pgEntitiesAccessValidator.validate({ tables: fakeAffectedTables }), true);
assert.strictEqual(pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesCartodbOK }), true);
assert.strictEqual(pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesPublicOK }), true);
assert.strictEqual(pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesTopologyOK }), true);
});
it('validate function: should not be validated', function () {
let authorizationLevel = 'master';
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesCarto }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesCartodbKO }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesPgcatalog }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesInfo }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesPublicKO }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesTopologyKO }, authorizationLevel),
false
);
authorizationLevel = 'regular';
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesCarto }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesCartodbKO }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesPgcatalog }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesInfo }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesPublicKO }, authorizationLevel),
false
);
assert.strictEqual(
pgEntitiesAccessValidator.validate({ tables: fakeAffectedTablesTopologyKO }, authorizationLevel),
false
);
});
it('hardValidation function', function () {
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTables), true);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesCartodbOK), true);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesPublicOK), true);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesTopologyOK), true);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesCarto), false);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesCartodbKO), false);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesPgcatalog), false);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesInfo), false);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesPublicKO), false);
assert.strictEqual(pgEntitiesAccessValidator.hardValidation(fakeAffectedTablesTopologyKO), false);
});
it('softValidation function', function () {
assert.strictEqual(pgEntitiesAccessValidator.softValidation(fakeAffectedTablesCartodbKO), true);
assert.strictEqual(pgEntitiesAccessValidator.softValidation(fakeAffectedTablesPgcatalog), false);
});
});

View File

@@ -0,0 +1,66 @@
'use strict';
const assert = require('assert');
const queryInfo = require('../../app/utils/query_info');
describe('query info', function () {
describe('copy format', function () {
describe('csv', function () {
const validQueries = [
"COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT CSV, DELIMITER ',', HEADER true)",
"COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT CSV, DELIMITER ',', HEADER true)",
"COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT CSV , DELIMITER ',', HEADER true)",
"COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT CSV)",
"COPY copy_endpoints_test FROM STDIN WITH(FORMAT csv,HEADER true)"
];
validQueries.forEach(query => {
it(query, function() {
const result = queryInfo.getFormatFromCopyQuery(query);
assert.equal(result, 'CSV');
});
});
});
describe('text', function() {
const validQueries = [
"COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT TEXT)",
"COPY copy_endpoints_test (id, name) FROM STDIN",
];
validQueries.forEach(query => {
it(query, function() {
const result = queryInfo.getFormatFromCopyQuery(query);
assert.equal(result, 'TEXT');
});
});
});
describe('binary', function() {
const validQueries = [
"COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT BINARY)",
];
validQueries.forEach(query => {
it(query, function() {
const result = queryInfo.getFormatFromCopyQuery(query);
assert.equal(result, 'BINARY');
});
});
});
describe('should fail', function() {
const validQueries = [
"COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT ERROR)",
"SELECT * from copy_endpoints_test"
];
validQueries.forEach(query => {
it(query, function() {
const result = queryInfo.getFormatFromCopyQuery(query);
assert.strictEqual(result, false);
});
});
});
});
});