2024-10-21 08:11:34 +00:00
|
|
|
import ch.nevis.esauth.auth.engine.AuthResponse
|
|
|
|
import groovy.xml.XmlSlurper
|
|
|
|
|
|
|
|
|
|
|
|
// AGOVaq conversion
|
|
|
|
def minLoiRoleToCtxClssConvertorMap = [
|
|
|
|
"level100": "urn:qa.agov.ch:names:tc:ac:classes:100",
|
|
|
|
"level200": "urn:qa.agov.ch:names:tc:ac:classes:200",
|
|
|
|
"level300": "urn:qa.agov.ch:names:tc:ac:classes:300",
|
|
|
|
"level400": "urn:qa.agov.ch:names:tc:ac:classes:400",
|
|
|
|
"level500": "urn:qa.agov.ch:names:tc:ac:classes:500"
|
|
|
|
]
|
|
|
|
|
|
|
|
def cleanSession() {
|
|
|
|
def s = request.getAuthSession(true)
|
|
|
|
|
|
|
|
s.removeAttribute('agov.op.onboarding.ctxClass')
|
|
|
|
s.removeAttribute('agov.op.onboarding.minLoi')
|
|
|
|
s.removeAttribute('agov.op.onboarding.homeName')
|
|
|
|
s.removeAttribute('agov.op.onboarding.subject')
|
|
|
|
s.removeAttribute('agov.op.onboarding.process.state')
|
|
|
|
s.removeAttribute('ch.adnovum.nevisidm.userDto')
|
|
|
|
s.removeAttribute('saml.response.statusCode')
|
|
|
|
if (response.getActualRoles().length > 0) {
|
|
|
|
def actualRoles = Arrays.copyOf(response.getActualRoles(), response.getActualRoles().length)
|
|
|
|
actualRoles.each{ role -> response.removeActualRole(role) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// for autditing
|
|
|
|
def user = session['ch.adnovum.nevisidm.user.extId'] ?: 'unknown'
|
|
|
|
def sourceIp = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown'
|
|
|
|
def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown'
|
|
|
|
def minLoi = 'unknown'
|
|
|
|
|
|
|
|
// 1) makes sure, that we are or were invoked with a correct URL ticket, set error code, if not
|
|
|
|
if (inargs['cd'] == null && session['agov.op.onboarding.code'] == null) {
|
|
|
|
response.setNote('lasterror', '9901')
|
|
|
|
response.setNote('lasterrorinfo', 'valid on-boarding link required')
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2a) if code as query param, store it to the session, and redirect
|
|
|
|
if (inargs['cd'] != null) {
|
|
|
|
// make sure, we are clean to be able to start over
|
|
|
|
cleanSession()
|
|
|
|
|
|
|
|
response.setSessionAttribute('agov.op.onboarding.code', inargs['cd'])
|
|
|
|
response.setStatus(AuthResponse.AUTH_CONTINUE)
|
|
|
|
response.setTransferDestination('/AUTH/ONBOARDING/')
|
|
|
|
response.setIsRedirectTransfer(true)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2b) clean the url, if necessary
|
|
|
|
if (request.currentResource.replaceAll('^https:\\/\\/[^\\/]+\\/AUTH\\/ONBOARDING\\/', '').length() > 0) {
|
|
|
|
|
2024-11-29 09:05:47 +00:00
|
|
|
if (inargs['language'] && inargs['language'] != session['ch.nevis.session.user.language']) {
|
|
|
|
// language change, set the language cookie
|
|
|
|
def langCookie = "LANG=${inargs['language']}; Domain=${parameters.get('cookie.domain')}; Path=/"
|
|
|
|
response.setHeader('Set-Cookie', langCookie)
|
|
|
|
}
|
|
|
|
|
2024-10-21 08:11:34 +00:00
|
|
|
response.setStatus(AuthResponse.AUTH_CONTINUE)
|
|
|
|
response.setTransferDestination('/AUTH/ONBOARDING/')
|
|
|
|
response.setIsRedirectTransfer(true)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3) if SAMLResponse available, process it
|
|
|
|
if (inargs['SAMLResponse'] != null) {
|
|
|
|
// we don't use a RelayState, make sure he is ignored
|
|
|
|
request.getInArgs().remove("RelayState")
|
|
|
|
response.setResult('processResponse')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4) check if we could already validate the ticket, and load the user
|
|
|
|
if (session['ch.adnovum.nevisidm.userDto'] != null && notes['lasterror'] == null) {
|
|
|
|
try {
|
|
|
|
def userDto = new XmlSlurper().parseText(session['ch.adnovum.nevisidm.userDto'])
|
|
|
|
def userState = userDto.state
|
|
|
|
|
|
|
|
if (userState == 'ACTIVE') {
|
|
|
|
def minLoiList = userDto.'**'.findAll { node -> node.name() == 'roles' && node.applicationName.text() == 'OP-MinLoi' }.collect({ node -> node.name.text() }).sort()
|
|
|
|
minLoi = minLoiList.isEmpty() ? null : minLoiList.first()
|
|
|
|
|
|
|
|
if (minLoi != null) {
|
|
|
|
response.setSessionAttribute('agov.op.onboarding.minLoi', minLoi)
|
|
|
|
if (minLoiRoleToCtxClssConvertorMap.containsKey(minLoi)) {
|
|
|
|
response.setSessionAttribute('agov.op.onboarding.ctxClass', minLoiRoleToCtxClssConvertorMap[minLoi])
|
|
|
|
} else {
|
|
|
|
LOG.warn("OP-ONBOARDING: Failed to convert '${minLoi}' to AGOVaq, taking 'urn:qa.agov.ch:names:tc:ac:classes:100'")
|
|
|
|
response.setSessionAttribute('agov.op.onboarding.ctxClass', "urn:qa.agov.ch:names:tc:ac:classes:100")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
LOG.debug("OP-ONBOARDING: no 'OP-MinLoi'-role assigned to user ${user}, using AGOVaq100")
|
|
|
|
minLoi = "level100"
|
|
|
|
response.setSessionAttribute('agov.op.onboarding.minLoi', "level100")
|
|
|
|
response.setSessionAttribute('agov.op.onboarding.ctxClass', "urn:qa.agov.ch:names:tc:ac:classes:100")
|
|
|
|
}
|
|
|
|
LOG.info("Event='OP-AUTHNREQ', RequestedAq='${minLoi}', User=${user}, SourceIp=${sourceIp}, UserAgent=${userAgent}")
|
|
|
|
response.setResult('sendAuthnRequest')
|
|
|
|
} else {
|
|
|
|
// state != ACTIVE and no lasterror should not happen
|
|
|
|
LOG.error("On boarding ticket processing failed: state='${userState}' but not lasterror set")
|
|
|
|
response.setNote('lasterror', '9909')
|
|
|
|
response.setNote('lasterrorinfo', 'internal error')
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
LOG.error("On boarding ticket processing failed: Exception " + e)
|
|
|
|
response.setNote('lasterror', '9909')
|
|
|
|
response.setNote('lasterrorinfo', 'internal error')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 5) validate URL Ticket?
|
|
|
|
if (inargs['submit'] != null && notes['verifyTicket'] == null) {
|
|
|
|
response.setNote('verifyTicket', 'go')
|
|
|
|
response.setResult('verifyTicket')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 6) if we reach that point, display the GUI
|
|
|
|
if (response.getNote('lasterror') != null) {
|
|
|
|
minLoi = session['agov.op.onboarding.minLoi'] ?: 'unknown'
|
|
|
|
LOG.info("Event='OP-FAILED', RequestedAq='${minLoi}', User=${user}, SourceIp=${sourceIp}, UserAgent=${userAgent}, lasterror=${response.getNote('lasterror')}, lasterrorinfo='${response.getNote('lasterrorinfo')}'")
|
|
|
|
cleanSession()
|
|
|
|
}
|
|
|
|
|
|
|
|
response.setStatus(AuthResponse.AUTH_CONTINUE)
|