Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support async authentication - onAuthenticate may now return Promise. C…
…loses #31.
- Loading branch information
Showing
3 changed files
with
119 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,6 +120,72 @@ function processOptions(options){ | |
|
||
function processAuth(req,res,useWWWAuth) { | ||
|
||
return new Promise( function (resolve, reject) { | ||
if( !swsOptions.authentication ){ | ||
return resolve(true); | ||
} | ||
|
||
var cookies = new Cookies( req, res ); | ||
|
||
// Check session cookie | ||
var sessionIdCookie = cookies.get('sws-session-id'); | ||
if( (sessionIdCookie !== undefined) && (sessionIdCookie !== null) ){ | ||
|
||
if( sessionIdCookie in sessionIDs ){ | ||
// renew it | ||
//sessionIDs[sessionIdCookie] = Date.now(); | ||
storeSessionID(sessionIdCookie); | ||
cookies.set('sws-session-id',sessionIdCookie,{path:swsOptions.uriPath,maxAge:swsOptions.sessionMaxAge*1000}); | ||
// Ok | ||
req['sws-auth'] = true; | ||
return resolve(true); | ||
} | ||
} | ||
|
||
var authInfo = basicAuth(req); | ||
|
||
var authenticated = false; | ||
var msg = 'Authentication required'; | ||
|
||
if( (authInfo !== undefined) && (authInfo!==null) && ('name' in authInfo) && ('pass' in authInfo)){ | ||
if(typeof swsOptions.onAuthenticate === 'function'){ | ||
|
||
Promise.resolve(swsOptions.onAuthenticate(req, authInfo.name, authInfo.pass)).then(function(onAuthResult) { | ||
if( onAuthResult ){ | ||
|
||
authenticated = true; | ||
|
||
// Session is only for stats requests | ||
if(req.url.startsWith(pathStats)){ | ||
// Generate session id | ||
var sessid = uuidv1(); | ||
storeSessionID(sessid); | ||
// Set session cookie with expiration in 15 min | ||
cookies.set('sws-session-id',sessid,{path:swsOptions.uriPath,maxAge:swsOptions.sessionMaxAge*1000}); | ||
} | ||
|
||
req['sws-auth'] = true; | ||
return resolve(true); | ||
|
||
}else{ | ||
msg = 'Invalid credentials'; | ||
res.status(403).end(msg); | ||
return resolve(false); | ||
} | ||
}); | ||
|
||
}else{ | ||
res.status(403).end(msg); | ||
return resolve(false); | ||
} | ||
}else{ | ||
res.status(403).end(msg); | ||
return resolve(false); | ||
} | ||
|
||
}); | ||
|
||
/* | ||
if( !swsOptions.authentication ){ | ||
return true; | ||
} | ||
|
@@ -176,6 +242,7 @@ function processAuth(req,res,useWWWAuth) { | |
req['sws-auth'] = true; | ||
return true; | ||
*/ | ||
} | ||
|
||
function processLogout(req,res){ | ||
|
@@ -200,6 +267,18 @@ function processLogout(req,res){ | |
// Query parameters (fields, path, method) defines which stat fields to return | ||
function processGetStats(req,res){ | ||
|
||
processAuth(req,res).then(function (authResult){ | ||
if(!authResult){ | ||
return; | ||
} | ||
res.status(200); | ||
if(('sws-auth' in req) && req['sws-auth']){ | ||
res.setHeader('x-sws-authenticated','true'); | ||
} | ||
res.json( processor.getStats( req.query ) ); | ||
}); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
sv2
Author
Collaborator
|
||
|
||
/* | ||
if(!processAuth(req,res)) { | ||
return; | ||
} | ||
|
@@ -209,19 +288,30 @@ function processGetStats(req,res){ | |
} | ||
res.status(200).json( processor.getStats( req.query ) ); | ||
*/ | ||
} | ||
|
||
|
||
// Process /swagger-stats/metrics request | ||
// Return all metrics for Prometheus | ||
function processGetMetrics(req,res){ | ||
|
||
processAuth(req,res).then(function (authResult){ | ||
if(!authResult){ | ||
return; | ||
} | ||
res.status(200).set('Content-Type', 'text/plain'); | ||
res.end(promClient.register.metrics()); | ||
}); | ||
|
||
/* | ||
if(!processAuth(req,res)) { | ||
return; | ||
} | ||
res.status(200).set('Content-Type', 'text/plain'); | ||
res.end(promClient.register.metrics()); | ||
*/ | ||
} | ||
|
||
module.exports = { | ||
|
@@ -240,11 +330,9 @@ module.exports = { | |
// Respond to requests handled by swagger-stats | ||
// swagger-stats requests will not be counted in statistics | ||
if(req.url.startsWith(pathStats)) { | ||
processGetStats(req, res); | ||
return; | ||
return processGetStats(req, res); | ||
}else if(req.url.startsWith(pathMetrics)){ | ||
processGetMetrics(req,res); | ||
return; | ||
return processGetMetrics(req,res); | ||
}else if(req.url.startsWith(pathLogout)){ | ||
processLogout(req,res); | ||
return; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@sv2 I think that without an error handler here (the second parameter to
.then(successCallback, errorCallback)
errors in the promise will be swallowed and an "UnhandledRejection" event will be emitted on the process object. This is probably not desirable