2017-12-29 22:22:17 +08:00
|
|
|
const { templateName } = require('../backends/template_maps');
|
|
|
|
const cors = require('../middleware/cors');
|
|
|
|
const userMiddleware = require('../middleware/user');
|
2018-02-27 23:52:27 +08:00
|
|
|
const rateLimit = require('../middleware/rate-limit');
|
|
|
|
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit;
|
2018-02-15 22:20:52 +08:00
|
|
|
const localsMiddleware = require('../middleware/context/locals');
|
2018-03-01 02:20:51 +08:00
|
|
|
const credentialsMiddleware = require('../middleware/context/credentials');
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2015-07-13 21:05:03 +08:00
|
|
|
/**
|
|
|
|
* @param {AuthApi} authApi
|
2015-09-16 22:18:26 +08:00
|
|
|
* @param {PgConnection} pgConnection
|
2015-10-01 00:00:54 +08:00
|
|
|
* @param {TemplateMaps} templateMaps
|
2015-07-13 21:05:03 +08:00
|
|
|
* @constructor
|
|
|
|
*/
|
2018-02-28 20:11:18 +08:00
|
|
|
function NamedMapsAdminController(authApi, templateMaps, userLimitsApi) {
|
2015-07-13 21:05:03 +08:00
|
|
|
this.authApi = authApi;
|
2015-10-01 00:00:54 +08:00
|
|
|
this.templateMaps = templateMaps;
|
2018-02-28 20:11:18 +08:00
|
|
|
this.userLimitsApi = userLimitsApi;
|
2015-07-08 19:11:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = NamedMapsAdminController;
|
|
|
|
|
2017-10-05 18:12:21 +08:00
|
|
|
NamedMapsAdminController.prototype.register = function (app) {
|
2017-12-29 23:24:19 +08:00
|
|
|
const { base_url_templated } = app;
|
2017-12-29 23:19:00 +08:00
|
|
|
|
2017-10-05 18:12:21 +08:00
|
|
|
app.post(
|
2017-12-29 23:24:19 +08:00
|
|
|
`${base_url_templated}/`,
|
2017-10-05 18:12:21 +08:00
|
|
|
cors(),
|
2018-03-01 22:42:03 +08:00
|
|
|
userMiddleware(),
|
2018-03-15 01:06:06 +08:00
|
|
|
rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_CREATE),
|
2018-03-01 22:52:48 +08:00
|
|
|
localsMiddleware(),
|
2018-03-01 02:46:46 +08:00
|
|
|
credentialsMiddleware(),
|
2018-03-15 00:22:47 +08:00
|
|
|
checkContentType({ action: 'POST', label: 'POST TEMPLATE' }),
|
2018-03-15 00:25:58 +08:00
|
|
|
authorizedByAPIKey({ authApi: this.authApi, action: 'create', label: 'POST TEMPLATE' }),
|
2018-03-15 00:31:37 +08:00
|
|
|
createTemplate({ templateMaps: this.templateMaps }),
|
2018-03-13 20:31:49 +08:00
|
|
|
sendResponse()
|
2017-10-05 18:12:21 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
app.put(
|
2017-12-29 23:24:19 +08:00
|
|
|
`${base_url_templated}/:template_id`,
|
2017-10-05 18:12:21 +08:00
|
|
|
cors(),
|
2018-03-01 22:42:03 +08:00
|
|
|
userMiddleware(),
|
2018-03-15 01:06:06 +08:00
|
|
|
rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_UPDATE),
|
2018-03-01 22:52:48 +08:00
|
|
|
localsMiddleware(),
|
2018-03-01 02:46:46 +08:00
|
|
|
credentialsMiddleware(),
|
2018-03-15 00:22:47 +08:00
|
|
|
checkContentType({ action: 'PUT', label: 'PUT TEMPLATE' }),
|
2018-03-15 00:25:58 +08:00
|
|
|
authorizedByAPIKey({ authApi: this.authApi, action: 'update', label: 'PUT TEMPLATE' }),
|
2018-03-15 00:31:37 +08:00
|
|
|
updateTemplate({ templateMaps: this.templateMaps }),
|
2018-03-13 20:31:49 +08:00
|
|
|
sendResponse()
|
2017-10-05 18:12:21 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
app.get(
|
2017-12-29 23:24:19 +08:00
|
|
|
`${base_url_templated}/:template_id`,
|
2017-10-05 18:12:21 +08:00
|
|
|
cors(),
|
2018-03-01 22:42:03 +08:00
|
|
|
userMiddleware(),
|
2018-03-15 01:06:06 +08:00
|
|
|
rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_GET),
|
2018-03-01 22:52:48 +08:00
|
|
|
localsMiddleware(),
|
2018-03-01 02:46:46 +08:00
|
|
|
credentialsMiddleware(),
|
2018-03-15 00:25:58 +08:00
|
|
|
authorizedByAPIKey({ authApi: this.authApi, action: 'get', label: 'GET TEMPLATE' }),
|
2018-03-15 00:31:37 +08:00
|
|
|
retrieveTemplate({ templateMaps: this.templateMaps }),
|
2018-03-13 20:31:49 +08:00
|
|
|
sendResponse()
|
2017-10-05 18:12:21 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
app.delete(
|
2017-12-29 23:24:19 +08:00
|
|
|
`${base_url_templated}/:template_id`,
|
2017-10-05 18:12:21 +08:00
|
|
|
cors(),
|
2018-03-01 22:42:03 +08:00
|
|
|
userMiddleware(),
|
2018-03-15 01:06:06 +08:00
|
|
|
rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_DELETE),
|
2018-03-01 22:52:48 +08:00
|
|
|
localsMiddleware(),
|
2018-03-01 02:46:46 +08:00
|
|
|
credentialsMiddleware(),
|
2018-03-15 00:25:58 +08:00
|
|
|
authorizedByAPIKey({ authApi: this.authApi, action: 'delete', label: 'DELETE TEMPLATE' }),
|
2018-03-15 00:31:37 +08:00
|
|
|
destroyTemplate({ templateMaps: this.templateMaps }),
|
2018-03-13 20:31:49 +08:00
|
|
|
sendResponse()
|
2017-10-05 18:12:21 +08:00
|
|
|
);
|
2017-09-22 22:45:34 +08:00
|
|
|
|
2017-10-05 18:12:21 +08:00
|
|
|
app.get(
|
2017-12-29 23:24:19 +08:00
|
|
|
`${base_url_templated}/`,
|
2017-09-22 22:45:34 +08:00
|
|
|
cors(),
|
2018-03-01 22:42:03 +08:00
|
|
|
userMiddleware(),
|
2018-03-15 01:06:06 +08:00
|
|
|
rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_LIST),
|
2018-03-01 22:52:48 +08:00
|
|
|
localsMiddleware(),
|
2018-03-01 02:46:46 +08:00
|
|
|
credentialsMiddleware(),
|
2018-03-15 00:25:58 +08:00
|
|
|
authorizedByAPIKey({ authApi: this.authApi, action: 'list', label: 'GET TEMPLATE LIST' }),
|
2018-03-15 00:31:37 +08:00
|
|
|
listTemplates({ templateMaps: this.templateMaps }),
|
2018-03-13 20:31:49 +08:00
|
|
|
sendResponse()
|
2017-09-22 22:45:34 +08:00
|
|
|
);
|
|
|
|
|
2017-10-05 18:12:21 +08:00
|
|
|
app.options(
|
2017-12-29 23:24:19 +08:00
|
|
|
`${base_url_templated}/:template_id`,
|
2017-10-05 18:12:21 +08:00
|
|
|
cors('Content-Type')
|
|
|
|
);
|
2015-07-08 19:11:57 +08:00
|
|
|
};
|
|
|
|
|
2018-03-15 00:22:47 +08:00
|
|
|
function checkContentType ({ action, label }) {
|
2018-03-13 20:12:18 +08:00
|
|
|
return function checkContentTypeMiddleware (req, res, next) {
|
|
|
|
if (!req.is('application/json')) {
|
|
|
|
const error = new Error(`template ${action} data must be of type application/json`);
|
|
|
|
error.label = label;
|
|
|
|
return next(error);
|
|
|
|
}
|
2018-03-13 20:31:49 +08:00
|
|
|
|
2018-03-13 20:12:18 +08:00
|
|
|
next();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-03-15 00:25:58 +08:00
|
|
|
function authorizedByAPIKey ({ authApi, action, label }) {
|
2017-12-29 22:19:52 +08:00
|
|
|
return function authorizedByAPIKeyMiddleware (req, res, next) {
|
|
|
|
const { user } = res.locals;
|
2018-03-13 20:12:18 +08:00
|
|
|
|
|
|
|
authApi.authorizedByAPIKey(user, res, (err, authenticated) => {
|
2017-12-29 22:19:52 +08:00
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!authenticated) {
|
|
|
|
const error = new Error(`Only authenticated user can ${action} templated maps`);
|
|
|
|
error.http_status = 403;
|
|
|
|
error.label = label;
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
};
|
2018-03-13 20:12:18 +08:00
|
|
|
}
|
2017-12-29 22:19:52 +08:00
|
|
|
|
2018-03-15 00:31:37 +08:00
|
|
|
function createTemplate ({ templateMaps }) {
|
2017-12-29 23:15:48 +08:00
|
|
|
return function createTemplateMiddleware (req, res, next) {
|
2017-12-30 01:34:54 +08:00
|
|
|
const { user } = res.locals;
|
2017-12-29 23:30:42 +08:00
|
|
|
const template = req.body;
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2018-03-13 20:12:18 +08:00
|
|
|
templateMaps.addTemplate(user, template, (err, templateId) => {
|
2017-12-29 23:15:48 +08:00
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
2017-12-29 22:04:44 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
res.body = { template_id: templateId };
|
2017-12-29 22:04:44 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
next();
|
2017-12-29 23:15:48 +08:00
|
|
|
});
|
2018-03-13 20:12:18 +08:00
|
|
|
};
|
|
|
|
}
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2018-03-15 00:31:37 +08:00
|
|
|
function updateTemplate ({ templateMaps }) {
|
2017-12-29 23:15:48 +08:00
|
|
|
return function updateTemplateMiddleware (req, res, next) {
|
2017-12-29 23:30:42 +08:00
|
|
|
const { user } = res.locals;
|
2017-12-29 23:15:48 +08:00
|
|
|
const template = req.body;
|
2017-12-29 23:30:42 +08:00
|
|
|
const templateId = templateName(req.params.template_id);
|
2016-03-11 18:06:51 +08:00
|
|
|
|
2018-03-13 20:12:18 +08:00
|
|
|
templateMaps.updTemplate(user, templateId, template, (err) => {
|
2017-12-29 23:15:48 +08:00
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
res.body = { template_id: templateId };
|
2017-12-29 22:04:44 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
next();
|
2017-12-29 23:15:48 +08:00
|
|
|
});
|
2018-03-13 20:12:18 +08:00
|
|
|
};
|
|
|
|
}
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2018-03-15 00:31:37 +08:00
|
|
|
function retrieveTemplate ({ templateMaps }) {
|
2018-01-03 20:15:11 +08:00
|
|
|
return function retrieveTemplateMiddleware (req, res, next) {
|
2017-12-29 23:15:48 +08:00
|
|
|
req.profiler.start('windshaft-cartodb.get_template');
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2017-12-30 01:34:54 +08:00
|
|
|
const { user } = res.locals;
|
2017-12-29 23:30:42 +08:00
|
|
|
const templateId = templateName(req.params.template_id);
|
2017-12-29 22:17:29 +08:00
|
|
|
|
2018-03-13 20:12:18 +08:00
|
|
|
templateMaps.getTemplate(user, templateId, (err, template) => {
|
2017-12-29 23:15:48 +08:00
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
2017-12-29 22:17:29 +08:00
|
|
|
|
2017-12-29 23:30:42 +08:00
|
|
|
if (!template) {
|
2017-12-30 01:34:54 +08:00
|
|
|
const error = new Error(`Cannot find template '${templateId}' of user '${user}'`);
|
2017-12-29 23:15:48 +08:00
|
|
|
error.http_status = 404;
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
// auth_id was added by ourselves,
|
|
|
|
// so we remove it before returning to the user
|
2017-12-29 23:30:42 +08:00
|
|
|
delete template.auth_id;
|
2017-12-29 22:17:29 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
res.body = { template };
|
2017-12-29 22:17:29 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
next();
|
2017-12-29 23:15:48 +08:00
|
|
|
});
|
2018-03-13 20:12:18 +08:00
|
|
|
};
|
|
|
|
}
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2018-03-15 00:31:37 +08:00
|
|
|
function destroyTemplate ({ templateMaps }) {
|
2017-12-29 23:15:48 +08:00
|
|
|
return function destroyTemplateMiddleware (req, res, next) {
|
|
|
|
req.profiler.start('windshaft-cartodb.delete_template');
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2017-12-29 23:30:42 +08:00
|
|
|
const { user } = res.locals;
|
|
|
|
const templateId = templateName(req.params.template_id);
|
2017-12-29 22:04:44 +08:00
|
|
|
|
2018-03-13 20:12:18 +08:00
|
|
|
templateMaps.delTemplate(user, templateId, (err/* , tpl_val */) => {
|
2017-12-29 23:15:48 +08:00
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
2017-12-29 22:17:29 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
res.statusCode = 204;
|
|
|
|
res.body = '';
|
2017-12-29 22:17:29 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
next();
|
2017-12-29 23:15:48 +08:00
|
|
|
});
|
2018-03-13 20:12:18 +08:00
|
|
|
};
|
|
|
|
}
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2018-03-15 00:31:37 +08:00
|
|
|
function listTemplates ({ templateMaps }) {
|
2017-12-29 23:15:48 +08:00
|
|
|
return function listTemplatesMiddleware (req, res, next) {
|
|
|
|
req.profiler.start('windshaft-cartodb.get_template_list');
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2017-12-29 23:30:42 +08:00
|
|
|
const { user } = res.locals;
|
2015-07-08 19:11:57 +08:00
|
|
|
|
2018-03-13 20:12:18 +08:00
|
|
|
templateMaps.listTemplates(user, (err, templateIds) => {
|
2017-12-29 23:15:48 +08:00
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
2017-12-29 22:04:44 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
res.body = { template_ids: templateIds };
|
2017-12-29 22:04:44 +08:00
|
|
|
|
2018-03-13 20:31:49 +08:00
|
|
|
next();
|
2017-12-29 23:15:48 +08:00
|
|
|
});
|
2018-03-13 20:12:18 +08:00
|
|
|
};
|
|
|
|
}
|
2018-03-13 20:31:49 +08:00
|
|
|
|
|
|
|
function sendResponse () {
|
|
|
|
return function sendResponseMiddleware (req, res) {
|
|
|
|
res.status(res.statusCode || 200);
|
|
|
|
|
|
|
|
const method = req.query.callback ? 'jsonp' : 'json';
|
|
|
|
res[method](res.body);
|
2018-03-13 22:02:44 +08:00
|
|
|
};
|
2018-03-13 20:31:49 +08:00
|
|
|
}
|