const Oauth2Controller = require('flitter-auth/controllers/Oauth2') /* * Handles views, processing, and data retrieval for flitter-auth's * built-in OAuth2 server, if it is enabled. Most handlers are inherited * from flitter-auth/controllers/Oauth2, but you can override them here * as you need. */ class Oauth2 extends Oauth2Controller { static get services() { return [...super.services, 'Vue', 'configs', 'models', 'output'] } async authorize_post(req, res, next) { const client = await this._get_authorize_client({query: req.body}) if ( !client ) return this._uniform(res, req.T('auth.unable_to_authorize')) const StarshipClient = this.models.get('oauth:Client') const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID }) // Make sure the user has IAM access before proceeding const Application = this.models.get('Application') const Policy = this.models.get('iam:Policy') const application = await Application.findOne({ oauth_client_ids: starship_client.id }) if ( !application ) { this.output.warn(`IAM Denial: OAuth client not associated with an application: ${starship_client.id}`) return this.Vue.auth_message(res, { message: req.T('saml.no_access').replace('APP_NAME', application.name), next_destination: '/dash', }) } else if ( !(await Policy.check_user_access(req.user, application.id)) ) { this.output.warn(`IAM Denial: User ${req.user.uid} not authorized to access application: ${application.id}`) return this.Vue.auth_message(res, { message: req.T('saml.no_access').replace('APP_NAME', application.name), next_destination: '/dash', }) } req.user.authorize(starship_client) await req.user.save() return super.authorize_post(req, res, next) } async authorize_get(req, res, next) { const client = await this._get_authorize_client(req) if ( !client ) return this._uniform(res, req.T('auth.unable_to_authorize')) const uri = new URL(Array.isArray(req.query.redirect_uri) ? req.query.redirect_uri[0] : req.query.redirect_uri) const StarshipClient = this.models.get('oauth:Client') const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID }) // Make sure the user has IAM access before proceeding const Application = this.models.get('Application') const Policy = this.models.get('iam:Policy') const application = await Application.findOne({ oauth_client_ids: starship_client.id }) if ( !application ) { this.output.warn(`IAM Denial: OAuth client not associated with an application: ${starship_client.id}`) return this.Vue.auth_message(res, { message: req.T('saml.no_access').replace('APP_NAME', application.name), next_destination: '/dash', }) } else if ( !(await Policy.check_user_access(req.user, application.id)) ) { this.output.warn(`IAM Denial: User ${req.user.uid} not authorized to access application: ${application.id}`) return this.Vue.auth_message(res, { message: req.T('saml.no_access').replace('APP_NAME', application.name), next_destination: '/dash', }) } let state; if ( state = (req.query.state || req.body.state) ) { state = Array.isArray(req.query.state) ? req.query.state[0] : req.query.state const uri_params = new URLSearchParams(uri.params) uri_params.set('state', state) } if ( req.user.has_authorized(starship_client) ) { return this.Vue.invoke_action(res, { text: 'Grant Access', action: 'post', params: { redirect_uri: uri.toString(), client_id: client.clientID, }, }) } return res.page('public:message', { ...this.Vue.data({ message: `

Authorize ${client.name}?


${req.T('auth.oauth_prompt').replace('CLIENT_NAME', client.name).replace('APP_NAME', this.configs.get('app.name'))}


${req.T('auth.will_redirect')} ${uri.host}`, actions: [ { text: req.T('common.deny'), action: 'redirect', next: '/dash', }, { text: req.T('common.grant'), action: 'post', params: { redirect_uri: uri.toString(), client_id: client.clientID, }, }, ], }) }) } } module.exports = exports = Oauth2