Compare commits

...

17 Commits

Author SHA1 Message Date
Raul Ochoa
f136b9f6e7 Release 2.15.1 2015-10-21 13:56:53 +02:00
Raul Ochoa
12175f10a6 Upgrades windshaft to 1.1.1 2015-10-21 13:55:36 +02:00
Raul Ochoa
01bd09040e Stubs next version 2015-10-13 12:44:29 +02:00
Raul Ochoa
ab38e7069a Release 2.15.0 2015-10-13 12:36:25 +02:00
Raul Ochoa
9449642773 Remove soft-purge option when purging fastly 2015-10-09 16:37:17 +02:00
Raul Ochoa
1f489a4537 Fix broken test due fastly-purge upgrade 2015-10-09 16:02:11 +02:00
Raul Ochoa
6effcfb62e Upgrades windshaft to 1.1.0 and fastly-purge to 1.0.1 2015-10-09 15:50:39 +02:00
Raul Ochoa
2cc4cc5deb Stubs next version 2015-09-30 19:26:33 +02:00
Raul Ochoa
4c5630ac43 Release 2.14.1 2015-09-30 18:52:08 +02:00
Raul Ochoa
3181bcc63e Remove app dependency from controllers 2015-09-30 18:00:54 +02:00
Raul Ochoa
bf9cb33d63 Fix tests after upgrading windshaft, which includes a fix for layergroupid 2015-09-30 17:55:17 +02:00
Raul Ochoa
e7aa6bbdf9 Upgrade windshaft 2015-09-30 17:44:40 +02:00
Raul Ochoa
550b73ce23 Update news 2015-09-30 17:41:37 +02:00
Raul Ochoa
ffaa756637 Merge pull request #337 from CartoDB/safe-user-extraction
Safe user extraction
2015-09-30 17:25:12 +02:00
Raul Ochoa
9cd67f06c1 User extraction from request middleware
Used only where potentially a user is required.

It doesn't make sense to extract a user for request that don't need
a user in the context.
2015-09-30 17:17:01 +02:00
Raul Ochoa
79375616d5 Default host to empty string when header is not found
A String object is required to not fail on `.match` interface.
2015-09-30 16:31:56 +02:00
Raul Ochoa
ba6b8fbff1 Stubs next version 2015-09-30 11:28:38 +02:00
15 changed files with 139 additions and 80 deletions

32
NEWS.md
View File

@@ -1,5 +1,37 @@
# Changelog
## 2.15.1
Released 2015-10-21
Announcements:
- Upgrades windshaft to [1.1.1](https://github.com/CartoDB/Windshaft/releases/tag/1.1.1)
## 2.15.0
Released 2015-10-13
Announcements:
- Fastly purging no longer uses soft-purge option
- Upgrades windshaft to [1.1.0](https://github.com/CartoDB/Windshaft/releases/tag/1.1.0)
- Upgrades fastly-purge to [1.0.1](https://github.com/CartoDB/node-fastly-purge/releases/tag/1.0.1)
## 2.14.1
Released 2015-09-30
Enhancements:
- Remove app dependency from controllers
Announcements:
- Upgrades windshaft to [1.0.1](https://github.com/CartoDB/Windshaft/releases/tag/1.0.1)
Improvements:
- Safer user extraction from request Host header
## 2.14.0
Released 2015-09-30

View File

@@ -1,8 +1,8 @@
var FastlyPurge = require('fastly-purge');
function FastlyCacheBackend(apiKey, serviceId, softPurge) {
function FastlyCacheBackend(apiKey, serviceId) {
this.serviceId = serviceId;
this.fastlyPurge = new FastlyPurge(apiKey, { softPurge: softPurge || true });
this.fastlyPurge = new FastlyPurge(apiKey, { softPurge: false });
}
module.exports = FastlyCacheBackend;

View File

@@ -5,12 +5,12 @@ var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
var userMiddleware = require('../middleware/user');
var MapStoreMapConfigProvider = require('../models/mapconfig/map_store_provider');
var TablesCacheEntry = require('../cache/model/database_tables_entry');
/**
* @param app
* @param {AuthApi} authApi
* @param {PgConnection} pgConnection
* @param {MapStore} mapStore
@@ -23,11 +23,10 @@ var TablesCacheEntry = require('../cache/model/database_tables_entry');
* @param {LayergroupAffectedTables} layergroupAffectedTables
* @constructor
*/
function LayergroupController(app, authApi, pgConnection, mapStore, tileBackend, previewBackend, attributesBackend,
function LayergroupController(authApi, pgConnection, mapStore, tileBackend, previewBackend, attributesBackend,
surrogateKeysCache, userLimitsApi, queryTablesApi, layergroupAffectedTables) {
BaseController.call(this, authApi, pgConnection);
this.app = app;
this.mapStore = mapStore;
this.tileBackend = tileBackend;
this.previewBackend = previewBackend;
@@ -44,13 +43,28 @@ module.exports = LayergroupController;
LayergroupController.prototype.register = function(app) {
app.get(app.base_url_mapconfig + '/:token/:z/:x/:y@:scale_factor?x.:format', cors(), this.tile.bind(this));
app.get(app.base_url_mapconfig + '/:token/:z/:x/:y.:format', cors(), this.tile.bind(this));
app.get(app.base_url_mapconfig + '/:token/:layer/:z/:x/:y.(:format)', cors(), this.layer.bind(this));
app.get(app.base_url_mapconfig + '/:token/:layer/attributes/:fid', cors(), this.attributes.bind(this));
app.get(app.base_url_mapconfig + '/static/center/:token/:z/:lat/:lng/:width/:height.:format', cors(),
app.get(app.base_url_mapconfig +
'/:token/:z/:x/:y@:scale_factor?x.:format', cors(), userMiddleware,
this.tile.bind(this));
app.get(app.base_url_mapconfig +
'/:token/:z/:x/:y.:format', cors(), userMiddleware,
this.tile.bind(this));
app.get(app.base_url_mapconfig +
'/:token/:layer/:z/:x/:y.(:format)', cors(), userMiddleware,
this.layer.bind(this));
app.get(app.base_url_mapconfig +
'/:token/:layer/attributes/:fid', cors(), userMiddleware,
this.attributes.bind(this));
app.get(app.base_url_mapconfig +
'/static/center/:token/:z/:lat/:lng/:width/:height.:format', cors(), userMiddleware,
this.center.bind(this));
app.get(app.base_url_mapconfig + '/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format', cors(),
app.get(app.base_url_mapconfig +
'/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format', cors(), userMiddleware,
this.bbox.bind(this));
};

View File

@@ -7,6 +7,7 @@ var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
var userMiddleware = require('../middleware/user');
var MapConfig = windshaft.model.MapConfig;
var Datasource = windshaft.model.Datasource;
@@ -19,7 +20,6 @@ var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider'
var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_layergroup_provider');
/**
* @param app
* @param {AuthApi} authApi
* @param {PgConnection} pgConnection
* @param {TemplateMaps} templateMaps
@@ -31,12 +31,11 @@ var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_laye
* @param {LayergroupAffectedTables} layergroupAffectedTables
* @constructor
*/
function MapController(app, authApi, pgConnection, templateMaps, mapBackend, metadataBackend, queryTablesApi,
function MapController(authApi, pgConnection, templateMaps, mapBackend, metadataBackend, queryTablesApi,
surrogateKeysCache, userLimitsApi, layergroupAffectedTables) {
BaseController.call(this, authApi, pgConnection);
this.app = app;
this.pgConnection = pgConnection;
this.templateMaps = templateMaps;
this.mapBackend = mapBackend;
@@ -55,10 +54,10 @@ module.exports = MapController;
MapController.prototype.register = function(app) {
app.get(app.base_url_mapconfig, cors(), this.createGet.bind(this));
app.post(app.base_url_mapconfig, cors(), this.createPost.bind(this));
app.get(app.base_url_templated + '/:template_id/jsonp', cors(), this.jsonp.bind(this));
app.post(app.base_url_templated + '/:template_id', cors(), this.instantiate.bind(this));
app.get(app.base_url_mapconfig, cors(), userMiddleware, this.createGet.bind(this));
app.post(app.base_url_mapconfig, cors(), userMiddleware, this.createPost.bind(this));
app.get(app.base_url_templated + '/:template_id/jsonp', cors(), userMiddleware, this.jsonp.bind(this));
app.post(app.base_url_templated + '/:template_id', cors(), userMiddleware, this.instantiate.bind(this));
app.options(app.base_url_mapconfig, cors('Content-Type'));
};

View File

@@ -7,14 +7,14 @@ var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
var userMiddleware = require('../middleware/user');
var TablesCacheEntry = require('../cache/model/database_tables_entry');
function NamedMapsController(app, authApi, pgConnection, namedMapProviderCache, tileBackend, previewBackend,
function NamedMapsController(authApi, pgConnection, namedMapProviderCache, tileBackend, previewBackend,
surrogateKeysCache, tablesExtentApi, metadataBackend) {
BaseController.call(this, authApi, pgConnection);
this.app = app;
this.namedMapProviderCache = namedMapProviderCache;
this.tileBackend = tileBackend;
this.previewBackend = previewBackend;
@@ -28,10 +28,13 @@ util.inherits(NamedMapsController, BaseController);
module.exports = NamedMapsController;
NamedMapsController.prototype.register = function(app) {
app.get(app.base_url_templated + '/:template_id/:layer/:z/:x/:y.(:format)', cors(), this.tile.bind(this));
app.get(
app.base_url_mapconfig + '/static/named/:template_id/:width/:height.:format', cors(), this.staticMap.bind(this)
);
app.get(app.base_url_templated +
'/:template_id/:layer/:z/:x/:y.(:format)', cors(), userMiddleware,
this.tile.bind(this));
app.get(app.base_url_mapconfig +
'/static/named/:template_id/:width/:height.:format', cors(), userMiddleware,
this.staticMap.bind(this));
};
NamedMapsController.prototype.sendResponse = function(req, res, resource, headers, namedMapProvider) {

View File

@@ -6,19 +6,20 @@ var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
var userMiddleware = require('../middleware/user');
/**
* @param {TemplateMaps} templateMaps
* @param {AuthApi} authApi
* @param {PgConnection} pgConnection
* @param {TemplateMaps} templateMaps
* @constructor
*/
function NamedMapsAdminController(templateMaps, authApi, pgConnection) {
function NamedMapsAdminController(authApi, pgConnection, templateMaps) {
BaseController.call(this, authApi, pgConnection);
this.templateMaps = templateMaps;
this.authApi = authApi;
this.templateMaps = templateMaps;
}
util.inherits(NamedMapsAdminController, BaseController);
@@ -26,11 +27,11 @@ util.inherits(NamedMapsAdminController, BaseController);
module.exports = NamedMapsAdminController;
NamedMapsAdminController.prototype.register = function(app) {
app.post(app.base_url_templated, cors(), this.create.bind(this));
app.put(app.base_url_templated + '/:template_id', cors(), this.update.bind(this));
app.get(app.base_url_templated + '/:template_id', cors(), this.retrieve.bind(this));
app.delete(app.base_url_templated + '/:template_id', cors(), this.destroy.bind(this));
app.get(app.base_url_templated, cors(), this.list.bind(this));
app.post(app.base_url_templated, cors(), userMiddleware, this.create.bind(this));
app.put(app.base_url_templated + '/:template_id', cors(), userMiddleware, this.update.bind(this));
app.get(app.base_url_templated + '/:template_id', cors(), userMiddleware, this.retrieve.bind(this));
app.delete(app.base_url_templated + '/:template_id', cors(), userMiddleware, this.destroy.bind(this));
app.get(app.base_url_templated, cors(), userMiddleware, this.list.bind(this));
app.options(app.base_url_templated + '/:template_id', cors('Content-Type'));
};

View File

@@ -0,0 +1,7 @@
var CdbRequest = require('../models/cdb_request');
var cdbRequest = new CdbRequest();
module.exports = function userMiddleware(req, res, next) {
req.context.user = cdbRequest.userByReq(req);
next();
};

View File

@@ -8,7 +8,7 @@ module.exports = CdbRequest;
CdbRequest.prototype.userByReq = function(req) {
var host = req.headers.host;
var host = req.headers.host || '';
if (req.params.user) {
return req.params.user;
}

View File

@@ -27,9 +27,6 @@ var NamedMapProviderCache = require('./cache/named_map_provider_cache');
var PgQueryRunner = require('./backends/pg_query_runner');
var PgConnection = require('./backends/pg_connection');
var CdbRequest = require('./models/cdb_request');
var cdbRequest = new CdbRequest();
var timeoutErrorTilePath = __dirname + '/../../assets/render-timeout-fallback.png';
var timeoutErrorTile = require('fs').readFileSync(timeoutErrorTilePath, {encoding: null});
@@ -157,13 +154,7 @@ module.exports = function(serverOptions) {
* Routing
******************************************************************************************************************/
app.all('*', function(req, res, next) {
req.context.user = cdbRequest.userByReq(req);
next();
});
new controller.Layergroup(
app,
authApi,
pgConnection,
mapStore,
@@ -177,7 +168,6 @@ module.exports = function(serverOptions) {
).register(app);
new controller.Map(
app,
authApi,
pgConnection,
templateMaps,
@@ -190,7 +180,6 @@ module.exports = function(serverOptions) {
).register(app);
new controller.NamedMaps(
app,
authApi,
pgConnection,
namedMapProviderCache,
@@ -201,7 +190,7 @@ module.exports = function(serverOptions) {
metadataBackend
).register(app);
new controller.NamedMapsAdmin(templateMaps, authApi, pgConnection).register(app);
new controller.NamedMapsAdmin(authApi, pgConnection, templateMaps).register(app);
new controller.ServerInfo().register(app);

32
npm-shrinkwrap.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "windshaft-cartodb",
"version": "2.14.0",
"version": "2.15.1",
"dependencies": {
"body-parser": {
"version": "1.14.1",
@@ -406,8 +406,8 @@
}
},
"fastly-purge": {
"version": "1.0.0",
"from": "fastly-purge@~1.0.0"
"version": "1.0.1",
"from": "fastly-purge@~1.0.1"
},
"log4js": {
"version": "0.6.25",
@@ -441,7 +441,7 @@
},
"inherits": {
"version": "2.0.1",
"from": "inherits@~2.0.1",
"from": "inherits@2",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
}
}
@@ -552,9 +552,9 @@
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
},
"util-deprecate": {
"version": "1.0.1",
"version": "1.0.2",
"from": "util-deprecate@~1.0.1",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz"
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
}
}
}
@@ -620,9 +620,9 @@
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz"
},
"tough-cookie": {
"version": "2.0.0",
"version": "2.2.0",
"from": "tough-cookie@>=0.12.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.0.tgz"
},
"http-signature": {
"version": "0.11.0",
@@ -711,9 +711,9 @@
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
"dependencies": {
"bluebird": {
"version": "2.10.1",
"version": "2.10.2",
"from": "bluebird@^2.9.30",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.1.tgz"
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz"
},
"chalk": {
"version": "1.1.1",
@@ -762,9 +762,9 @@
}
},
"commander": {
"version": "2.8.1",
"version": "2.9.0",
"from": "commander@^2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"dependencies": {
"graceful-readlink": {
"version": "1.0.1",
@@ -827,8 +827,8 @@
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
},
"windshaft": {
"version": "1.0.0",
"from": "windshaft@~1.0.0",
"version": "1.1.1",
"from": "windshaft@~1.1.1",
"dependencies": {
"mapnik": {
"version": "1.4.15-cdb2",
@@ -1301,9 +1301,9 @@
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz"
},
"tough-cookie": {
"version": "2.0.0",
"version": "2.2.0",
"from": "tough-cookie@>=0.12.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.0.tgz"
},
"form-data": {
"version": "0.1.4",

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "windshaft-cartodb",
"version": "2.14.0",
"version": "2.15.1",
"description": "A map tile server for CartoDB",
"keywords": [
"cartodb"
@@ -29,13 +29,13 @@
"node-statsd": "~0.0.7",
"underscore" : "~1.6.0",
"dot": "~1.0.2",
"windshaft": "~1.0.0",
"windshaft": "~1.1.1",
"step": "~0.0.6",
"queue-async": "~1.0.7",
"request": "~2.62.0",
"cartodb-redis": "~0.13.0",
"cartodb-psql": "~0.4.0",
"fastly-purge": "~1.0.0",
"fastly-purge": "~1.0.1",
"redis-mpool": "~0.4.0",
"lru-cache": "2.6.5",
"lzma": "~1.3.7",

View File

@@ -68,7 +68,7 @@ describe('templates surrogate keys', function() {
var cacheEntryKey = new NamedMapsCacheEntry(templateOwner, templateName).key();
var invalidationMatchHeader = '\\b' + cacheEntryKey + '\\b';
var fastlyPurgePath = '/service/' + FAKE_FASTLY_SERVICE_ID + '/purge/' + encodeURIComponent(cacheEntryKey);
var fastlyPurgePath = '/service/' + FAKE_FASTLY_SERVICE_ID + '/purge/' + cacheEntryKey;
var nock = require('nock');
nock.enableNetConnect(/(127.0.0.1:5555|cartocdn.com)/);
@@ -132,7 +132,6 @@ describe('templates surrogate keys', function() {
var fastlyScope = nock(FastlyPurge.FASTLY_API_ENDPOINT)
.post(fastlyPurgePath)
.matchHeader('Fastly-Key', FAKE_FASTLY_API_KEY)
.matchHeader('Fastly-Soft-Purge', 1)
.matchHeader('Accept', 'application/json')
.reply(200, {
status:'ok'
@@ -199,7 +198,6 @@ describe('templates surrogate keys', function() {
var fastlyScope = nock(FastlyPurge.FASTLY_API_ENDPOINT)
.post(fastlyPurgePath)
.matchHeader('Fastly-Key', FAKE_FASTLY_API_KEY)
.matchHeader('Fastly-Soft-Purge', 1)
.matchHeader('Accept', 'application/json')
.reply(200, {
status:'ok'
@@ -260,7 +258,6 @@ describe('templates surrogate keys', function() {
var fastlyScope = nock(FastlyPurge.FASTLY_API_ENDPOINT)
.post(fastlyPurgePath)
.matchHeader('Fastly-Key', FAKE_FASTLY_API_KEY)
.matchHeader('Fastly-Soft-Purge', 1)
.matchHeader('Accept', 'application/json')
.reply(200, {
status:'ok'

View File

@@ -333,7 +333,7 @@ describe('tests from old api translated to multilayer', function() {
assert.ok(!res.headers.hasOwnProperty('x-cache-channel'));
// TODO when affected tables query makes the request to fail layergroup should be removed
keysToDelete['map_cfg|f14693f2d7b6dcf4629724b3d1efe22d'] = 0;
keysToDelete['map_cfg|4fb7bd7008322ce66f22d20aebba1ab0'] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
var parsed = JSON.parse(res.body);

View File

@@ -57,4 +57,28 @@ describe('req2params', function() {
assert.equal(user, undefined);
});
it('should not fail for undefined host header', function() {
var userFromHostConfig = global.environment.user_from_host;
global.environment.user_from_host = null;
var cdbRequest = new CdbRequest();
var user = cdbRequest.userByReq(createRequest(undefined));
global.environment.user_from_host = userFromHostConfig;
assert.equal(user, undefined);
});
it('should not fail for null host header', function() {
var userFromHostConfig = global.environment.user_from_host;
global.environment.user_from_host = null;
var cdbRequest = new CdbRequest();
var user = cdbRequest.userByReq(createRequest(null));
global.environment.user_from_host = userFromHostConfig;
assert.equal(user, undefined);
});
});

View File

@@ -1,18 +1,13 @@
require('../../../support/test_helper.js');
var assert = require('assert');
var cartodbServer = require('../../../../lib/cartodb/server');
var serverOptions = require('../../../../lib/cartodb/server_options');
var StatsClient = require('../../../../lib/cartodb/stats/client');
var LayergroupController = require('../../../../lib/cartodb/controllers/layergroup');
describe('tile stats', function() {
var statsClientGetInstanceFn = StatsClient.getInstance;
after(function() {
StatsClient.getInstance = statsClientGetInstanceFn;
global.statsClient = null;
});
@@ -28,7 +23,7 @@ describe('tile stats', function() {
}
});
var layergroupController = new LayergroupController(cartodbServer(serverOptions));
var layergroupController = new LayergroupController();
var reqMock = {
params: {
@@ -70,7 +65,7 @@ describe('tile stats', function() {
send: function() {}
};
var layergroupController = new LayergroupController(cartodbServer(serverOptions));
var layergroupController = new LayergroupController();
layergroupController.finalizeGetTileOrGrid('Another error happened', reqMock, resMock, null, null);
@@ -79,9 +74,7 @@ describe('tile stats', function() {
});
function mockStatsClientGetInstance(instance) {
StatsClient.getInstance = function() {
return instance;
};
global.statsClient = instance;
}
});