Implement OAuth2 server, link oauth:Client and auth::Oauth2Client, implement permission checks
This commit is contained in:
@@ -2,6 +2,16 @@ const { Middleware } = require('libflitter')
|
||||
|
||||
class PermissionMiddleware extends Middleware {
|
||||
async test(req, res, next, { check }) {
|
||||
// If the request was authorized using an OAuth2 bearer token,
|
||||
// make sure the associated client has permission to access this endpoint.
|
||||
if ( req?.oauth?.client ) {
|
||||
if ( !req.oauth.client.can(check) )
|
||||
return res.status(401)
|
||||
.message('Insufficient permissions (OAuth2 Client).')
|
||||
.api()
|
||||
}
|
||||
|
||||
// Make sure the user has permission
|
||||
if ( !req.user.can(check) )
|
||||
return res.status(401)
|
||||
.message('Insufficient permissions.')
|
||||
|
||||
60
app/routing/middleware/auth/APIRoute.middleware.js
Normal file
60
app/routing/middleware/auth/APIRoute.middleware.js
Normal file
@@ -0,0 +1,60 @@
|
||||
const { Middleware } = require('libflitter')
|
||||
|
||||
class APIRouteMiddleware extends Middleware {
|
||||
static get services() {
|
||||
return [...super.services, 'models']
|
||||
}
|
||||
|
||||
async test(req, res, next, { allow_token = true, allow_user = true }) {
|
||||
// First, check if there is a user in the session.
|
||||
if ( allow_user && req.is_auth ) {
|
||||
return next()
|
||||
} else if ( allow_token ) {
|
||||
return req.app.oauth2.authorise()(req, res, async e => {
|
||||
if ( e ) return next(e)
|
||||
// Look up the OAuth2 client an inject it into the route
|
||||
if ( req.user && req.user.id ) {
|
||||
const User = this.models.get('auth:User')
|
||||
const user = await User.findById(req.user.id)
|
||||
if ( !user )
|
||||
return res.status(401)
|
||||
.message('The user this token is associated with no longer exists.')
|
||||
.api()
|
||||
|
||||
req.user = user
|
||||
req.is_auth = true
|
||||
|
||||
// Look up the token and the associated client
|
||||
const Oauth2BearerToken = this.models.get('auth::Oauth2BearerToken')
|
||||
const Client = this.models.get('oauth:Client')
|
||||
|
||||
// e.g. "Bearer XYZ".split(' ')[1] -> "XYZ"
|
||||
const bearer = req.headers.authorization.split(' ')[1]
|
||||
const token = await Oauth2BearerToken.findOne({ accessToken: bearer })
|
||||
if ( !token )
|
||||
return res.status(401)
|
||||
.message('Unable to lookup OAuth2 token.')
|
||||
.api()
|
||||
|
||||
const client = await Client.findOne({uuid: token.clientID})
|
||||
if ( !client )
|
||||
return res.status(401)
|
||||
.message('This OAuth2 client is no longer authorized.')
|
||||
.api()
|
||||
|
||||
req.oauth.token = token
|
||||
req.oauth.client = client
|
||||
} else
|
||||
return res.status(401)
|
||||
.message('Unable to lookup user associated with that token.')
|
||||
.api()
|
||||
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
return res.status(401).api()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = APIRouteMiddleware
|
||||
Reference in New Issue
Block a user