apps/strider/dist-lib/middleware.js
require('./logging');
const auth = require('./auth');
const utils = require('./utils');
const common = require('./common');
const Project = require('./models').Project;
const User = require('./models').User;
module.exports = {
bodySetter: bodySetter,
requireBody: requireBody,
custom404: custom404,
anonProject: anonProject,
project: project,
projectPlugin: projectPlugin,
projectProvider: projectProvider,
csrfErrorHandler: csrfErrorHandler,
// Legacy aliases - don't use these:
require_auth: auth.requireUserOr401,
require_auth_browser: auth.requireUser,
require_admin: auth.requireAdminOr401,
require_project_admin: auth.requireProjectAdmin,
};
// Custom middleware to save unparsed request body to req.content
function bodySetter(req, res, next) {
if (req._post_body) {
return next();
}
req.post_body = req.post_body || '';
if ('POST' !== req.method) {
return next();
}
req._post_body = true;
req.on('data', function (chunk) {
req.post_body += chunk;
});
next();
}
// Require the specified req.body parameters, or else return a 400 with a descriptive JSON body
function requireBody(paramsList) {
return function (req, res, next) {
const errors = [];
let status = 'ok';
for (let i = 0; i < paramsList.length; i++) {
const val = req.body[paramsList[i]];
if (!val) {
errors.push(`required parameter \`${paramsList[i]}\` not found.`);
status = 'error';
}
}
if (errors.length === 0) {
next();
}
else {
return res.status(400).json({
errors: errors,
status: status,
});
}
};
}
function custom404(req, res, next) {
if (req.method !== 'GET') {
return next();
}
res.statusCode = 404;
res.render('doesnotexist.html');
}
// Create helper function to get or set the provifer config. Expects req.project
// `req.providerConfig` function
// providerConfig() -> return the config
// providerConfig(config, next(err)). save the config
//
// For hosted providers, the following function is also available
// accountConfig() -> return the account confi
// acountConfig(config, next(err)). save the account config
function projectProvider(req, res, next) {
const project = req.project;
req.providerConfig = function (config, next) {
if (arguments.length === 0) {
return project.provider.config;
}
project.provider.config = config;
project.markModified('provider');
project.save(next);
};
// make this conditional?
if (project.provider.account) {
const account = project.creator.account(project.provider.id, project.provider.account);
req.accountConfig = function (config, next) {
if (arguments.length === 0) {
return account.config;
}
account.config = config;
project.creator.markModified('accounts');
project.creator.save(next);
};
}
next();
}
// Get plugin config. Expects req.project
// Sets `req.pluginConfig` function
// pluginConfig() -> return the config
// pluginConfig(config, next(err)). save the config
function projectPlugin(req, res, next) {
let pluginid;
// if only 3 args, then get pluginid from params ":plugin"
if (arguments.length === 4) {
pluginid = req;
req = res;
res = next;
next = arguments[3];
}
else {
pluginid = req.params.plugin;
}
const branch = req.project.branch(req.query.branch);
let plugin = null;
if (!branch) {
return res.status(404).send('Specified branch not found for the project');
}
// if it's just mirroring master
if (branch.mirror_master) {
return res.status(400).send('Branch not individually configurable');
}
for (let i = 0; i < branch.plugins.length; i++) {
if (branch.plugins[i].id === pluginid) {
plugin = branch.plugins[i];
break;
}
}
if (plugin === null) {
return res.status(404).send('Plugin not enabled for the specified project');
}
req.pluginConfig = function (config, next) {
if (arguments.length === 0) {
return plugin.config;
}
plugin.config = config;
req.project.markModified('branches');
req.project.save(function (err) {
next(err, config);
});
};
req.userConfig = function (config, next) {
if (!req.user.isProjectCreator) {
if (arguments.length === 0) {
return false;
}
return next(new Error('Current user is not the creator - cannot set the creator config'));
}
if (arguments.length === 0) {
return req.project.creator.jobplugins[pluginid];
}
const schema = common.userConfigs.job && common.userConfigs.job[pluginid];
if (!schema) {
return next(new Error(`Plugin ${pluginid} doesn't define any user config`));
}
config = utils.validateAgainstSchema(config, schema);
// TODO: validation
req.project.creator.jobplugins[pluginid] = config;
req.project.creator.markModified('jobplugins');
req.project.creator.save(function (err) {
next(err, config);
});
};
next();
}
// just link project but doesn't fail if there's no auth
function anonProject(req, res, next) {
let name = `${req.params.org}/${req.params.repo}`;
name = name.toLowerCase();
Project.findOne({ name: name })
.populate('creator')
.exec(function (err, project) {
if (err) {
return res.status(500).send({
error: 'Failed to find project',
info: err,
});
}
if (!project) {
return res.status(404).send('Project not found');
}
if (!project.creator) {
return res
.status(400)
.send('Project malformed; project creator user is missing.');
}
req.project = project;
req.accessLevel = User.projectAccessLevel(req.user, project);
if (req.user && project.creator) {
req.user.isProjectCreator =
project.creator._id.toString() === req.user._id.toString();
}
next();
});
}
// getProject Middleware
// assumes two url parameters, :org and :repo, and req.user
// checks user access level, and sets the following properties on the
// request object.
//
// req.project = the project
// req.accessLevel = -1 for no access, 0 for public, 1 for normal, 2 for admin
//
// Errors:
// 404: not found
// 401: not public and you don't have access
// 500: something strange happened w/ the DB lookup
function project(req, res, next) {
if (req.params.org === 'auth') {
return next();
}
anonProject(req, res, function () {
if (req.accessLevel > -1) {
return next();
}
if (!req.user) {
req.session.return_to = req.url;
return res.redirect('/login?ember=true');
}
res.status(401).send('Not authorized');
});
}
function csrfErrorHandler(err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN')
return next(err);
res.status(403).send({ status: 'forbidden', errors: [{ message: 'invalid _csrf token' }] });
}
//# sourceMappingURL=middleware.js.map