issuer.rest.walnut.js/grants.js

97 lines
2.9 KiB
JavaScript

'use strict';
var crypto = require('crypto');
var PromiseA = require('bluebird');
var OpErr = PromiseA.OperationalError;
var makeB64UrlSafe = require('./common').makeB64UrlSafe;
function trim(grant) {
return {
sub: grant.sub,
azp: grant.azp,
azpSub: grant.azpSub,
scope: grant.scope,
updatedAt: parseInt(grant.updatedAt, 10),
};
}
function create(app) {
var restful = {};
restful.getOne = function (req, res) {
var promise = req.Store.get(req.params.sub+'/'+req.params.azp).then(function (grant) {
if (!grant) {
throw new OpErr('no grants found');
}
return trim(grant);
});
app.handlePromise(req, res, promise, "[issuer@oauth3.org] retrieve grants");
};
restful.getAll = function (req, res) {
var promise = req.Store.find({ sub: req.params.sub }).then(function (results) {
return results.map(trim).sort(function (grantA, grantB) {
return (grantA.azp < grantB.azp) ? -1 : 1;
});
});
app.handlePromise(req, res, promise, "[issuer@oauth3.org] retrieve grants");
};
restful.saveNew = function (req, res) {
var promise = req.Store.get(req.params.sub+'/'+req.params.azp).then(function (existing) {
if (existing) {
if (req.body.sub && req.body.sub !== existing.azpSub) {
throw new OpErr("specified 'sub' does not agree with existing grants");
}
req.body.sub = existing.azpSub;
}
if (!req.body.sub) {
req.body.sub = makeB64UrlSafe(crypto.randomBytes(32).toString('base64'));
}
if (typeof req.body.scope !== 'string' || typeof req.body.sub !== 'string') {
throw new OpErr("malformed request: 'sub' and 'scope' must be strings");
}
return require('./common').getPrimarySub(req.Store, req.body.sub).catch(function (err) {
if (/collision/.test(err.message)) {
err.message = 'pre-existing PPID collision detected';
}
throw err;
});
}).then(function (primSub) {
if (primSub && primSub !== req.params.sub) {
console.log('account "'+req.params.sub+'" cannot use PPID "'+req.body.sub+'" already used by "'+primSub+'"');
throw new OpErr("PPID collision detected, cannot save authorized party's sub");
}
var grant = {
sub: req.params.sub,
azp: req.params.azp,
azpSub: req.body.sub,
scope: req.body.scope.split(/[+ ,]+/g).join(','),
};
return req.Store.upsert(grant.sub+'/'+grant.azp, grant);
}).then(function () {
return req.Store.get(req.params.sub+'/'+req.params.azp);
}).then(function (grant) {
if (!grant) {
throw new Error('failed to retrieve grants after saving them');
}
return trim(grant);
});
app.handlePromise(req, res, promise, '[issuer@oauth3.org] save grants');
};
return {
trim: trim,
restful: restful,
};
}
module.exports.create = create;