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:
parent
f10ae51b53
commit
221bc78e49
5 changed files with 120 additions and 81 deletions
|
@ -6,7 +6,6 @@ swagger:
|
|||
fittingsDirs: [ fittings ]
|
||||
defaultPipe: null
|
||||
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
|
||||
# (see https://github.com/apigee-127/bagpipes)
|
||||
|
@ -22,10 +21,13 @@ swagger:
|
|||
name: swagger_validator
|
||||
validateResponse: true
|
||||
|
||||
_swagger_security:
|
||||
name: swagger_security
|
||||
securityHandlersModule: helpers/securityHandlers
|
||||
|
||||
# pipe for all swagger-node controllers
|
||||
swagger_controllers:
|
||||
- onError: json_error_handler
|
||||
- cors
|
||||
- swagger_params_parser
|
||||
- swagger_security
|
||||
- _swagger_validate
|
||||
|
|
70
lib/units/api/helpers/securityHandlers.js
Normal file
70
lib/units/api/helpers/securityHandlers.js
Normal 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"
|
||||
})
|
||||
}
|
||||
}
|
|
@ -7,8 +7,6 @@ var cookieSession = require('cookie-session')
|
|||
|
||||
var logger = require('../../util/logger')
|
||||
|
||||
var auth = require('./middleware/auth')
|
||||
|
||||
module.exports = function(options) {
|
||||
var log = logger.createLogger('api')
|
||||
, app = express()
|
||||
|
@ -25,17 +23,19 @@ module.exports = function(options) {
|
|||
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
|
||||
app.use(cookieSession({
|
||||
name: options.ssid
|
||||
, keys: [options.secret]
|
||||
}))
|
||||
|
||||
app.use(auth({
|
||||
secret: options.secret
|
||||
, authUrl: options.authUrl
|
||||
}))
|
||||
|
||||
server.listen(options.port)
|
||||
log.info('Listening on port %d', options.port)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
swagger: "2.0"
|
||||
info:
|
||||
version: "1.0.10"
|
||||
version: "2.0.0"
|
||||
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:
|
||||
name: Apache-2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0
|
||||
contact:
|
||||
url: http://openstf.io/
|
||||
name: STF Support
|
||||
email: contact@openstf.io
|
||||
url: http://openstf.io/
|
||||
basePath: /api/v1
|
||||
schemes:
|
||||
- http
|
||||
|
@ -17,6 +18,11 @@ consumes:
|
|||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
tags:
|
||||
- name: user
|
||||
description: User Operations
|
||||
- name: device
|
||||
description: Device Operations
|
||||
paths:
|
||||
/me:
|
||||
x-swagger-router-controller: user
|
||||
|
@ -24,6 +30,8 @@ paths:
|
|||
summary: User Profile
|
||||
description: The User Profile endpoint returns information about current authorized user.
|
||||
operationId: getCurrentUser
|
||||
tags:
|
||||
- user
|
||||
responses:
|
||||
"200":
|
||||
description: Current User Profile information
|
||||
|
@ -33,6 +41,8 @@ paths:
|
|||
description: Unexpected Error
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
security:
|
||||
- accessTokenAuth: []
|
||||
# TODO: Change group endpoint with something more easy to understandable endpoint
|
||||
/group:
|
||||
x-swagger-router-controller: user
|
||||
|
@ -40,21 +50,27 @@ paths:
|
|||
summary: User Group
|
||||
description: The User Group endpoint returns information about user group of current authorized user.
|
||||
operationId: getCurrentUserGroup
|
||||
tags:
|
||||
- user
|
||||
responses:
|
||||
"200":
|
||||
description: Current User Group information
|
||||
description: Current User's Group information
|
||||
schema:
|
||||
$ref: "#/definitions/GroupResponse"
|
||||
default:
|
||||
description: Unexpected Error
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
security:
|
||||
- accessTokenAuth: []
|
||||
/accessTokens:
|
||||
x-swagger-router-controller: token
|
||||
get:
|
||||
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
|
||||
tags:
|
||||
- user
|
||||
responses:
|
||||
"200":
|
||||
description: Access Tokens titles
|
||||
|
@ -64,12 +80,16 @@ paths:
|
|||
description: Unexpected Error
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
security:
|
||||
- accessTokenAuth: []
|
||||
/devices:
|
||||
x-swagger-router-controller: device
|
||||
get:
|
||||
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
|
||||
tags:
|
||||
- device
|
||||
responses:
|
||||
"200":
|
||||
description: List of Devices
|
||||
|
@ -79,12 +99,16 @@ paths:
|
|||
description: Unexpected Error
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
security:
|
||||
- accessTokenAuth: []
|
||||
/devices/{serial}:
|
||||
x-swagger-router-controller: device
|
||||
get:
|
||||
summary: Device Information
|
||||
description: Device Information
|
||||
description: The device enpoint return information about a single device.
|
||||
operationId: getDeviceBySerial
|
||||
tags:
|
||||
- device
|
||||
parameters:
|
||||
- name: serial
|
||||
in: path
|
||||
|
@ -100,6 +124,8 @@ paths:
|
|||
description: Unexpected Error
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
security:
|
||||
- accessTokenAuth: []
|
||||
/swagger.json:
|
||||
x-swagger-pipe: swagger_raw
|
||||
definitions:
|
||||
|
@ -145,3 +171,9 @@ definitions:
|
|||
properties:
|
||||
message:
|
||||
type: string
|
||||
|
||||
securityDefinitions:
|
||||
accessTokenAuth:
|
||||
type: apiKey
|
||||
name: accessTokenAuth
|
||||
in: header
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue