diff --git a/patterns/1f0702aaabef60a615abf41f_resources/resources.zip b/patterns/1f0702aaabef60a615abf41f_resources/resources.zip index 6a75363..d6e5de4 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 a7d7c14..e28691b 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 38b8d20..06a0a69 100644 Binary files a/patterns/204c22beaccdfd22727af378_template/webdata.zip and b/patterns/204c22beaccdfd22727af378_template/webdata.zip differ diff --git a/patterns/3a982aa242ff4f8ebd823693_script/countries_security_filter.lua b/patterns/3a982aa242ff4f8ebd823693_script/countries_security_filter.lua new file mode 100644 index 0000000..e685e93 --- /dev/null +++ b/patterns/3a982aa242ff4f8ebd823693_script/countries_security_filter.lua @@ -0,0 +1,42 @@ +package.path = package.path .. ";/opt/nevisproxy/webapp/WEB-INF/lib/lua/Utils.lua" +local Utils = require "Utils" + +function inputHeader(request, response) + local trace = request:getTracer() + + local queryParams = Utils.getQueryParameters(request) + local path = request:getRequestPath() + + -- only allow calls to the countries service + if path == nil then + trace:error("path is nil") + end + + if path ~= nil and path ~= '/resource/utility/api/v1/countries' then + trace:info("utility service called with invalid path " .. request:getRequestPath()) + response:send(404) + return + end + + -- only alloq one query-parameter 'lang' with the values DE, FR, IT, EN, RS + for param, values in pairs(queryParams) do + if (param ~= 'lang') then + trace:info("utility service called with invalid query param " .. param) + response:send(404) + return + end + if Helpers.tableLength(values) ~= 1 then + trace:info("utility service called with invalid value for query param " .. param) + response:send(404) + return + end + for i, value in pairs(values) do + local lang = string.upper(value) + if not ('DE' == lang or 'FR' == lang or 'IT' == lang or 'EN' == lang or 'RS' == lang) then + trace:info("utility service called with invalid value for query param " .. param .. "=" .. value) + response:send(404) + return + end + end + end +end diff --git a/patterns/4fcfadb4a5c946ead7e6e995_labels/labels.zip b/patterns/4fcfadb4a5c946ead7e6e995_labels/labels.zip index a7d7c14..e28691b 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 38b8d20..06a0a69 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 2d2cd26..4ec3281 100644 --- a/patterns/584964c837512845d7940809_authStatesFile/recovery-preprocessing.xml +++ b/patterns/584964c837512845d7940809_authStatesFile/recovery-preprocessing.xml @@ -193,11 +193,12 @@ - + - - + + + @@ -209,6 +210,7 @@ + @@ -220,6 +222,11 @@ + + + + + diff --git a/patterns/584964c837512845d7940809_resources/recovery-preprocessing.groovy b/patterns/584964c837512845d7940809_resources/recovery-processing.groovy similarity index 96% rename from patterns/584964c837512845d7940809_resources/recovery-preprocessing.groovy rename to patterns/584964c837512845d7940809_resources/recovery-processing.groovy index 9c0733c..e7d096d 100644 --- a/patterns/584964c837512845d7940809_resources/recovery-preprocessing.groovy +++ b/patterns/584964c837512845d7940809_resources/recovery-processing.groovy @@ -1,192 +1,191 @@ -import org.codehaus.groovy.runtime.StackTraceUtils -import groovy.xml.XmlSlurper - - -// AGOVaq conversion -def maxLoiRoleToCtxClssConvertorMap = [ - "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 getUserIdVerificationForRecovery(currentLoaRole) { - // application is AGOV-AccountStatus - def list = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto')) - def result = list.'**'.find {node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-AccountStatus,mustRecover'}?.value?.text() - - if (!result) { - // fallback if not explicitly set - def chDomicile = list.country.text() == 'ch' - def lastIdVerification = list.'**'.find {node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-Loi,' + currentLoaRole}?.value?.text() ?: 'missing' - switch (currentLoaRole) { - case 'level100': - result = chDomicile ? 'SimpleLetter' : 'Video' - break - case 'level200': - result = chDomicile ? 'Bmid' : 'Video' - break - case 'level300': - case 'level400': - result = chDomicile ? lastIdVerification : 'Video' - break - default: - LOG.warn("unexpected loa on account: ${currentLoaRole}") - // safest default, should work in any case - result = 'Video' - } - LOG.warn("Recovery method not set, choosing ${result} (based on currentLoad: ${currentLoaRole}, CH-domicile: ${chDomicile}, last verification method: ${lastIdVerification})") - } - return result -} - -def getAqLevelBasedOnIdVerificationForRecovery(idVerification, highestRoleLevel) { - def result = 'level' - - switch (idVerification) { - case 'None': - result = result.concat('100') - break - case 'SimpleLetter': - result = result.concat('200') - break - case 'Video': - case 'VideoSelfPaid': - case 'Bmid': - case 'BmidSelfPaid': - case 'Counter': - result = result.concat((highestRoleLevel == 'level400') ? '400' : '300') - break - default: - LOG.warn("unexpected idVerification for recovery on account: ${idVerification}") - // safest default, should work in any case - result = highestRoleLevel - } - - return result -} - -def getUserMustRecoverValidFrom() { - // set attibutes from DTO: -> validFrom - def payload = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto')) - def authzNode = payload.'**'.find {node -> node.name() == 'authorizations' && node.role.name.text() == 'mustRecover'} - return (authzNode) ? ((authzNode.validFrom && !authzNode.validFrom.text().isEmpty()) ? authzNode.validFrom?.text() : authzNode.ctlCreDat?.text()) : '' -} - - -// 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 maxLoi = null - - -// new -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 - LOG.debug("Recovery: Dto is '${userDto}") - LOG.debug("Recovery: state is '${userState}") - def session = request.getAuthSession(true) - - if (userState == 'ACTIVE') { - - session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes:recovery') - - def maxLoiList = userDto.'**'.findAll { node -> node.name() == 'roles' && node.applicationName.text() == 'AGOV-Loi' }.collect({ node -> node.name.text() }) - maxLoi = (maxLoiList == null || maxLoiList.isEmpty()) ? null : maxLoiList.sort().last() - - def idVerification = null - def agovAqValidFrom = null - if (maxLoi) { - idVerification = userDto.'**'.find { node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-Loi,' + maxLoi}?.value?.text() - idVerification = idVerification ?: 'None' - agovAqValidFrom = userDto.'**'.find { node -> node.name() == 'authorizations' && node.role.name.text() == maxLoi}?.validFrom?.text() - agovAqValidFrom = agovAqValidFrom?: userDto.'**'.find { node -> node.name() == 'authorizations' && node.role.name.text() == maxLoi}?.ctlCreDat?.text() - } - - def mustRecover = userDto.'**'.find { node -> node.name() == 'roles' && node.applicationName.text() == 'AGOV-AccountStatus' && node.name.text() == 'mustRecover' } - - def hasRecoveryRole = userDto.'**'.find { node -> node.name() == 'roles' && node.applicationName.text() == 'AGOV-AccountStatus' && node.name.text() == 'recovery' } - - - if (mustRecover) { - // attributes are defined over the mustRecover authorization - session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes:mustRecover') - - idVerification = getUserIdVerificationForRecovery(maxLoi ?: 'level100') ?: idVerification - - agovAqValidFrom = getUserMustRecoverValidFrom() - - maxLoi = getAqLevelBasedOnIdVerificationForRecovery(idVerification, maxLoi) - } - - LOG.debug("Recovery: MaxLoi is '${maxLoi}'") - LOG.debug("Recovery: IdVerification is ${idVerification}") - LOG.debug("Recovery: agovAqValidFrom is ${agovAqValidFrom}") - LOG.debug("Recovery: mustRecover is '${mustRecover}'") - LOG.debug("Recovery: hasRecoveryRole is '${hasRecoveryRole}'") - - if (maxLoi != null) { - if (maxLoiRoleToCtxClssConvertorMap.containsKey(maxLoi)) { - LOG.debug("Recovery: MaxLoiMapping is " + maxLoiRoleToCtxClssConvertorMap[maxLoi]) - response.setSessionAttribute('agov.recovery.currentAgovAq', '' + maxLoiRoleToCtxClssConvertorMap[maxLoi]) - response.setSessionAttribute('agov.recovery.currentIdVerification', '' + idVerification) - response.setSessionAttribute('agov.recovery.currentAgovAqRoleValidFrom', '' + agovAqValidFrom) - - if ((maxLoi == 'level100') && (mustRecover == null)) { - // mustRecover role not set, so code needs to be checked - LOG.debug("Recovery: emailAndCode") - response.setSessionAttribute('agov.recovery.authenticatedWith', 'urn:qa.agov.ch:names:tc:authfactor:emailAndCode') - response.setResult('needCode') - return - } else { - LOG.debug("Recovery: email") - response.setSessionAttribute('agov.recovery.authenticatedWith', 'urn:qa.agov.ch:names:tc:authfactor:email') - response.setResult('ok') - return - } - - } else { - LOG.error("Recovery: Failed to convert '${maxLoi}' to AGOVaq") - response.setResult('error') - return - } - } else { - // maxLoi is null - LOG.debug("Recovery: no 'AGOV-Loi'-role assigned to user ${user}") - if ((hasRecoveryRole != null) && (mustRecover == null)) { - response.setResult('notFullyRegistered') - return - } else { - LOG.error("Recovery: no 'AGOV-Loi'-role assigned to user ${user} and no recovery role ") - response.setResult('error') - return - } - } - } else { - // state != ACTIVE and no lasterror should not happen - LOG.error("Recovery: state='${userState}' but not lasterror set") - response.setNote('lasterror', '9909') - response.setNote('lasterrorinfo', 'internal error') - response.setResult('error') - return - } - } catch (Exception e) { - e = StackTraceUtils.sanitize(e) - def affectedLines = e.stackTrace.findAll { it.className.startsWith('Script') }.collect { "${it.methodName}:${it.lineNumber}" } - LOG.error("FATAL: Recovery processing failed (at lines: ${affectedLines})", e) - response.setNote('lasterror', '9909') - response.setNote('lasterrorinfo', 'internal error') - response.setResult('error') - return - } -} - -LOG.error("Recovery: userDto missing or failure before (lasterror='${notes.getProperty('lasterror', '-')}')") -response.setNote('lasterror', '9909') -response.setNote('lasterrorinfo', 'internal error') -response.setResult('error') -return +import org.codehaus.groovy.runtime.StackTraceUtils +import groovy.xml.XmlSlurper + + +// AGOVaq conversion +def maxLoiRoleToCtxClssConvertorMap = [ + "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 getUserIdVerificationForRecovery(currentLoaRole) { + // application is AGOV-AccountStatus + def list = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto')) + def result = list.'**'.find {node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-AccountStatus,mustRecover'}?.value?.text() + + if (!result) { + // fallback if not explicitly set + def chDomicile = list.country.text() == 'ch' + def lastIdVerification = list.'**'.find {node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-Loi,' + currentLoaRole}?.value?.text() ?: 'missing' + switch (currentLoaRole) { + case 'level100': + result = chDomicile ? 'SimpleLetter' : 'Video' + break + case 'level200': + result = chDomicile ? 'Bmid' : 'Video' + break + case 'level300': + case 'level400': + result = chDomicile ? lastIdVerification : 'Video' + break + default: + LOG.warn("unexpected loa on account: ${currentLoaRole}") + // safest default, should work in any case + result = 'Video' + } + LOG.warn("Recovery method not set, choosing ${result} (based on currentLoad: ${currentLoaRole}, CH-domicile: ${chDomicile}, last verification method: ${lastIdVerification})") + } + return result +} + +def getAqLevelBasedOnIdVerificationForRecovery(idVerification, highestRoleLevel) { + def result = 'level' + + switch (idVerification) { + case 'None': + result = result.concat('100') + break + case 'SimpleLetter': + result = result.concat('200') + break + case 'Video': + case 'VideoSelfPaid': + case 'Bmid': + case 'BmidSelfPaid': + case 'Counter': + result = result.concat((highestRoleLevel == 'level400') ? '400' : '300') + break + default: + LOG.warn("unexpected idVerification for recovery on account: ${idVerification}") + // safest default, should work in any case + result = highestRoleLevel + } + + return result +} + +def getUserMustRecoverValidFrom() { + // set attibutes from DTO: -> validFrom + def payload = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto')) + def authzNode = payload.'**'.find {node -> node.name() == 'authorizations' && node.role.name.text() == 'mustRecover'} + return (authzNode) ? ((authzNode.validFrom && !authzNode.validFrom.text().isEmpty()) ? authzNode.validFrom?.text() : authzNode.ctlCreDat?.text()) : '' +} + + +// 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 maxLoi = null + + +// new +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 + LOG.debug("Recovery: Dto is '${userDto}") + LOG.debug("Recovery: state is '${userState}") + def session = request.getAuthSession(true) + + if (userState == 'ACTIVE') { + + session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes:recovery') + session.setAttribute('agov.recovery.authenticatedWith', 'urn:qa.agov.ch:names:tc:authfactor:email') + + def maxLoiList = userDto.'**'.findAll { node -> node.name() == 'roles' && node.applicationName.text() == 'AGOV-Loi' }.collect({ node -> node.name.text() }) + maxLoi = (maxLoiList == null || maxLoiList.isEmpty()) ? null : maxLoiList.sort().last() + + def idVerification = null + def agovAqValidFrom = null + if (maxLoi) { + idVerification = userDto.'**'.find { node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-Loi,' + maxLoi}?.value?.text() + idVerification = idVerification ?: 'None' + agovAqValidFrom = userDto.'**'.find { node -> node.name() == 'authorizations' && node.role.name.text() == maxLoi}?.validFrom?.text() + agovAqValidFrom = agovAqValidFrom?: userDto.'**'.find { node -> node.name() == 'authorizations' && node.role.name.text() == maxLoi}?.ctlCreDat?.text() + } + + def mustRecover = userDto.'**'.find { node -> node.name() == 'roles' && node.applicationName.text() == 'AGOV-AccountStatus' && node.name.text() == 'mustRecover' } + + def hasRecoveryRole = userDto.'**'.find { node -> node.name() == 'roles' && node.applicationName.text() == 'AGOV-AccountStatus' && node.name.text() == 'recovery' } + + + if (mustRecover) { + // attributes are defined over the mustRecover authorization + session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes:mustRecover') + + idVerification = getUserIdVerificationForRecovery(maxLoi ?: 'level100') ?: idVerification + + agovAqValidFrom = getUserMustRecoverValidFrom() + + maxLoi = getAqLevelBasedOnIdVerificationForRecovery(idVerification, maxLoi) + } + + LOG.debug("Recovery: MaxLoi is '${maxLoi}'") + LOG.debug("Recovery: IdVerification is ${idVerification}") + LOG.debug("Recovery: agovAqValidFrom is ${agovAqValidFrom}") + LOG.debug("Recovery: mustRecover is '${mustRecover}'") + LOG.debug("Recovery: hasRecoveryRole is '${hasRecoveryRole}'") + + if (maxLoi != null) { + if (maxLoiRoleToCtxClssConvertorMap.containsKey(maxLoi)) { + LOG.debug("Recovery: MaxLoiMapping is " + maxLoiRoleToCtxClssConvertorMap[maxLoi]) + response.setSessionAttribute('agov.recovery.currentAgovAq', '' + maxLoiRoleToCtxClssConvertorMap[maxLoi]) + response.setSessionAttribute('agov.recovery.currentIdVerification', '' + idVerification) + response.setSessionAttribute('agov.recovery.currentAgovAqRoleValidFrom', '' + agovAqValidFrom) + + if ((maxLoi == 'level100') && (mustRecover == null)) { + // mustRecover role not set, so code needs to be checked + LOG.debug("Recovery: emailAndCode") + response.setResult('needCode') + return + } else { + LOG.debug("Recovery: email") + response.setResult('ok') + return + } + + } else { + LOG.error("Recovery: Failed to convert '${maxLoi}' to AGOVaq") + response.setResult('error') + return + } + } else { + // maxLoi is null + LOG.debug("Recovery: no 'AGOV-Loi'-role assigned to user ${user}") + if ((hasRecoveryRole != null) && (mustRecover == null)) { + response.setResult('notFullyRegistered') + return + } else { + LOG.error("Recovery: no 'AGOV-Loi'-role assigned to user ${user} and no recovery role ") + response.setResult('error') + return + } + } + } else { + // state != ACTIVE and no lasterror should not happen + LOG.error("Recovery: state='${userState}' but not lasterror set") + response.setNote('lasterror', '9909') + response.setNote('lasterrorinfo', 'internal error') + response.setResult('error') + return + } + } catch (Exception e) { + e = StackTraceUtils.sanitize(e) + def affectedLines = e.stackTrace.findAll { it.className.startsWith('Script') }.collect { "${it.methodName}:${it.lineNumber}" } + LOG.error("FATAL: Recovery processing failed (at lines: ${affectedLines})", e) + response.setNote('lasterror', '9909') + response.setNote('lasterrorinfo', 'internal error') + response.setResult('error') + return + } +} + +LOG.error("Recovery: userDto missing or failure before (lasterror='${notes.getProperty('lasterror', '-')}')") +response.setNote('lasterror', '9909') +response.setNote('lasterrorinfo', 'internal error') +response.setResult('error') +return diff --git a/patterns/9ff0369f3cf662f95d94ff09_resources/ensureRecoveryCode.groovy b/patterns/9ff0369f3cf662f95d94ff09_resources/ensureRecoveryCode.groovy index 22f8a61..b147744 100644 --- a/patterns/9ff0369f3cf662f95d94ff09_resources/ensureRecoveryCode.groovy +++ b/patterns/9ff0369f3cf662f95d94ff09_resources/ensureRecoveryCode.groovy @@ -30,14 +30,22 @@ String endPoint = "${parameters.get('utility-service.baseUrl')}/api/v1/recovery/ def userDto = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto')) def recoveryCredential = userDto.'**'.find {node -> node.name() == 'credentials' && node.type.text() == 'CONTEXT_PASSWORD' && node.context.text() == 'RECOVERY'} -// 1a) check if user has a credential +// Only for aq 100, skip for the rest +if (Arrays.stream(response.getActualRoles()).filter( r -> r.matches('^.*AGOV-Loi\\.level[2345]00.*$')).findAny().isPresent()) { + LOG.debug("Account '${user}' has a higher AQ-level than 100, no need to check code") + response.setResult('done') + return +} + + +// 1b) check if user has a credential if ( recoveryCredential != null ) { LOG.debug("Account '${user}' has an active recovery code, no need to create new code") response.setResult('done') return } -// 1b) check if a recovery is ongoing (nothing to do) +// 1c) check if a recovery is ongoing (nothing to do) if (Arrays.stream(response.getActualRoles()).filter( r -> r.contains('AGOV-AccountStatus.recovery')).findAny().isPresent()) { LOG.debug("Account '${user}' is in recovery, no need to create new code") response.setResult('done') diff --git a/patterns/Fetch_Country_Name_594764b3b866d7855f6990a1.yml b/patterns/Fetch_Country_Name_594764b3b866d7855f6990a1.yml index 46cfa5c..878a345 100644 --- a/patterns/Fetch_Country_Name_594764b3b866d7855f6990a1.yml +++ b/patterns/Fetch_Country_Name_594764b3b866d7855f6990a1.yml @@ -3,6 +3,7 @@ pattern: id: "594764b3b866d7855f6990a1" className: "ch.nevis.admin.v4.plugin.nevisauth.patterns2.GenericAuthenticationStep" name: "Fetch_Country_Name" + notes: "TODO/haburger/2024-12-17: replace this with a call to http://utility-application-be.adn-agov-me-01-dev:8081/utility/api/v1/countries?lang=DE" properties: authStatesFile: "res://594764b3b866d7855f6990a1#authStatesFile" onSuccess: diff --git a/patterns/Utility_Resource_Service_Countries_Security_Filter_3a982aa242ff4f8ebd823693.yml b/patterns/Utility_Resource_Service_Countries_Security_Filter_3a982aa242ff4f8ebd823693.yml new file mode 100644 index 0000000..31486b2 --- /dev/null +++ b/patterns/Utility_Resource_Service_Countries_Security_Filter_3a982aa242ff4f8ebd823693.yml @@ -0,0 +1,7 @@ +schemaVersion: "1.0" +pattern: + id: "3a982aa242ff4f8ebd823693" + className: "ch.nevis.admin.v4.plugin.nevisproxy.patterns.LuaPattern" + name: "Utility_Resource_Service_Countries_Security_Filter" + properties: + script: "res://3a982aa242ff4f8ebd823693#script" diff --git a/patterns/Utility_Resource_Service_eaa622e2a760704c1e0e22f2.yml b/patterns/Utility_Resource_Service_eaa622e2a760704c1e0e22f2.yml new file mode 100644 index 0000000..0ecbc51 --- /dev/null +++ b/patterns/Utility_Resource_Service_eaa622e2a760704c1e0e22f2.yml @@ -0,0 +1,13 @@ +schemaVersion: "1.0" +pattern: + id: "eaa622e2a760704c1e0e22f2" + className: "ch.nevis.admin.v4.plugin.nevisproxy.patterns.RESTServiceAccess" + name: "Utility_Resource_Service" + properties: + host: + - "pattern://1f0702aaabef60a615abf41f" + path: "/resource/utility/" + addons: + - "pattern://3a982aa242ff4f8ebd823693" + backends: "var://utility_resource_service-backend-address" + allowedMethods: "GET" diff --git a/variables.yml b/variables.yml index 9ad399f..48e3de7 100644 --- a/variables.yml +++ b/variables.yml @@ -965,6 +965,17 @@ variables: minRequired: 0 value: null requireOverloading: true + utility_resource_service-backend-address: + className: "ch.nevis.admin.v4.plugin.base.generation.property.URLProperty" + parameters: + minRequired: 1 + schemeInputMode: "OPTIONAL" + allowedSchemes: "http,https" + hostNameInputMode: "REQUIRED" + portInputMode: "OPTIONAL" + pathInputMode: "OPTIONAL" + value: "http://utility-application-be.adn-agov-me-01-dev:8081/utility/" + requireOverloading: true verify_shadow_user-parameters: className: "ch.nevis.admin.v4.plugin.base.generation.property.TextProperty" parameters: