397 строки
12 KiB
JavaScript
397 строки
12 KiB
JavaScript
var BadgeClient = require('badgekit-api-client');
|
|
var async = require('async');
|
|
|
|
module.exports = function (env) {
|
|
// Error messages
|
|
var errorHandlers = {
|
|
unauthorized: function () {
|
|
var err = new Error('You must be logged in to access this area.');
|
|
err.status = 401;
|
|
return err;
|
|
},
|
|
forbidden: function () {
|
|
var errorString = 'You are not authorized to access this area. ' +
|
|
'If you think you are supposed to have permissions, ' +
|
|
'try logging out and in again, or contact help@webmaker.org';
|
|
var err = new Error(errorString);
|
|
err.status = 403;
|
|
return err;
|
|
}
|
|
};
|
|
|
|
var badgeClient = new BadgeClient(env.get('BADGES_ENDPOINT'), {
|
|
key: env.get('BADGES_KEY'),
|
|
secret: env.get('BADGES_SECRET')
|
|
});
|
|
|
|
var permissionsModel = require('../lib/badges-permissions-model.js');
|
|
|
|
return {
|
|
middleware: {
|
|
// Check if a use has at least a certain level of permissions
|
|
// Can be 'admin', 'superMentor' or 'mentor'
|
|
atleast: function (level) {
|
|
var levels = ['isAdmin', 'isSuperMentor', 'isMentor'];
|
|
return function (req, res, next) {
|
|
var user = req.session.user;
|
|
if (!level || levels.indexOf(level) <= -1) {
|
|
var problem = level + ' is not a valid type of user.';
|
|
var err = new Error('There is a problem with the permissions model: ' + problem);
|
|
return next(err);
|
|
} else if (!user) {
|
|
return next(errorHandlers.unauthorized());
|
|
} else if (user.isAdmin) {
|
|
return next();
|
|
} else if (level === 'isSuperMentor' && (user.isAdmin || user.isSuperMentor)) {
|
|
return next();
|
|
} else if (level === 'isMentor' && (user.isAdmin || user.isSuperMentor || user.isMentor)) {
|
|
return next();
|
|
} else {
|
|
return next(errorHandlers.forbidden());
|
|
}
|
|
};
|
|
},
|
|
// Does this user have permissions to issue, approve applications, see instances?
|
|
hasPermissions: function (action) {
|
|
return function (req, res, next) {
|
|
var user = req.session.user;
|
|
|
|
if (!user) {
|
|
return next(errorHandlers.unauthorized());
|
|
}
|
|
|
|
var allowed = permissionsModel({
|
|
badge: req.params.badge,
|
|
user: req.session.user,
|
|
action: action
|
|
});
|
|
|
|
if (!allowed) {
|
|
return next(errorHandlers.forbidden());
|
|
} else {
|
|
return next();
|
|
}
|
|
};
|
|
}
|
|
},
|
|
getAll: function (req, res, next) {
|
|
badgeClient.getBadges({
|
|
system: env.get('BADGES_SYSTEM')
|
|
}, function (err, badges) {
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
res.json(badges);
|
|
});
|
|
},
|
|
getBadge: function (req, res, next) {
|
|
badgeClient.getBadge({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge
|
|
}, function (err, data) {
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
return res.send(data);
|
|
});
|
|
},
|
|
getInstances: function (req, res, next) {
|
|
badgeClient.getBadgeInstances({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge
|
|
}, function (err, instances) {
|
|
// errorString
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
|
|
// We need to get the badge data too
|
|
badgeClient.getBadge({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge
|
|
}, function (err, badge) {
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
res.json({
|
|
badge: badge,
|
|
instances: instances
|
|
});
|
|
});
|
|
});
|
|
},
|
|
deleteInstance: function (req, res, next) {
|
|
badgeClient.deleteBadgeInstance({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge,
|
|
email: req.params.email
|
|
}, function (err, result) {
|
|
if (err) {
|
|
console.log(err.stack);
|
|
return res.send(500, err.message);
|
|
}
|
|
res.send('DELETED');
|
|
});
|
|
},
|
|
details: function (req, res, next) {
|
|
function getBadge(callback) {
|
|
badgeClient.getBadge({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge
|
|
}, function (err, data) {
|
|
return callback(err, data);
|
|
});
|
|
}
|
|
|
|
function getInstance(callback) {
|
|
if (req.session.user) {
|
|
badgeClient.getBadgeInstance({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge,
|
|
email: req.session.user.email
|
|
}, function (err, data) {
|
|
if (err && err.name === 'ResourceNotFoundError') {
|
|
err = null;
|
|
}
|
|
return callback(err, data);
|
|
});
|
|
} else {
|
|
return callback(null, null);
|
|
}
|
|
}
|
|
|
|
function getApplication(callback) {
|
|
if (req.session.user) {
|
|
badgeClient.getApplications({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge
|
|
}, {
|
|
email: req.session.user.email,
|
|
processed: false
|
|
}, function (err, data) {
|
|
return callback(err, data);
|
|
});
|
|
} else {
|
|
return callback(null, null);
|
|
}
|
|
}
|
|
async.parallel(
|
|
[getBadge, getInstance, getApplication],
|
|
function (err, results) {
|
|
if (err) {
|
|
return res.render('badge-not-found.html', {
|
|
page: 'search',
|
|
view: 'badges'
|
|
});
|
|
}
|
|
|
|
var badge = results[0];
|
|
var instance = results[1];
|
|
var application = (results[2] && results[2].length) ? results[2][0] : null;
|
|
|
|
// Shim for https://bugzilla.mozilla.org/show_bug.cgi?id=1001161
|
|
if (badge.issuer && !badge.issuer.imageUrl) {
|
|
badge.issuer.imageUrl = 'https://webmaker.org/img/logo-webmaker.png';
|
|
}
|
|
|
|
// Can the current user issue this badge?
|
|
var canIssue = permissionsModel({
|
|
badge: req.params.badge,
|
|
user: req.session.user,
|
|
action: 'issue'
|
|
});
|
|
|
|
// Do we want to ask which Hive city the earner is affiliated with?
|
|
var requestCity = (req.params.badge === 'hive-community-member');
|
|
|
|
// Check if we have any criteria to display.
|
|
var canApply = true;
|
|
if (['Data Trail Timeline', 'Privacy Coach', 'IP Address Tracer'].indexOf(badge.name) >= 0) {
|
|
canApply = false;
|
|
}
|
|
|
|
res.render('badge-detail.html', {
|
|
page: req.params.badge,
|
|
view: 'badges',
|
|
badge: badge,
|
|
canIssue: canIssue,
|
|
canApply: canApply,
|
|
requestCity: requestCity,
|
|
backpackUrl: env.get('BACKPACK_PUSH_URL'),
|
|
assertionUrl: instance ? instance.assertionUrl : null,
|
|
application: application
|
|
});
|
|
});
|
|
},
|
|
apply: function (req, res, next) {
|
|
var evidence = [req.body.evidence];
|
|
var applicationSlug = req.body.applicationSlug;
|
|
|
|
if (req.body.city) {
|
|
evidence.push('Hive City: ' + req.body.city);
|
|
}
|
|
|
|
evidence = evidence.map(function (evidence) {
|
|
return {
|
|
reflection: evidence
|
|
};
|
|
});
|
|
|
|
var application = {
|
|
learner: req.session.user.email,
|
|
evidence: evidence,
|
|
slug: applicationSlug
|
|
};
|
|
|
|
var apiFunction;
|
|
if (applicationSlug) {
|
|
apiFunction = badgeClient.updateApplication.bind(badgeClient);
|
|
} else {
|
|
apiFunction = badgeClient.addApplication.bind(badgeClient);
|
|
}
|
|
|
|
apiFunction({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge,
|
|
application: application
|
|
}, function (err, data) {
|
|
if (err) {
|
|
return res.send(500, err);
|
|
}
|
|
res.send(data);
|
|
});
|
|
},
|
|
issue: function (req, res, next) {
|
|
var apiFunction;
|
|
var query = {
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge,
|
|
comment: req.body.comment
|
|
};
|
|
|
|
if (req.body.emails) {
|
|
query.emails = req.body.emails;
|
|
apiFunction = badgeClient.createBadgeInstances.bind(badgeClient);
|
|
} else if (req.body.email) {
|
|
query.email = req.body.email;
|
|
apiFunction = badgeClient.createBadgeInstance.bind(badgeClient);
|
|
} else {
|
|
return res.send(500, {
|
|
error: 'No email address provided'
|
|
});
|
|
}
|
|
|
|
apiFunction(query, function (err, data) {
|
|
if (err) {
|
|
var errorString = err.toString();
|
|
return res.send(500, {
|
|
error: errorString
|
|
});
|
|
}
|
|
res.send(data);
|
|
});
|
|
},
|
|
claim: function (req, res, next) {
|
|
var codeQuery = {
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge,
|
|
claimCode: req.body.claimcode
|
|
};
|
|
|
|
badgeClient.claimClaimCode(codeQuery, req.session.user.email, function (err, data) {
|
|
if (err) {
|
|
var errorString = err.message;
|
|
if (err.code === 404) {
|
|
errorString = 'The code "' + req.body.claimcode + '" could not be found';
|
|
}
|
|
return res.send(500, {
|
|
error: errorString
|
|
});
|
|
}
|
|
|
|
var instanceQuery = {
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge,
|
|
email: req.session.user.email
|
|
};
|
|
|
|
badgeClient.createBadgeInstance(instanceQuery, function (err, data) {
|
|
if (err) {
|
|
var errorString = err.message;
|
|
return res.send(500, errorString);
|
|
}
|
|
|
|
res.send(data);
|
|
});
|
|
});
|
|
},
|
|
getApplications: function (req, res, next) {
|
|
badgeClient.getApplications({
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge
|
|
}, function (err, raw) {
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
|
|
var applications = [];
|
|
// No way to query for pending applications only.
|
|
// See bug 1021009
|
|
if (req.query.processed) {
|
|
applications = raw;
|
|
} else {
|
|
raw.forEach(function (application) {
|
|
if (!application.processed) {
|
|
applications.push(application);
|
|
}
|
|
});
|
|
}
|
|
|
|
res.send(applications);
|
|
});
|
|
},
|
|
submitReview: function (req, res, next) {
|
|
var context = {
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.params.badge,
|
|
application: req.params.application,
|
|
review: {
|
|
author: req.session.email,
|
|
comment: req.body.comment,
|
|
reviewItems: req.body.reviewItems
|
|
}
|
|
};
|
|
badgeClient.addReview(context, function (err, review) {
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
return res.send(200, 'Success');
|
|
});
|
|
},
|
|
create: function (req, res, next) {
|
|
var context = {
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.body
|
|
};
|
|
badgeClient.createBadge(context, function (err, badge) {
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
return res.send(200, badge);
|
|
});
|
|
},
|
|
update: function (req, res, next) {
|
|
var context = {
|
|
system: env.get('BADGES_SYSTEM'),
|
|
badge: req.body
|
|
};
|
|
badgeClient.updateBadge(context, function (err, badge) {
|
|
if (err) {
|
|
return res.send(500, err.message);
|
|
}
|
|
return res.send(200, badge);
|
|
});
|
|
}
|
|
};
|
|
};
|