Implement OAuth2 server, link oauth:Client and auth::Oauth2Client, implement permission checks
This commit is contained in:
136
app/controllers/api/v1/OAuth.controller.js
Normal file
136
app/controllers/api/v1/OAuth.controller.js
Normal file
@@ -0,0 +1,136 @@
|
||||
const { Controller } = require('libflitter')
|
||||
const is_absolute_url = require('is-absolute-url')
|
||||
|
||||
class OAuthController extends Controller {
|
||||
static get services() {
|
||||
return [...super.services, 'models']
|
||||
}
|
||||
|
||||
async get_clients(req, res, next) {
|
||||
const Client = this.models.get('oauth:Client')
|
||||
const clients = await Client.find({ active: true })
|
||||
const data = []
|
||||
|
||||
for ( const client of clients ) {
|
||||
if ( req.user.can(`oauth:client:${client.id}:view`) ) {
|
||||
data.push(await client.to_api())
|
||||
}
|
||||
}
|
||||
|
||||
return res.api(data)
|
||||
}
|
||||
|
||||
async get_client(req, res, next) {
|
||||
const Client = this.models.get('oauth:Client')
|
||||
const client = await Client.findById(req.params.id)
|
||||
|
||||
if ( !client || !client.active )
|
||||
return res.status(404)
|
||||
.message('Client not found with that ID.')
|
||||
.api()
|
||||
|
||||
if ( !req.user.can(`oauth:client:${client.id}:view`) )
|
||||
return res.status(401)
|
||||
.message('Insufficient permissions.')
|
||||
.api()
|
||||
|
||||
return res.api(await client.to_api())
|
||||
}
|
||||
|
||||
async create_client(req, res, next) {
|
||||
if ( !req.user.can('oauth:client:create') )
|
||||
return res.status(401)
|
||||
.message('Insufficient permissions.')
|
||||
.api()
|
||||
|
||||
const required_fields = ['name', 'api_scopes', 'redirect_url']
|
||||
for ( const field of required_fields ) {
|
||||
if ( !req.body[field] )
|
||||
return res.status(400)
|
||||
.message(`Missing required field: ${field}`)
|
||||
.api()
|
||||
}
|
||||
|
||||
if ( !Array.isArray(req.body.api_scopes) ) {
|
||||
return res.status(400)
|
||||
.message(`Improperly formatted field: api_scopes (should be array)`)
|
||||
.api()
|
||||
}
|
||||
|
||||
if ( !is_absolute_url(req.body.redirect_url) )
|
||||
return res.status(400)
|
||||
.message(`Improperly formatted field: redirect_url (should be absolute URL)`)
|
||||
.api()
|
||||
|
||||
const Client = this.models.get('oauth:Client')
|
||||
const client = new Client({
|
||||
name: req.body.name,
|
||||
api_scopes: req.body.api_scopes,
|
||||
redirect_url: req.body.redirect_url,
|
||||
})
|
||||
|
||||
await client.save()
|
||||
return res.api(await client.to_api())
|
||||
}
|
||||
|
||||
async update_client(req, res, next) {
|
||||
const Client = this.models.get('oauth:Client')
|
||||
const client = await Client.findById(req.params.id)
|
||||
|
||||
if ( !client || !client.active )
|
||||
return res.status(404)
|
||||
.message('Client not found with that ID.')
|
||||
.api()
|
||||
|
||||
if ( !req.user.can(`oauth:client:${client.id}:update`) )
|
||||
return res.status(401)
|
||||
.message('Insufficient permissions.')
|
||||
.api()
|
||||
|
||||
const required_fields = ['name', 'api_scopes', 'redirect_url']
|
||||
for ( const field of required_fields ) {
|
||||
if ( !req.body[field] )
|
||||
return res.status(400)
|
||||
.message(`Missing required field: ${field}`)
|
||||
.api()
|
||||
}
|
||||
|
||||
if ( !Array.isArray(req.body.api_scopes) )
|
||||
return res.status(400)
|
||||
.message(`Improperly formatted field: api_scopes (should be array)`)
|
||||
.api()
|
||||
|
||||
if ( !is_absolute_url(req.body.redirect_url) )
|
||||
return res.status(400)
|
||||
.message(`Improperly formatted field: redirect_url (should be absolute URL)`)
|
||||
.api()
|
||||
|
||||
client.name = req.body.name
|
||||
client.api_scopes = req.body.api_scopes
|
||||
client.redirect_url = req.body.redirect_url
|
||||
|
||||
await client.save()
|
||||
return res.api()
|
||||
}
|
||||
|
||||
async delete_client(req, res, next) {
|
||||
const Client = this.models.get('oauth:Client')
|
||||
const client = await Client.findById(req.params.id)
|
||||
|
||||
if ( !client || !client.active )
|
||||
return res.status(404)
|
||||
.message('Client not found with that ID.')
|
||||
.api()
|
||||
|
||||
if ( !req.user.can(`oauth:client:${client.id}:delete`) )
|
||||
return res.status(401)
|
||||
.message('Insufficient permissions.')
|
||||
.api()
|
||||
|
||||
client.active = false
|
||||
await client.save()
|
||||
return res.api()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = OAuthController
|
||||
Reference in New Issue
Block a user