95 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			2.8 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 req.Store.find({ azpSub: req.body.sub });
 | |
|     }).then(function (existing) {
 | |
|       if (existing.length) {
 | |
|         if (existing.length > 1) {
 | |
|           throw new OpErr("pre-existing PPID collision detected");
 | |
|         } else if (existing[0].sub !== req.params.sub || existing[0].azp !== req.params.azp) {
 | |
|           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;
 |