You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CoreID/app/controllers/saml/SAML.controller.js

94 lines
3.7 KiB

const { Controller } = require('libflitter')
const FlitterProfileMapper = require('../../classes/saml/FlitterProfileMapper')
const samlp = require('samlp')
class SAMLController extends Controller {
static get services() {
return [...super.services, 'saml', 'output', 'Vue', 'configs', 'models']
}
async get_metadata(req, res, next) {
return samlp.metadata({
issuer: this.saml.config().provider_name,
cert: await this.saml.public_cert(),
logoutEndpointPaths: {
redirect: '/saml/logout',
},
redirectEndpointPath: '/saml/sso',
postEndpointPath: '/saml/sso',
})(req, res, next)
}
async get_sso(req, res, next) {
const index = await req.saml.participants.issue({ service_provider: req.saml_request.service_provider })
// Apply the appropriate IAM policy if this SAML SP is associated with an App
// If the SAML service provider has no associated application, just allow it
// TODO test this
const associated_app = await req.saml_request.service_provider.application()
if ( associated_app ) {
const Policy = this.models.get('iam:Policy')
const can_access = await Policy.check_user_access(req.user, associated_app.id)
if ( !can_access ) {
return this.Vue.auth_message(res, {
message: req.T('saml.no_access').replace('APP_NAME', associated_app.name),
next_destination: '/dash',
})
}
}
return samlp.auth({
issuer: this.saml.config().provider_name,
cert: await this.saml.public_cert(),
key: await this.saml.private_key(),
getPostURL: (wtrealm, wreply, req, callback) => {
this.output.debug(`${req.T('saml.redirect_url')} ${req.saml_request.service_provider.acs_url}`)
return callback(null, req.saml_request.service_provider.acs_url) // fetch this from registered SAML app
},
profileMapper: user => new FlitterProfileMapper(user),
destination: req.saml_request.service_provider.acs_url,
sessionIndex: index,
})(req, res, next)
}
async post_logout(req, res, next) {
return res.api({
saml: req.saml_request,
body: req.body,
query: req.query,
})
}
async get_logout(req, res, next) {
return samlp.logout({
deflate: true,
issuer: this.saml.config().provider_name,
cert: await this.saml.public_cert(),
key: await this.saml.private_key(),
protocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
clearIdPSession: done => {
this.output.info(`${req.T('saml.clear_idp_session')} ${req.user.uid.toLowerCase()}`)
req.saml.participants.clear().then(async () => {
if ( this.saml.config().slo.end_coreid_session ) {
await req.user.logout(req)
// show logout page
return this.Vue.auth_message(res, {
message: req.T('auth.logged_out'),
next_destination: '/',
})
} else {
return this.Vue.auth_message(res, {
message: req.T('auth.logged_out'),
next_destination: '/',
})
}
})
},
sessionParticipants: await req.saml.participants.wrapper(),
})(req, res, next)
}
}
module.exports = exports = SAMLController