From 9669ab54de450f9b683fdd7aa8a175ee72b27c5e Mon Sep 17 00:00:00 2001 From: haburger Date: Mon, 8 Dec 2025 17:22:53 +0000 Subject: [PATCH] new configuration version --- ...8s-nevisauth-ac27dd7daad0ca2b7229bfaf.yaml | 2 +- .../default/conf/EncodeAndDisplayToken.groovy | 19 ++ .../opt/nevisauth/default/conf/esauth4.xml | 316 ++++++++++++++++-- .../default/conf/selectIdmProfile.groovy | 74 ++++ .../set_userextid_groovy_script_step.groovy | 59 ++++ 5 files changed, 449 insertions(+), 21 deletions(-) create mode 100644 DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/EncodeAndDisplayToken.groovy create mode 100644 DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/selectIdmProfile.groovy create mode 100644 DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/set_userextid_groovy_script_step.groovy diff --git a/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/etc/nevis/k8s-nevisauth-ac27dd7daad0ca2b7229bfaf.yaml b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/etc/nevis/k8s-nevisauth-ac27dd7daad0ca2b7229bfaf.yaml index 38ac436..007acd6 100644 --- a/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/etc/nevis/k8s-nevisauth-ac27dd7daad0ca2b7229bfaf.yaml +++ b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/etc/nevis/k8s-nevisauth-ac27dd7daad0ca2b7229bfaf.yaml @@ -46,7 +46,7 @@ spec: podDisruptionBudget: maxUnavailable: "50%" git: - tag: "r-28d025621af8913de776f24a3d4921835e1af78e" + tag: "r-52cf67aa5ec5c56333d2605f507c60bb29159968" dir: "DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth" credentials: "git-credentials" keystores: diff --git a/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/EncodeAndDisplayToken.groovy b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/EncodeAndDisplayToken.groovy new file mode 100644 index 0000000..2679729 --- /dev/null +++ b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/EncodeAndDisplayToken.groovy @@ -0,0 +1,19 @@ +import ch.nevis.esauth.auth.engine.AuthResponse +import ch.nevis.esauth.util.httpclient.api.HttpClient + +if (outargs['out.JWTToken']) { + // we have a token + def header = "Bearer ${outargs['out.JWTToken']}" + response.setNote('agov.test.token', header) + notes.setProperty('agov.test.token', header) + response.removeOutArg('out.JWTToken') +} + +// if (!response.getNote('agov.test.token')) { +// response.setResult('newToken') +// return +//} + + +// show the GUI +response.setResult('display') diff --git a/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml index cc247ab..c5bdf4d 100644 --- a/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml +++ b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml @@ -105,7 +105,7 @@ - + @@ -131,11 +131,14 @@ - - - + + + + + + - + @@ -362,7 +365,7 @@ - + @@ -378,21 +381,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + @@ -598,12 +802,6 @@ - - - - - - @@ -1084,6 +1282,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1095,6 +1361,16 @@ + + + + + + + + + + diff --git a/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/selectIdmProfile.groovy b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/selectIdmProfile.groovy new file mode 100644 index 0000000..4951a61 --- /dev/null +++ b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/selectIdmProfile.groovy @@ -0,0 +1,74 @@ +import groovy.xml.XmlSlurper + +def idmSeverityRoleMap = [ + "EnterpriseRoleAdmin": [11, "op-idmlogin.role.accs-mgmt-idm"], + "ClientRoot": [12, "op-idmlogin.role.support-priv"], + "AppAdmin": [20, "op-idmlogin.role.idmcfg-mgmt"], + "AppOwner": [5, "op-idmlogin.role.accs-mgmt-nonidm"], + "UserAndUnitAdmin": [7, "op-idmlogin.role.usr-unit-mgmt"], + "UserAdmin": [6, "op-idmlogin.role.usr-mgmt"], + "TemplateAdmin": [10, "op-idmlogin.role.support-basic"], + "Helpdesk": [1, "op-idmlogin.role.readonly-access" ] +] + +try { + def dtoString = session['ch.adnovum.nevisidm.userDto'] + + def idmDto = new XmlSlurper().parseText(dtoString) + def idmPrfMap = idmDto.'**'.findAll + { prf -> prf.name() == 'profiles' + && prf.'**'.find + { role -> role.name() == 'roles' + && role.applicationName.text() == 'nevisIdm' + } + }.collectEntries { prf -> [ prf.extId.text(), + prf.'**'.findAll + { role -> role.name() == 'roles' + && role.applicationName.text() == 'nevisIdm' + }.collect{ rolePrioEntry -> idmSeverityRoleMap[rolePrioEntry.name.text()] ?: [1000, "DO-NOT-USE(${rolePrioEntry.name.text()})"] + }.sort { a, b -> a[0] <=> b[0] // sort by severity + }.last()[1] // take label of the ighest one + ] } + + if ((inargs.getProperty('submit', '') == 'go') && idmPrfMap.containsKey(inargs.getProperty('profile_selection', 'missing'))) { + + // user selected a profile which exists, we take it + def operationsProfileExtId = inargs.getProperty('profile_selection', 'missing') + LOG.info("User selected profile: ${operationsProfileExtId} '${idmPrfMap.get(operationsProfileExtId)}'") + response.setSessionAttribute('operationsProfileExtId', '' + operationsProfileExtId) + response.setResult('ok') + return + + } else if (idmPrfMap.size() == 1) { + + // we take the only profile, with an IDM role + def operationsProfileExtId = idmPrfMap.keySet().first() + LOG.info("taking the only profile with an idm role: ${operationsProfileExtId} '${idmPrfMap.get(operationsProfileExtId)}'") + response.setSessionAttribute('operationsProfileExtId', '' + operationsProfileExtId) + response.setResult('ok') + return + + } else if (idmPrfMap.isEmpty()) { + + // no profile with an IDM role, do nothing + response.setResult('ok') + return + + } else { + + // user should select a profile + response.setGuiName('op_idmlogin_select_profile') + idmPrfMap.each { + response.addRadioGuiField('profile_selection', it.value, it.key) + } + response.addButtonGuiField('submit', 'general.continue', 'go') + + response.setStatus(ch.nevis.esauth.auth.engine.AuthResponse.AUTH_CONTINUE) + return + } +} catch (Exception e) { + def errorMsg = "Failed to process profile selection: ${e.getMessage()}" + LOG.error(errorMsg, e) + response.setError(9901, errorMsg) + response.setResult('error') +} \ No newline at end of file diff --git a/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/set_userextid_groovy_script_step.groovy b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/set_userextid_groovy_script_step.groovy new file mode 100644 index 0000000..1fdd29c --- /dev/null +++ b/DEFAULT-ADN-AGOV-ADMIN-PROJECT/DEFAULT-ADN-AGOV-ADMIN-INV/auth/var/opt/nevisauth/default/conf/set_userextid_groovy_script_step.groovy @@ -0,0 +1,59 @@ +try { + def s = request.getAuthSession(true) + + LOG.debug("operationsExtId: ${notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserExtId']}") + LOG.debug("operationsUserProfileExtIdList: ${notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserProfileExtId']}") + + // set operation's account extId and profile extid + if (notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserExtId'] == null || notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserProfileExtId'] == null) { + LOG.error("[OPACCESS] User ${notes['saml.assertion.subject']} tried to access without operations account or profile") + response.setResult('error'); + return + } + + response.setSessionAttribute('operationsExtId', notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserExtId']) + + // extract additional attributes from assertion in session + if (notes['saml.attributes.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname']) { + response.setSessionAttribute('idp.firstName', notes['saml.attributes.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname']) + } + if (notes['saml.attributes.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname']) { + response.setSessionAttribute('idp.lastName', notes['saml.attributes.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname']) + } + if (notes['saml.attributes.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress']) { + response.setSessionAttribute('idp.email', notes['saml.attributes.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress']) + } + if (notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/languageOfCorrespondance']) { + response.setSessionAttribute('idp.language', notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/languageOfCorrespondance']) + } + + // we take the first one, if there is no profile in the operations unit + def unitAndProfileExtidPar = notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserProfileExtId'] + .split(',').find{pairstr -> pairstr.split("\\\\")[1] == "130274ee-7e24-4050-9b94-d5717ef52ade" } + ?: notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserProfileExtId'].split(',')[0] + + if (! unitAndProfileExtidPar.contains('130274ee-7e24-4050-9b94-d5717ef52ade') ) + { + LOG.info("[OPACCESS] User ${notes['saml.assertion.subject']} with opaccount ${notes['saml.attributes.http://schemas.agov.ch/ws/2023/05/identity/claims/operationsUserExtId']} has no operations profile, we use the first one") + } + response.setSessionAttribute('operationsProfileExtId', unitAndProfileExtidPar.split("\\\\")[0]) + + // ad role based on agov aq level + def acrToRoleMap = [ 'urn:qa.agov.ch:names:tc:ac:classes:100':'AGOV-Loi.level100', + 'urn:qa.agov.ch:names:tc:ac:classes:200':'AGOV-Loi.level200', + 'urn:qa.agov.ch:names:tc:ac:classes:300':'AGOV-Loi.level300', + 'urn:qa.agov.ch:names:tc:ac:classes:400':'AGOV-Loi.level400', + 'urn:qa.agov.ch:names:tc:ac:classes:500':'AGOV-Loi.level500' + ] + + if (acrToRoleMap[session['ch.nevis.auth.saml.assertion.authnContextClassRef']?='none']) { + response.addActualRole(acrToRoleMap[session['ch.nevis.auth.saml.assertion.authnContextClassRef']]) + } + + + response.setResult('ok'); + +} catch(Exception ex) { + LOG.warn("Exception in selectProfile groovy script: " + ex) + response.setResult('error'); +}