diff --git a/bundles.yml b/bundles.yml index 00bcb0f..53b970a 100644 --- a/bundles.yml +++ b/bundles.yml @@ -1,12 +1,12 @@ schemaVersion: "1.0" bundles: -- "nevisadmin-plugin-oauth:8.2405.2.0" -- "nevisadmin-plugin-authcloud:8.2405.2.0" -- "nevisadmin-plugin-nevisidm:8.2405.2.0" -- "nevisadmin-plugin-mobile-auth:8.2405.2.0" -- "nevisadmin-plugin-fido2:8.2405.2.0" -- "nevisadmin-plugin-nevisdp:8.2405.2.0" -- "nevisadmin-plugin-nevisauth:8.2405.2.0" -- "nevisadmin-plugin-nevisproxy:8.2405.2.0" -- "nevisadmin-plugin-nevisdetect:8.2405.2.0" - "nevisadmin-plugin-base-generation:8.2405.2.0" +- "nevisadmin-plugin-oauth:8.2405.2.0" +- "nevisadmin-plugin-nevisdetect:8.2405.2.0" +- "nevisadmin-plugin-nevisauth:8.2405.2.0" +- "nevisadmin-plugin-nevisdp:8.2405.2.0" +- "nevisadmin-plugin-nevisproxy:8.2405.2.0" +- "nevisadmin-plugin-mobile-auth:8.2405.2.0" +- "nevisadmin-plugin-nevisidm:8.2405.2.0" +- "nevisadmin-plugin-fido2:8.2405.2.0" +- "nevisadmin-plugin-authcloud:8.2405.2.0" diff --git a/patterns/1f0702aaabef60a615abf41f_resources/resources.zip b/patterns/1f0702aaabef60a615abf41f_resources/resources.zip index e1f1243..849e62a 100644 Binary files a/patterns/1f0702aaabef60a615abf41f_resources/resources.zip and b/patterns/1f0702aaabef60a615abf41f_resources/resources.zip differ diff --git a/patterns/204c22beaccdfd22727af378_labels/labels.zip b/patterns/204c22beaccdfd22727af378_labels/labels.zip index b5e50e9..c28e7e4 100644 Binary files a/patterns/204c22beaccdfd22727af378_labels/labels.zip and b/patterns/204c22beaccdfd22727af378_labels/labels.zip differ diff --git a/patterns/204c22beaccdfd22727af378_template/webdata.zip b/patterns/204c22beaccdfd22727af378_template/webdata.zip index 2bb59b1..51c06d0 100644 Binary files a/patterns/204c22beaccdfd22727af378_template/webdata.zip and b/patterns/204c22beaccdfd22727af378_template/webdata.zip differ diff --git a/patterns/4fcfadb4a5c946ead7e6e995_labels/labels.zip b/patterns/4fcfadb4a5c946ead7e6e995_labels/labels.zip index b5e50e9..c28e7e4 100644 Binary files a/patterns/4fcfadb4a5c946ead7e6e995_labels/labels.zip and b/patterns/4fcfadb4a5c946ead7e6e995_labels/labels.zip differ diff --git a/patterns/4fcfadb4a5c946ead7e6e995_template/webdata.zip b/patterns/4fcfadb4a5c946ead7e6e995_template/webdata.zip index 2bb59b1..51c06d0 100644 Binary files a/patterns/4fcfadb4a5c946ead7e6e995_template/webdata.zip and b/patterns/4fcfadb4a5c946ead7e6e995_template/webdata.zip differ diff --git a/patterns/584964c837512845d7940809_authStatesFile/recovery-preprocessing.xml b/patterns/584964c837512845d7940809_authStatesFile/recovery-preprocessing.xml index ea99217..207fa9c 100644 --- a/patterns/584964c837512845d7940809_authStatesFile/recovery-preprocessing.xml +++ b/patterns/584964c837512845d7940809_authStatesFile/recovery-preprocessing.xml @@ -5,14 +5,6 @@ - - - - - - - - @@ -36,11 +28,6 @@ - - - - - @@ -113,13 +100,6 @@ - - - - - - - diff --git a/patterns/68665057549fd887ea09fb86_scriptFile/requestedRoleLevel.groovy b/patterns/68665057549fd887ea09fb86_scriptFile/requestedRoleLevel.groovy index edc4fe7..059c687 100644 --- a/patterns/68665057549fd887ea09fb86_scriptFile/requestedRoleLevel.groovy +++ b/patterns/68665057549fd887ea09fb86_scriptFile/requestedRoleLevel.groovy @@ -1,8 +1,6 @@ import groovy.xml.XmlSlurper import groovy.json.JsonSlurper -//import ch.nevis.esauth.util.httpclient.api.HttpClients -//import ch.nevis.esauth.util.httpclient.api.Http - +import io.opentelemetry.api.trace.Span int getRequestedLevel(String authnContextClassRef, def roleList){ if (!authnContextClassRef) { @@ -58,11 +56,13 @@ if (requestedRoleLevelNumber == 0 || session.get('ch.nevis.auth.saml.request.sco } try { + def spanCtxt = Span.current().getSpanContext() + def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}" def jsonSlurper = new JsonSlurper() def url = parameters.get('url') + '?entity-id=' + session.get('ch.nevis.auth.saml.request.scoping.requesterId') LOG.debug('Request url: ' + url) def httpClient = HttpClients.create(parameters) - def httpResponse = Http.get().url(url).build().send(httpClient) + def httpResponse = Http.get().url(url).header('traceparent', traceparent).build().send(httpClient) LOG.debug('Response Message: ' + httpResponse.reasonPhrase()) LOG.debug('Response Status Code: ' + httpResponse.code()) LOG.debug('Response: ' + httpResponse.bodyAsString()) diff --git a/patterns/699f22cf1cd4ad08bd973f31_scriptFile/fido2_fetchCaptchaResult.gy b/patterns/699f22cf1cd4ad08bd973f31_scriptFile/fido2_fetchCaptchaResult.groovy similarity index 51% rename from patterns/699f22cf1cd4ad08bd973f31_scriptFile/fido2_fetchCaptchaResult.gy rename to patterns/699f22cf1cd4ad08bd973f31_scriptFile/fido2_fetchCaptchaResult.groovy index a9682b0..ee09bbe 100644 --- a/patterns/699f22cf1cd4ad08bd973f31_scriptFile/fido2_fetchCaptchaResult.gy +++ b/patterns/699f22cf1cd4ad08bd973f31_scriptFile/fido2_fetchCaptchaResult.groovy @@ -1,101 +1,63 @@ -def url = parameters.get('url') - -def email = inargs['userInputValue_prompt.email'] -def token = inargs['captcha_response']?: 'MISSING' - -def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown' -def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown' - -def payload = "{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }" - -LOG.debug('Token: ' + token) -LOG.debug('Payload: ' + payload) - -try { - - def httpClient = HttpClients.create(parameters) - def httpResponse = Http.post() - .url(url) - .header("Accept", "application/json") - .header("X-FriendlyCAPTCHA-Token", token) - .entity(Http.entity() - .content(payload) - .contentType("application/json") - .build()) - .build() - .send(httpClient) - - LOG.debug('Response Message: ' + httpResponse.reasonPhrase()) - LOG.debug('Response Status Code: ' + httpResponse.code()) - LOG.debug('Response: ' + httpResponse.bodyAsString()) - - if (httpResponse.code() == 200) { - if (httpResponse.bodyAsString().contains('SUCCESSFUL')) { - response.setResult('ok') - return - } else { - LOG.warn("Friendly captcha not successful for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'") - response.setResult('exit.1') - return - } - } else { - LOG.error("Friendly captcha failed with statuscode ${httpResponse.code()} for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'") - response.setResult('error') - response.setError(1, 'Unexpected HTTP reponse') - } -} catch (all) { - // Handle exception and set the transition - LOG.error("Friendly captcha failed with a general error '${all}' for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }', service-url: ${url}") - response.setResult('error') - response.setError(1, 'Exception during HTTP call') -} - - -// TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore -// -// def payload = '{ "email": "' + inargs['userInputValue_prompt.email'] + '", "action": "LOGIN", "userIp": "' + ip + '", "userAgent": "' + userAgent + '"}' -// -// LOG.info('Token: ' + inargs['recaptcha_response']) -// LOG.info('Integration: ' + session['agov.fido2.X-ReCAPTCHA-Integration']) -// LOG.info('Payload: ' + payload) -// -// try { -// -// def httpClient = HttpClients.create(parameters) -// def httpResponse = Http.post() -// .url(url) -// .header("Accept", "application/json") -// .header("X-ReCAPTCHA-Token", inargs['recaptcha_response']) -// .header("X-ReCAPTCHA-Integration", session['agov.fido2.X-ReCAPTCHA-Integration']) -// .entity(Http.entity() -// .content(payload) -// .contentType("application/json") -// .build()) -// .build() -// .send(httpClient) -// -// LOG.info('Response Message: ' + httpResponse.reasonPhrase()) -// LOG.info('Response Status Code: ' + httpResponse.code()) -// LOG.info('Response: ' + httpResponse.bodyAsString()) -// -// if (httpResponse.code() == 200) { -// if (httpResponse.bodyAsString().contains('SUCCESSFUL')) { -// response.setResult('ok') -// return -// } else { -// -// response.setSessionAttribute('agov.fido2.X-ReCAPTCHA-Integration', 'VISIBLE') -// response.setResult('exit.1') -// return -// } -// } else { -// LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) -// response.setResult('error') -// response.setError(1, 'Unexpected HTTP reponse') -// } -// } catch (all) { -// // Handle exception and set the transition -// LOG.error('error: ' + all, all) -// response.setResult('error') -// response.setError(1, 'Exception during HTTP call') -// } \ No newline at end of file +import io.opentelemetry.api.trace.Span + +def url = parameters.get('url') + +def email = inargs['userInputValue_prompt.email'] +def token = inargs['captcha_response']?: 'MISSING' +def enabled = (session['agov.fido2.captchaSettings.enabled']?:'true').toBoolean() + +def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown' +def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown' + +def payload = "{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }" + +LOG.debug('Token: ' + token) +LOG.debug('Payload: ' + payload) + +try { + + if (!enabled) { + LOG.info("FriendlyCAPTCHA is disabled, allowing operation for ${payload}") + response.setResult('ok') + return + } + + def spanCtxt = Span.current().getSpanContext() + def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}" + + def httpClient = HttpClients.create(parameters) + def httpResponse = Http.post() + .url(url) + .header("Accept", "application/json") + .header("X-FriendlyCAPTCHA-Token", token) + .header("traceparent", traceparent) + .entity(Http.entity() + .content(payload) + .contentType("application/json") + .build()) + .build() + .send(httpClient) + + LOG.debug('Response Status Code: ' + httpResponse.code()) + LOG.debug('Response: ' + httpResponse.bodyAsString()) + + if (httpResponse.code() == 200) { + if (httpResponse.bodyAsString().contains('SUCCESSFUL')) { + response.setResult('ok') + return + } else { + LOG.warn("Friendly captcha not successful for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'") + response.setResult('exit.1') + return + } + } else { + LOG.error("Friendly captcha failed with statuscode ${httpResponse.code()} for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'") + response.setResult('error') + response.setError(1, 'Unexpected HTTP reponse') + } +} catch (all) { + // Handle exception and set the transition + LOG.error("Friendly captcha failed with a general error '${all}' for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }', service-url: ${url}") + response.setResult('error') + response.setError(1, 'Exception during HTTP call') +} diff --git a/patterns/717094cbd4ddbadeab4b2cc1_scriptFile/Recovery_fetchCaptchaResult.groovy b/patterns/717094cbd4ddbadeab4b2cc1_scriptFile/Recovery_fetchCaptchaResult.groovy index cad172a..e3f8b9d 100644 --- a/patterns/717094cbd4ddbadeab4b2cc1_scriptFile/Recovery_fetchCaptchaResult.groovy +++ b/patterns/717094cbd4ddbadeab4b2cc1_scriptFile/Recovery_fetchCaptchaResult.groovy @@ -1,7 +1,10 @@ +import io.opentelemetry.api.trace.Span + def url = parameters.get('url') def email = inargs['email'] def token = inargs['captcha_response']?: 'MISSING' +def enabled = (session['agov.recovery.captchaSettings.enabled']?:'true').toBoolean() def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown' def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown' @@ -13,11 +16,21 @@ LOG.debug('Payload: ' + payload) try { + if (!enabled) { + LOG.info("FriendlyCAPTCHA is disabled, allowing operation for ${payload}") + response.setResult('ok') + return + } + + def spanCtxt = Span.current().getSpanContext() + def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}" + def httpClient = HttpClients.create(parameters) def httpResponse = Http.post() .url(url) .header("Accept", "application/json") .header("X-FriendlyCAPTCHA-Token", token) + .header("traceparent", traceparent) .entity(Http.entity() .content(payload) .contentType("application/json") @@ -25,7 +38,6 @@ try { .build() .send(httpClient) - LOG.debug('Response Message: ' + httpResponse.reasonPhrase()) LOG.debug('Response Status Code: ' + httpResponse.code()) LOG.debug('Response: ' + httpResponse.bodyAsString()) @@ -49,54 +61,3 @@ try { response.setResult('error') response.setError(1, 'Exception during HTTP call') } - - - -// TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore -// def payload = '{ "email": "' + inargs['email'] + '", "action": "LOGIN", "userIp": "' + session.get('agov.recovery.ip') + '", "userAgent": "' + session.get('agov.recovery.userAgent') + '"}' -// -// LOG.info('Token: ' + inargs['recaptcha_response']) -// LOG.info('Integration: ' + session['agov.recovery.X-ReCAPTCHA-Integration']) -// LOG.info('Payload: ' + payload) -// -// try { -// -// def httpClient = HttpClients.create(parameters) -// def httpResponse = Http.post() -// .url(url) -// .header("Accept", "application/json") -// .header("X-ReCAPTCHA-Token", inargs['recaptcha_response']) -// .header("X-ReCAPTCHA-Integration", session['agov.recovery.X-ReCAPTCHA-Integration']) -// .entity(Http.entity() -// .content(payload) -// .contentType("application/json") -// // .charSet("utf-8") -// .build()) -// .build() -// .send(httpClient) -// -// LOG.info('Response Message: ' + httpResponse.reasonPhrase()) -// LOG.info('Response Status Code: ' + httpResponse.code()) -// LOG.info('Response: ' + httpResponse.bodyAsString()) -// -// if (httpResponse.code() == 200) { -// if (httpResponse.bodyAsString().contains('SUCCESSFUL')) { -// response.setResult('ok') -// return -// } else { -// -// response.setSessionAttribute('agov.recovery.X-ReCAPTCHA-Integration', 'VISIBLE') -// response.setResult('exit.1') -// return -// } -// } else { -// LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) -// response.setResult('error') -// response.setError(1, 'Unexpected HTTP reponse') -// } -// } catch (all) { -// // Handle exception and set the transition -// LOG.error('error: ' + all, all) -// response.setResult('error') -// response.setError(1, 'Exception during HTTP call') -// } \ No newline at end of file diff --git a/patterns/9f443ce76f9522dfae4c3aa0_scriptFile/recovery_sendEmail.gy b/patterns/9f443ce76f9522dfae4c3aa0_scriptFile/recovery_sendEmail.groovy similarity index 80% rename from patterns/9f443ce76f9522dfae4c3aa0_scriptFile/recovery_sendEmail.gy rename to patterns/9f443ce76f9522dfae4c3aa0_scriptFile/recovery_sendEmail.groovy index 5b5ed6e..bbf7bdc 100644 --- a/patterns/9f443ce76f9522dfae4c3aa0_scriptFile/recovery_sendEmail.gy +++ b/patterns/9f443ce76f9522dfae4c3aa0_scriptFile/recovery_sendEmail.groovy @@ -1,41 +1,41 @@ -//import ch.nevis.esauth.util.httpclient.api.HttpClient; -//import ch.nevis.esauth.util.httpclient.api.HttpClients; -//import ch.nevis.esauth.util.httpclient.api.Http; - -def url = parameters.get('url') -//def payload = parameters.get('json') -//def url = "https://me.agov-d.azure.adnovum.net:48081/utility/api/v1/email/031" -def email = inargs['email'] -def language = session['ch.nevis.session.user.language'] ?: 'en' -def payload = '{ "email": "' + email + '", "language": "' + language + '"}' - -try { - def httpClient = HttpClients.create(parameters) - def httpResponse = Http.post() - .url(url) - .header("Accept", "application/json") - .entity(Http.entity() - .content(payload) - .contentType("application/json") - // .charSet("utf-8") - .build()) - .build() - .send(httpClient) - - LOG.info('Response Message: ' + httpResponse.reasonPhrase()) - LOG.info('Response Status Code: ' + httpResponse.code()) - LOG.info('Response: ' + httpResponse.bodyAsString()) - - if (httpResponse.code() == 200) { - response.setResult('ok') - } else { - LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) - response.setResult('error') - response.setError(1, 'Unexpected HTTP reponse') - } -} catch (all) { - // Handle exception and set the transition - LOG.error('error: ' + all, all) - response.setResult('error') - response.setError(1, 'Exception during HTTP call') +import io.opentelemetry.api.trace.Span + +def url = parameters.get('url') +def email = inargs['email'] +def language = session['ch.nevis.session.user.language'] ?: 'en' +def payload = '{ "email": "' + email + '", "language": "' + language + '"}' + +try { + def spanCtxt = Span.current().getSpanContext() + def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}" + + def httpClient = HttpClients.create(parameters) + def httpResponse = Http.post() + .url(url) + .header("Accept", "application/json") + .header("traceparent", traceparent) + .entity(Http.entity() + .content(payload) + .contentType("application/json") + // .charSet("utf-8") + .build()) + .build() + .send(httpClient) + + LOG.info('Response Message: ' + httpResponse.reasonPhrase()) + LOG.info('Response Status Code: ' + httpResponse.code()) + LOG.info('Response: ' + httpResponse.bodyAsString()) + + if (httpResponse.code() == 200) { + response.setResult('ok') + } else { + LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) + response.setResult('error') + response.setError(1, 'Unexpected HTTP reponse') + } +} catch (all) { + // Handle exception and set the transition + LOG.error('error: ' + all, all) + response.setResult('error') + response.setError(1, 'Exception during HTTP call') } \ No newline at end of file diff --git a/patterns/AuthnFailed_LockedAccount_3cc9ad9d0cc771665881abcc.yml b/patterns/AuthnFailed_LockedAccount_3cc9ad9d0cc771665881abcc.yml deleted file mode 100644 index 60a9de5..0000000 --- a/patterns/AuthnFailed_LockedAccount_3cc9ad9d0cc771665881abcc.yml +++ /dev/null @@ -1,18 +0,0 @@ -schemaVersion: "1.0" -pattern: - id: "3cc9ad9d0cc771665881abcc" - className: "ch.nevis.admin.v4.plugin.nevisauth.patterns2.TransformVariablesStep" - name: "AuthnFailed_LockedAccount" - label: "UTILS" - notes: "Display screen : informing the user that a problem blocking his account\ - \ has been encountered\n\nmissing info : if you didn't lock the account then go\ - \ consult the support page for unlocking the account\n\nErrors : 1: user verification\ - \ failed (user not found); 98: account disabled or archived (98 not in use yet)" - properties: - variables: - - notes:saml.errorCode: "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed" - - notes:saml.errorMessage: "Your account is locked , Request ID: ${request:transferId}" - - notes:saml.errorInfo: "If you didn't lock the account then go consult the support\ - \ page for unlocking the account" - onSuccess: - - "pattern://473f9d6b4ab9d61c1eb8c689" diff --git a/patterns/FIDO2_ResetSessionInfos_887ada57500885703a4a9408.yml b/patterns/FIDO2_ResetSessionInfos_887ada57500885703a4a9408.yml deleted file mode 100644 index c130eda..0000000 --- a/patterns/FIDO2_ResetSessionInfos_887ada57500885703a4a9408.yml +++ /dev/null @@ -1,13 +0,0 @@ -schemaVersion: "1.0" -pattern: - id: "887ada57500885703a4a9408" - className: "ch.nevis.admin.v4.plugin.nevisauth.patterns2.TransformVariablesStep" - name: "FIDO2_ResetSessionInfos" - notes: "TODO/haburger/2024-AUG-20: remove after migration to Friendly Captcha is\ - \ done" - properties: - variables: - - sess:agov.fido2.X-ReCAPTCHA-Integration: "" - emptyValue: "remove-variable" - onSuccess: - - "pattern://f39352769cb2a1c88e1a176d" diff --git a/patterns/IdP-Idm-SecToken-Signer-Trust_2d8151249e6734ccc072422b.yml b/patterns/IdP-Idm-SecToken-Signer-Trust_2d8151249e6734ccc072422b.yml new file mode 100644 index 0000000..c40a349 --- /dev/null +++ b/patterns/IdP-Idm-SecToken-Signer-Trust_2d8151249e6734ccc072422b.yml @@ -0,0 +1,9 @@ +schemaVersion: "1.0" +pattern: + id: "2d8151249e6734ccc072422b" + className: "ch.nevis.admin.v4.plugin.nevisproxy.patterns.AutomaticTrustStoreProvider" + name: "IdP-Idm-SecToken-Signer-Trust" + properties: + keystore: + - "pattern://aeb2fed9962dcd5f7893db51" + truststoreFile: "var://idp-idm-sectoken-signer-trust-additional-trusted-certificates" diff --git a/patterns/Mobile_NLess_Auth_f63c475c35b616b7c6c1901c.yml b/patterns/Mobile_NLess_Auth_f63c475c35b616b7c6c1901c.yml index bd235a1..15b1221 100644 --- a/patterns/Mobile_NLess_Auth_f63c475c35b616b7c6c1901c.yml +++ b/patterns/Mobile_NLess_Auth_f63c475c35b616b7c6c1901c.yml @@ -9,7 +9,7 @@ pattern: onSuccess: - "pattern://56c67433c7a47b6cb06f011a" nextSteps: - - "pattern://887ada57500885703a4a9408" + - "pattern://f39352769cb2a1c88e1a176d" - "pattern://d76231eaa88cb1645ce44cf3" resources: "res://f63c475c35b616b7c6c1901c#resources" keyObjects: diff --git a/patterns/Recovery_fetchCaptchaInfos_bea3ca0c85381d07d632be52.yml b/patterns/Recovery_fetchCaptchaInfos_bea3ca0c85381d07d632be52.yml index 8740a46..654fdf7 100644 --- a/patterns/Recovery_fetchCaptchaInfos_bea3ca0c85381d07d632be52.yml +++ b/patterns/Recovery_fetchCaptchaInfos_bea3ca0c85381d07d632be52.yml @@ -7,6 +7,7 @@ pattern: scriptFile: "res://bea3ca0c85381d07d632be52#scriptFile" parameters: - url: "${var.captcha-service.configinfo.url}" + - realIpHttpHeaderName: "${var.captcha-service.configinfo.realIpHttpHeaderName}" onSuccess: - "pattern://584964c837512845d7940809" scriptTraceGroup: "AgovCaptcha" diff --git a/patterns/Security_Response_Headers_0d3511bed6798a78cc3237f6.yml b/patterns/Security_Response_Headers_0d3511bed6798a78cc3237f6.yml index cd4e291..4ea6f80 100644 --- a/patterns/Security_Response_Headers_0d3511bed6798a78cc3237f6.yml +++ b/patterns/Security_Response_Headers_0d3511bed6798a78cc3237f6.yml @@ -3,34 +3,6 @@ pattern: id: "0d3511bed6798a78cc3237f6" className: "ch.nevis.admin.v4.plugin.nevisproxy.patterns.SecurityResponseHeaders" name: "Security Response Headers" + label: "PROXY" properties: - responseHeaders: - - Strict-Transport-Security: "max-age=63072000; includeSubDomains;" - - X-Content-Type-Options: "nosniff" - - Referrer-Policy: "strict-origin-when-cross-origin" - - X-Frame-Options: "DENY" - - Cross-Origin-Opener-Policy: "same-origin" - - Cross-Origin-Embedder-Policy: "require-corp" - - Cross-Origin-Resource-Policy: "same-site" - - Permissions-Policy: "geolocation=(), camera=(), microphone=(), interest-cohort=()" - - Content-Security-Policy-Report-Only: "default-src 'none'; script-src 'self'\ - \ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM='\ - \ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM='\ - \ 'unsafe-inline'; script-src-elem https://www.google.com https://www.gstatic.com\ - \ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-VVRbrI9TGfTX6IQoysg2+krJFUO9Ckt6G7Gcs1q2dgM='\ - \ 'sha256-6FA//NVJWFgnJwirzDKHC42MZIXYrIxtNaKCahX3DLg=' 'sha256-3whVsWq2brmbgJQdoqbeJgW+43c+XyGdWbKl7sqG3YQ='\ - \ 'sha256-3whVsWq2brmbgJQdoqbeJgW+43c+XyGdWbKl7sqG3YQ=' 'self'; connect-src\ - \ 'self'; img-src 'self'; style-src 'self' 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0='\ - \ 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0=' 'sha256-JnkgaYe2Kqj0SvIYv1vTPV72Rnsp5aU6c015YNij5Ks='\ - \ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\ - \ 'sha256-MdFWcEIx4V82/ap9SUt01BxZMN4eFGEl8hNDFEGIzJU=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\ - \ 'sha256-ifPclQYYwRDXSPQgB9/6UgAgEICBpwegJBWNhOI8dOA=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\ - \ 'sha256-2diQqrANllVP9IWjXj1A6fjjvlPtpN6NXlmTiRJneCU=' 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0='\ - \ 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\ - \ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\ - \ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\ - \ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\ - \ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\ - \ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\ - \ 'unsafe-hashes' 'unsafe-inline'; form-action 'self'; font-src 'self'; frame-src\ - \ https://www.google.com" + responseHeaders: "var://security-response-headers-response-headers" diff --git a/patterns/bea3ca0c85381d07d632be52_scriptFile/Recovery_fetchCaptchaInfos b/patterns/bea3ca0c85381d07d632be52_scriptFile/Recovery_fetchCaptchaInfos deleted file mode 100644 index 66e69f4..0000000 --- a/patterns/bea3ca0c85381d07d632be52_scriptFile/Recovery_fetchCaptchaInfos +++ /dev/null @@ -1,44 +0,0 @@ -import groovy.json.JsonSlurper - -def url = parameters.get('url') - -try { - def jsonSlurper = new JsonSlurper() - def httpClient = HttpClients.create(parameters) - def httpResponse = Http.get().url(url).build().send(httpClient) - LOG.debug('Response Message: ' + httpResponse.reasonPhrase()) - LOG.debug('Response Status Code: ' + httpResponse.code()) - LOG.debug('Response: ' + httpResponse.bodyAsString()) - - if (httpResponse.code() == 200) { - def json = jsonSlurper.parseText(httpResponse.bodyAsString()) - - // TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore - // response.setSessionAttribute('agov.recovery.json.accountUrl', json.accountUrl) - // response.setSessionAttribute('agov.recovery.json.registrationUrl', json.registrationUrl) - // response.setSessionAttribute('agov.recovery.json.captchaSettings.enabled', String.valueOf(json.captchaSettings.enabled)) - // response.setSessionAttribute('agov.recovery.json.captchaSettings.reCaptchaInvisibleSiteKey', json.captchaSettings.reCaptchaInvisibleSiteKey) - // response.setSessionAttribute('agov.recovery.json.captchaSettings.reCaptchaVisibleSiteKey', json.captchaSettings.reCaptchaVisibleSiteKey) - // if (session.get('agov.recovery.X-ReCAPTCHA-Integration') == null) { - // response.setSessionAttribute('agov.recovery.X-ReCAPTCHA-Integration', 'INVISIBLE') - // } else { - // response.setSessionAttribute('agov.recovery.X-ReCAPTCHA-Integration', 'VISIBLE') - // } - - response.setSessionAttribute('agov.recovery.captchaSettings.enabled', String.valueOf(json.captchaSettings.enabled)) - response.setSessionAttribute('agov.recovery.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey) - response.setSessionAttribute('agov.recovery.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl) - - - response.setResult('ok') - } else { - LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) - response.setResult('error') - response.setError(1, 'Unexpected HTTP reponse') - } -} catch (all) { - // Handle exception and set the transition - LOG.error('error: ' + all, all) - response.setResult('error') - response.setError(1, 'Exception during HTTP call') -} \ No newline at end of file diff --git a/patterns/bea3ca0c85381d07d632be52_scriptFile/Recovery_fetchCaptchaInfos.groovy b/patterns/bea3ca0c85381d07d632be52_scriptFile/Recovery_fetchCaptchaInfos.groovy new file mode 100644 index 0000000..c811ec7 --- /dev/null +++ b/patterns/bea3ca0c85381d07d632be52_scriptFile/Recovery_fetchCaptchaInfos.groovy @@ -0,0 +1,39 @@ +import groovy.json.JsonSlurper +import io.opentelemetry.api.trace.Span + +def url = parameters.get('url') +def realIpHttpHeaderName = parameters.get('realIpHttpHeaderName') ?: 'X-Real-IP' +def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown' + +try { + def spanCtxt = Span.current().getSpanContext() + def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}" + + def jsonSlurper = new JsonSlurper() + def httpClient = HttpClients.create(parameters) + def httpResponse = Http.get().url(url).header('traceparent', traceparent) + .header(realIpHttpHeaderName, ip).build().send(httpClient) + + LOG.debug('Response Status Code: ' + httpResponse.code()) + LOG.debug('Response: ' + httpResponse.bodyAsString()) + + if (httpResponse.code() == 200) { + def json = jsonSlurper.parseText(httpResponse.bodyAsString()) + + response.setSessionAttribute('agov.recovery.captchaSettings.enabled', String.valueOf(json.friendlyCaptureClientSettings.enabled)) + response.setSessionAttribute('agov.recovery.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey) + response.setSessionAttribute('agov.recovery.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl) + + + response.setResult('ok') + } else { + LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) + response.setResult('error') + response.setError(1, 'Unexpected HTTP reponse') + } +} catch (all) { + // Handle exception and set the transition + LOG.error('error: ' + all, all) + response.setResult('error') + response.setError(1, 'Exception during HTTP call') +} \ No newline at end of file diff --git a/patterns/db4acd487dc7e8b82de8abb4_scriptFile/handleCodeParameter.groovy b/patterns/db4acd487dc7e8b82de8abb4_scriptFile/handleCodeParameter.groovy index a30b09b..fbb7b99 100644 --- a/patterns/db4acd487dc7e8b82de8abb4_scriptFile/handleCodeParameter.groovy +++ b/patterns/db4acd487dc7e8b82de8abb4_scriptFile/handleCodeParameter.groovy @@ -1,4 +1,5 @@ import ch.nevis.esauth.auth.engine.AuthResponse + if (inargs['cancel'] == 'cancel') { //cleanSession() response.setStatus(AuthResponse.AUTH_ERROR) diff --git a/patterns/e3cac41e75980361d7d26bde_authStatesFile/EmailInput.xml b/patterns/e3cac41e75980361d7d26bde_authStatesFile/EmailInput.xml index e6afb38..bef9b13 100644 --- a/patterns/e3cac41e75980361d7d26bde_authStatesFile/EmailInput.xml +++ b/patterns/e3cac41e75980361d7d26bde_authStatesFile/EmailInput.xml @@ -8,12 +8,6 @@ - - - - - - diff --git a/patterns/f393012a278e525956a362d3_authStatesFile/ensureAccountState.xml b/patterns/f393012a278e525956a362d3_authStatesFile/ensureAccountState.xml index d97cdb3..313999f 100644 --- a/patterns/f393012a278e525956a362d3_authStatesFile/ensureAccountState.xml +++ b/patterns/f393012a278e525956a362d3_authStatesFile/ensureAccountState.xml @@ -5,9 +5,9 @@ - - - + + + diff --git a/patterns/f393012a278e525956a362d3_resources/ensureAccountState.groovy b/patterns/f393012a278e525956a362d3_resources/ensureAccountState.groovy index b8c189b..cb00cb1 100644 --- a/patterns/f393012a278e525956a362d3_resources/ensureAccountState.groovy +++ b/patterns/f393012a278e525956a362d3_resources/ensureAccountState.groovy @@ -94,12 +94,13 @@ if (!session['ch.adnovum.nevisidm.userDto'].contains("idVerifi json['items'].eachWithIndex { az, i -> if (az.roleExtId == level100RoleExtid) { - agovAq100AuthEndpoint = "${endpoint}/${az.extId}" + aq100AuthRestURL = "${endpoint}/${az.extId}" } } } - endpoint = "${aq100AuthRestURL}/properties" + + endpoint = "${aq100AuthRestURL}/properties" def patchRequest = new HTTPRequestWrapper() patchRequest.addToHeaders('Content-Type', ['application/json']) diff --git a/patterns/f39352769cb2a1c88e1a176d_scriptFile/fido2_fetchCaptchaInfos.gy b/patterns/f39352769cb2a1c88e1a176d_scriptFile/fido2_fetchCaptchaInfos.groovy similarity index 55% rename from patterns/f39352769cb2a1c88e1a176d_scriptFile/fido2_fetchCaptchaInfos.gy rename to patterns/f39352769cb2a1c88e1a176d_scriptFile/fido2_fetchCaptchaInfos.groovy index 3a0836b..c945609 100644 --- a/patterns/f39352769cb2a1c88e1a176d_scriptFile/fido2_fetchCaptchaInfos.gy +++ b/patterns/f39352769cb2a1c88e1a176d_scriptFile/fido2_fetchCaptchaInfos.groovy @@ -1,52 +1,38 @@ -import groovy.json.JsonSlurper -import io.opentelemetry.api.trace.Span - -def url = parameters.get('url') - -try { - //TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore - session.remove('agov.fido2.X-ReCAPTCHA-Integration') - - def spanCtxt = Span.current().getSpanContext() - - - def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}" - LOG.error('traceparent: ' + traceparent) - - def jsonSlurper = new JsonSlurper() - def httpClient = HttpClients.create(parameters) - def httpResponse = Http.get().url(url).build().send(httpClient) - LOG.debug('Response Message: ' + httpResponse.reasonPhrase()) - LOG.debug('Response Status Code: ' + httpResponse.code()) - LOG.debug('Response: ' + httpResponse.bodyAsString()) - - if (httpResponse.code() == 200) { - def json = jsonSlurper.parseText(httpResponse.bodyAsString()) - - // TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore - // response.setSessionAttribute('agov.fido2.json.captchaSettings.enabled', String.valueOf(json.captchaSettings.enabled)) - // response.setSessionAttribute('agov.fido2.json.captchaSettings.reCaptchaInvisibleSiteKey', json.captchaSettings.reCaptchaInvisibleSiteKey) - // response.setSessionAttribute('agov.fido2.json.captchaSettings.reCaptchaVisibleSiteKey', json.captchaSettings.reCaptchaVisibleSiteKey) - // - // if (session.get('agov.fido2.X-ReCAPTCHA-Integration') == null) { - // response.setSessionAttribute('agov.fido2.X-ReCAPTCHA-Integration', 'INVISIBLE') - // } else { - // response.setSessionAttribute('agov.fido2.X-ReCAPTCHA-Integration', 'VISIBLE') - // } - - response.setSessionAttribute('agov.fido2.captchaSettings.enabled', String.valueOf(json.friendlyCaptureClientSettings.enabled)) - response.setSessionAttribute('agov.fido2.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey) - response.setSessionAttribute('agov.fido2.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl) - - response.setResult('ok') - } else { - LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) - response.setResult('error') - response.setError(1, 'Unexpected HTTP reponse') - } -} catch (all) { - // Handle exception and set the transition - LOG.error('error: ' + all, all) - response.setResult('error') - response.setError(1, 'Exception during HTTP call') +import groovy.json.JsonSlurper +import io.opentelemetry.api.trace.Span + +def url = parameters.get('url') +def realIpHttpHeaderName = parameters.get('realIpHttpHeaderName') ?: 'X-Real-IP' +def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown' + +try { + def spanCtxt = Span.current().getSpanContext() + def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}" + + def jsonSlurper = new JsonSlurper() + def httpClient = HttpClients.create(parameters) + def httpResponse = Http.get().url(url).header('traceparent', traceparent) + .header(realIpHttpHeaderName, ip).build().send(httpClient) + + LOG.debug('Response Status Code: ' + httpResponse.code()) + LOG.debug('Response: ' + httpResponse.bodyAsString()) + + if (httpResponse.code() == 200) { + def json = jsonSlurper.parseText(httpResponse.bodyAsString()) + + response.setSessionAttribute('agov.fido2.captchaSettings.enabled', String.valueOf(json.friendlyCaptureClientSettings.enabled)) + response.setSessionAttribute('agov.fido2.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey) + response.setSessionAttribute('agov.fido2.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl) + + response.setResult('ok') + } else { + LOG.error('Unexcpected HTTP response code: ' + httpResponse.code()) + response.setResult('error') + response.setError(1, 'Unexpected HTTP reponse') + } +} catch (all) { + // Handle exception and set the transition + LOG.error('error: ' + all, all) + response.setResult('error') + response.setError(1, 'Exception during HTTP call') } \ No newline at end of file diff --git a/patterns/fido2_fetchCaptchaInfos_f39352769cb2a1c88e1a176d.yml b/patterns/fido2_fetchCaptchaInfos_f39352769cb2a1c88e1a176d.yml index ce0c0ff..13dc3fb 100644 --- a/patterns/fido2_fetchCaptchaInfos_f39352769cb2a1c88e1a176d.yml +++ b/patterns/fido2_fetchCaptchaInfos_f39352769cb2a1c88e1a176d.yml @@ -7,6 +7,7 @@ pattern: scriptFile: "res://f39352769cb2a1c88e1a176d#scriptFile" parameters: - url: "${var.captcha-service.configinfo.url}" + - realIpHttpHeaderName: "${var.captcha-service.configinfo.realIpHttpHeaderName}" onSuccess: - "pattern://e3cac41e75980361d7d26bde" onFailure: diff --git a/patterns/nevisAuth_Database_b7b59e97b3fd18bb60178573.yml b/patterns/nevisAuth_Database_b7b59e97b3fd18bb60178573.yml index 61879ff..09a42ba 100644 --- a/patterns/nevisAuth_Database_b7b59e97b3fd18bb60178573.yml +++ b/patterns/nevisAuth_Database_b7b59e97b3fd18bb60178573.yml @@ -14,3 +14,4 @@ pattern: user: "var://auth-session-store-database-user" password: "var://auth-session-store-database-password" databaseManagement: "var://auth-session-store-database-management" + parameters: "serverTimezone=UTC" diff --git a/patterns/nevisIDM_b8a36646f81c3247cdb5d90b.yml b/patterns/nevisIDM_b8a36646f81c3247cdb5d90b.yml index 744b9ae..fd223ad 100644 --- a/patterns/nevisIDM_b8a36646f81c3247cdb5d90b.yml +++ b/patterns/nevisIDM_b8a36646f81c3247cdb5d90b.yml @@ -10,7 +10,7 @@ pattern: frontendTrustStore: - "pattern://c0722fc79e7314c9cdcd20ff" authSignerTrustStore: - - "pattern://55bf63a1b1716e9631f7080d" + - "pattern://2d8151249e6734ccc072422b" database: - "pattern://2951ead44a7a9362a4545094" logging: diff --git a/variables.yml b/variables.yml index c8d4752..bc50607 100644 --- a/variables.yml +++ b/variables.yml @@ -450,6 +450,12 @@ variables: value: "cors.allowed.fqdns: '{\"trustbroker.agov-d.azure.adnovum.net\", \"auth.agov-d.azure.adnovum.net\"\ }'" requireOverloading: true + idp-idm-sectoken-signer-trust-additional-trusted-certificates: + className: "ch.nevis.admin.v4.plugin.base.generation.property.AttachmentProperty" + parameters: + minRequired: 0 + value: null + requireOverloading: true idp-sp-connector-properties: className: "ch.nevis.admin.v4.plugin.base.generation.property.AuthStateProperty" parameters: @@ -571,7 +577,8 @@ variables: separators: - "=" switchedSeparators: [] - value: null + value: + - OpTrace: "DEBUG" requireOverloading: true log_idm-default-log-level: className: "ch.nevis.admin.v4.plugin.base.generation.property.SelectionProperty" @@ -883,6 +890,31 @@ variables: secret: true value: "sample password" requireOverloading: true + security-response-headers-response-headers: + className: "ch.nevis.admin.v4.plugin.base.generation.property.KeyValueProperty" + parameters: + minRequired: 1 + separators: + - ":" + switchedSeparators: [] + value: + - Strict-Transport-Security: "max-age=63072000; includeSubDomains;" + - X-Content-Type-Options: "nosniff" + - Referrer-Policy: "strict-origin-when-cross-origin" + - X-Frame-Options: "DENY" + - Cross-Origin-Opener-Policy: "same-origin" + - Cross-Origin-Embedder-Policy: "require-corp" + - Cross-Origin-Resource-Policy: "same-site" + - Permissions-Policy: "geolocation=(), camera=(), microphone=(), interest-cohort=()" + - Content-Security-Policy-Report-Only: "default-src 'none'; script-src 'self'\ + \ 'sha256-YPbtYpCQA51uSiLa2ux1TkGQoRDNbpdlYd50ospNgYw=' 'sha256-YPbtYpCQA51uSiLa2ux1TkGQoRDNbpdlYd50ospNgYw='\ + \ 'sha256-uOoE0nq21NJDv37YLUOxV9aCnNstJ0GK7BiXNMXQAcI='; connect-src 'self';\ + \ img-src 'self'; style-src 'self' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\ + \ 'sha256-MdFWcEIx4V82/ap9SUt01BxZMN4eFGEl8hNDFEGIzJU=' 'sha256-ifPclQYYwRDXSPQgB9/6UgAgEICBpwegJBWNhOI8dOA='\ + \ 'sha256-2diQqrANllVP9IWjXj1A6fjjvlPtpN6NXlmTiRJneCU=' 'sha256-JhfXJ5URuB/EAqhZ9vqgEO6trOuCE0w2/ChmfrVzxFo=';\ + \ form-action 'self' https://trustbroker.agov-d.azure.adnovum.net/adfs/ls;\ + \ font-src 'self'; " + requireOverloading: true service_provider_state-registration-template-parameters: className: "ch.nevis.admin.v4.plugin.base.generation.property.TextProperty" parameters: