| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 15:52:11 -06:00
										 |  |  | var crypto = require('crypto'); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  | var PromiseA = require('bluebird'); | 
					
						
							|  |  |  | var OpErr = PromiseA.OperationalError; | 
					
						
							| 
									
										
										
										
											2017-07-26 15:52:11 -06:00
										 |  |  | var makeB64UrlSafe = require('./common').makeB64UrlSafe; | 
					
						
							| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function trim(grant) { | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     sub:   grant.sub, | 
					
						
							|  |  |  |     azp:   grant.azp, | 
					
						
							| 
									
										
										
										
											2017-08-01 14:23:43 -06:00
										 |  |  |     azpSub: grant.azpSub, | 
					
						
							| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  |     scope: grant.scope, | 
					
						
							|  |  |  |     updatedAt: parseInt(grant.updatedAt, 10), | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function create(app) { | 
					
						
							| 
									
										
										
										
											2017-07-26 15:51:51 -06:00
										 |  |  |   var restful = {}; | 
					
						
							| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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) { | 
					
						
							| 
									
										
										
										
											2017-07-26 15:52:11 -06:00
										 |  |  |     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')); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  |       if (typeof req.body.scope !== 'string' || typeof req.body.sub !== 'string') { | 
					
						
							|  |  |  |         throw new OpErr("malformed request: 'sub' and 'scope' must be strings"); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-07-26 15:52:11 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  |       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 () { | 
					
						
							| 
									
										
										
										
											2017-08-01 14:23:43 -06:00
										 |  |  |       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); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:10:41 -06:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     app.handlePromise(req, res, promise, '[issuer@oauth3.org] save grants'); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     trim:    trim, | 
					
						
							|  |  |  |     restful: restful, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.create = create; |