1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 18:29:17 +02:00

use security handler instead of express middleware for access token validation.

This commit is contained in:
Vishal Banthia 2015-12-03 17:33:53 +09:00
parent f10ae51b53
commit 221bc78e49
5 changed files with 120 additions and 81 deletions

View file

@ -6,7 +6,6 @@ swagger:
fittingsDirs: [ fittings ] fittingsDirs: [ fittings ]
defaultPipe: null defaultPipe: null
swaggerControllerPipe: swagger_controllers # defines the standard processing pipe for controllers swaggerControllerPipe: swagger_controllers # defines the standard processing pipe for controllers
swagger: 'swagger/api_v1.yaml'
# values defined in the bagpipes key are the bagpipes pipes and fittings definitions # values defined in the bagpipes key are the bagpipes pipes and fittings definitions
# (see https://github.com/apigee-127/bagpipes) # (see https://github.com/apigee-127/bagpipes)
@ -22,10 +21,13 @@ swagger:
name: swagger_validator name: swagger_validator
validateResponse: true validateResponse: true
_swagger_security:
name: swagger_security
securityHandlersModule: helpers/securityHandlers
# pipe for all swagger-node controllers # pipe for all swagger-node controllers
swagger_controllers: swagger_controllers:
- onError: json_error_handler - onError: json_error_handler
- cors
- swagger_params_parser - swagger_params_parser
- swagger_security - swagger_security
- _swagger_validate - _swagger_validate

View file

@ -0,0 +1,70 @@
var jwtutil = require('../../../util/jwtutil')
var urlutil = require('../../../util/urlutil')
var logger = require('../../../util/logger')
var dbapi = require('../../../db/api')
var log = logger.createLogger('api:auth')
module.exports = {
accessTokenAuth: accessTokenAuth
}
function accessTokenAuth(req, res, next) {
if (req.headers.authorization) {
var tokenId = req.headers.authorization.split(" ")[1]
if (tokenId) {
dbapi.loadAccessToken(tokenId)
.then(function(token) {
var jwt = token.jwt
, data = jwtutil.decode(jwt, req.options.secret)
if (data) {
dbapi.loadUser(data.email)
.then(function(user) {
if (user) {
req.user = user
next()
}
})
}
})
.catch(function(err) {
log.error('Failed to load token: ', err.stack)
res.json(500, {
success: false,
description: "Bad Access Token"
})
})
} else {
log.error("Bad Access Token Header")
res.json(500, {
success: false,
description: "Bad Access Token Header"
})
}
}
// TODO: Remove this once frontend become stateless
else if (req.session && req.session.jwt) {
dbapi.loadUser(req.session.jwt.email)
.then(function(user) {
if (user) {
req.user = user
next()
}
else {
res.json(500, {
success: false,
description: "Bad Request"
})
}
})
.catch(next)
}
else {
res.json(500, {
success: false,
description: "Request does not have Authorization header"
})
}
}

View file

@ -7,8 +7,6 @@ var cookieSession = require('cookie-session')
var logger = require('../../util/logger') var logger = require('../../util/logger')
var auth = require('./middleware/auth')
module.exports = function(options) { module.exports = function(options) {
var log = logger.createLogger('api') var log = logger.createLogger('api')
, app = express() , app = express()
@ -25,17 +23,19 @@ module.exports = function(options) {
swaggerExpress.register(app); swaggerExpress.register(app);
}) })
// Adding options in request, so that swagger controller
// can use it.
app.use(function(req, res, next) {
req.options = options
next()
})
// TODO: Remove this once frontend is stateless // TODO: Remove this once frontend is stateless
app.use(cookieSession({ app.use(cookieSession({
name: options.ssid name: options.ssid
, keys: [options.secret] , keys: [options.secret]
})) }))
app.use(auth({
secret: options.secret
, authUrl: options.authUrl
}))
server.listen(options.port) server.listen(options.port)
log.info('Listening on port %d', options.port) log.info('Listening on port %d', options.port)
} }

View file

@ -1,65 +0,0 @@
var jwtutil = require('../../../util/jwtutil')
var urlutil = require('../../../util/urlutil')
var logger = require('../../../util/logger')
var dbapi = require('../../../db/api')
module.exports = function(options) {
return function(req, res, next) {
var log = logger.createLogger('api:auth')
if (req.headers.authorization) {
var tokenId = req.headers.authorization.split(" ")[1]
if (tokenId) {
dbapi.loadAccessToken(tokenId)
.then(function(token) {
var jwt = token.jwt
, data = jwtutil.decode(jwt, options.secret)
if (data) {
dbapi.loadUser(data.email)
.then(function(user) {
if (user) {
req.user = user
next()
}
})
}
})
.catch(function(err) {
log.error('Failed to load token: ', err.stack)
res.json(500, {
success: false,
description: "Bad Access Token"
})
})
} else {
log.error("Bad Access Token")
res.json(500, {
success: false,
description: "Bad Access Token Header"
})
}
}
// TODO: Remove this once frontend become stateless
else if (req.session && req.session.jwt) {
dbapi.loadUser(req.session.jwt.email)
.then(function(user) {
if (user) {
req.user = user
next()
}
else {
// We no longer have the user in the database
res.redirect(options.authUrl)
}
})
.catch(next)
}
else {
// No session, forward to auth client
res.redirect(options.authUrl)
}
}
}

View file

@ -1,14 +1,15 @@
swagger: "2.0" swagger: "2.0"
info: info:
version: "1.0.10" version: "2.0.0"
title: Smartphone Test Farm title: Smartphone Test Farm
description: Control and manager real Smartphone devices from browser and apis description: Control and manager real Smartphone devices from browser and restful apis
license: license:
name: Apache-2.0 name: Apache-2.0
url: http://www.apache.org/licenses/LICENSE-2.0 url: http://www.apache.org/licenses/LICENSE-2.0
contact: contact:
url: http://openstf.io/ name: STF Support
email: contact@openstf.io email: contact@openstf.io
url: http://openstf.io/
basePath: /api/v1 basePath: /api/v1
schemes: schemes:
- http - http
@ -17,6 +18,11 @@ consumes:
- application/json - application/json
produces: produces:
- application/json - application/json
tags:
- name: user
description: User Operations
- name: device
description: Device Operations
paths: paths:
/me: /me:
x-swagger-router-controller: user x-swagger-router-controller: user
@ -24,6 +30,8 @@ paths:
summary: User Profile summary: User Profile
description: The User Profile endpoint returns information about current authorized user. description: The User Profile endpoint returns information about current authorized user.
operationId: getCurrentUser operationId: getCurrentUser
tags:
- user
responses: responses:
"200": "200":
description: Current User Profile information description: Current User Profile information
@ -33,6 +41,8 @@ paths:
description: Unexpected Error description: Unexpected Error
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"
security:
- accessTokenAuth: []
# TODO: Change group endpoint with something more easy to understandable endpoint # TODO: Change group endpoint with something more easy to understandable endpoint
/group: /group:
x-swagger-router-controller: user x-swagger-router-controller: user
@ -40,21 +50,27 @@ paths:
summary: User Group summary: User Group
description: The User Group endpoint returns information about user group of current authorized user. description: The User Group endpoint returns information about user group of current authorized user.
operationId: getCurrentUserGroup operationId: getCurrentUserGroup
tags:
- user
responses: responses:
"200": "200":
description: Current User Group information description: Current User's Group information
schema: schema:
$ref: "#/definitions/GroupResponse" $ref: "#/definitions/GroupResponse"
default: default:
description: Unexpected Error description: Unexpected Error
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"
security:
- accessTokenAuth: []
/accessTokens: /accessTokens:
x-swagger-router-controller: token x-swagger-router-controller: token
get: get:
summary: Access Tokens summary: Access Tokens
description: Return Current User Access Tokens titles description: The Access Tokens endpoints returns titles of all the valid access tokens.
operationId: getAccessTokens operationId: getAccessTokens
tags:
- user
responses: responses:
"200": "200":
description: Access Tokens titles description: Access Tokens titles
@ -64,12 +80,16 @@ paths:
description: Unexpected Error description: Unexpected Error
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"
security:
- accessTokenAuth: []
/devices: /devices:
x-swagger-router-controller: device x-swagger-router-controller: device
get: get:
summary: Device List summary: Device List
description: List of all the STF devices including Disconnected and Offline description: The devices enpoint return list of all the STF devices including Disconnected and Offline
operationId: getDevices operationId: getDevices
tags:
- device
responses: responses:
"200": "200":
description: List of Devices description: List of Devices
@ -79,12 +99,16 @@ paths:
description: Unexpected Error description: Unexpected Error
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"
security:
- accessTokenAuth: []
/devices/{serial}: /devices/{serial}:
x-swagger-router-controller: device x-swagger-router-controller: device
get: get:
summary: Device Information summary: Device Information
description: Device Information description: The device enpoint return information about a single device.
operationId: getDeviceBySerial operationId: getDeviceBySerial
tags:
- device
parameters: parameters:
- name: serial - name: serial
in: path in: path
@ -100,6 +124,8 @@ paths:
description: Unexpected Error description: Unexpected Error
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"
security:
- accessTokenAuth: []
/swagger.json: /swagger.json:
x-swagger-pipe: swagger_raw x-swagger-pipe: swagger_raw
definitions: definitions:
@ -145,3 +171,9 @@ definitions:
properties: properties:
message: message:
type: string type: string
securityDefinitions:
accessTokenAuth:
type: apiKey
name: accessTokenAuth
in: header