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(`${req.T('api.missing_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(req.T('api.provider_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(`${req.T('api.missing_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(api.T('api.provider_already_exists')) .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