97 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			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;
 |