const { Controller } = require('libflitter') class SAMLController extends Controller { static get services() { return [...super.services, 'models'] } async get_providers(req, res, next) { const ServiceProvider = this.models.get('saml:ServiceProvider') const providers = await ServiceProvider.find({ active: true }) const visible = providers.filter(x => req.user.can(`saml:provider:${x.id}:view`)) .map(x => x.to_api()) return res.api(visible) } async get_provider(req, res, next) { const ServiceProvider = this.models.get('saml:ServiceProvider') const provider = await ServiceProvider.findById(req.params.id) if ( !provider || !provider.active ) return res.status(404).api() if ( !req.user.can(`saml:provider:${provider.id}:view`) ) return res.status(401).api() return res.api(provider.to_api()) } async create_provider(req, res, next) { const ServiceProvider = this.models.get('saml:ServiceProvider') const required_fields = ['name', 'entity_id', 'acs_url'] for ( const field of required_fields ) { if ( !req.body[field]?.trim() ) return res.status(400) .message(`Missing required field: ${field}`) .api() } // The entity_id must be unique const existing_provider = await ServiceProvider.findOne({ entity_id: req.body.entity_id, active: true, }) if ( existing_provider ) return res.status(400) .send(`A service provider with that entity_id already exists.`) .api() const data = { name: req.body.name, entity_id: req.body.entity_id, acs_url: req.body.acs_url, active: true, } if ( req.body.slo_url ) data.slo_url = req.body.slo_url const provider = new ServiceProvider(data) await provider.save() req.user.allow(`saml:provider:${provider.id}`) await req.user.save() return res.api(provider.to_api()) } async update_provider(req, res, next) { const ServiceProvider = this.models.get('saml:ServiceProvider') const provider = await ServiceProvider.findById(req.params.id) if ( !provider || !provider.active ) return res.status(404).api() if ( !req.user.can(`saml:provider:${provider.id}:update`) ) return res.status(401).api() const required_fields = ['name', 'entity_id', 'acs_url'] for ( const field of required_fields ) { if ( !req.body[field].trim() ) return res.status(400) .message(`Missing required field: ${field}`) .api() } // Make sure the entity_id won't cause a collision const duplicate_providers = await ServiceProvider.find({ entity_id: req.body.entity_id, _id: { $ne: provider._id }, }) if ( duplicate_providers.length > 0 ) return res.status(400) .message('A service provider already exists with that entity_id.') .api() // Update the record provider.name = req.body.name provider.entity_id = req.body.entity_id provider.acs_url = req.body.acs_url provider.slo_url = req.body.slo_url await provider.save() return res.api() } async delete_provider(req, res, next) { const ServiceProvider = this.models.get('saml:ServiceProvider') const provider = await ServiceProvider.findById(req.params.id) if ( !provider || !provider.active ) return res.status(404).api() if ( !req.user.can(`saml:provider:${provider.id}:delete`) ) return res.status(401).api() provider.active = false await provider.save() return res.api() } } module.exports = exports = SAMLController