2 files added and 7 files updated
This commit is contained in:
parent
76a7ac7695
commit
49d8eaf672
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
Binary file not shown.
Binary file not shown.
|
@ -193,11 +193,12 @@
|
||||||
</Gui>
|
</Gui>
|
||||||
</Response>
|
</Response>
|
||||||
<property name="scriptTraceGroup" value="Recovery"/>
|
<property name="scriptTraceGroup" value="Recovery"/>
|
||||||
<property name="script" value="file:///var/opt/nevisauth/default/conf/recovery-preprocessing.groovy"/>
|
<property name="script" value="file:///var/opt/nevisauth/default/conf/recovery-processing.groovy"/>
|
||||||
</AuthState>
|
</AuthState>
|
||||||
<AuthState name="${state.entry}_IdmUserIdPasswordLogin" final="true" resumeState="true" class="ch.nevis.idm.authstate.IdmPasswordVerifyState">
|
<AuthState name="${state.entry}_IdmUserIdPasswordLogin" final="true" resumeState="true" class="ch.nevis.idm.authstate.IdmPasswordVerifyState">
|
||||||
<ResultCond name="ok" next="${state.exit.1}" authLevel="auth.weak"/>
|
<ResultCond name="no_code-true" next="${state.exit.1}"/>
|
||||||
<ResultCond name="pwChange" next="${state.entry}_IdmUserIdPasswordLogin" authLevel="auth.weak"/>
|
<ResultCond name="ok" next="${state.entry}_codeVerified"/>
|
||||||
|
<ResultCond name="pwChange" next="${state.entry}_IdmUserIdPasswordLogin"/>
|
||||||
<ResultCond name="lockWarn" next="${state.entry}_IdmUserIdPasswordLogin"/>
|
<ResultCond name="lockWarn" next="${state.entry}_IdmUserIdPasswordLogin"/>
|
||||||
<ResultCond name="nowLocked" next="${state.entry}_codeLocked"/>
|
<ResultCond name="nowLocked" next="${state.entry}_codeLocked"/>
|
||||||
<ResultCond name="locked" next="${state.entry}_codeLocked"/>
|
<ResultCond name="locked" next="${state.entry}_codeLocked"/>
|
||||||
|
@ -209,6 +210,7 @@
|
||||||
<Gui name="recovery_check_code">
|
<Gui name="recovery_check_code">
|
||||||
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
|
<GuiElem name="lasterror" type="error" label="${notes:lasterrorinfo}" value="${notes:lasterror}"/>
|
||||||
<GuiElem name="code" type="pw-text" label="not-used" value="hide-input-in-logs" optional="true"/>
|
<GuiElem name="code" type="pw-text" label="not-used" value="hide-input-in-logs" optional="true"/>
|
||||||
|
<GuiElem name="no_code" type="checkbox" label="not-used" value="true" optional="true"/>
|
||||||
<GuiElem name="authRequestId" type="hidden" value="${sess:ch.nevis.auth.saml.request.id}" optional="true"/>
|
<GuiElem name="authRequestId" type="hidden" value="${sess:ch.nevis.auth.saml.request.id}" optional="true"/>
|
||||||
</Gui>
|
</Gui>
|
||||||
</Response>
|
</Response>
|
||||||
|
@ -220,6 +222,11 @@
|
||||||
<property name="user.loginid" value="${sess:ch.adnovum.nevisidm.user.loginId}"/>
|
<property name="user.loginid" value="${sess:ch.adnovum.nevisidm.user.loginId}"/>
|
||||||
<property name="client.name" value="agov"/>
|
<property name="client.name" value="agov"/>
|
||||||
</AuthState>
|
</AuthState>
|
||||||
|
<AuthState name="${state.entry}_codeVerified" class="ch.nevis.esauth.auth.states.standard.TransformAttributes" final="false" resumeState="false">
|
||||||
|
<ResultCond name="default" next="${state.exit.1}"/>
|
||||||
|
<Response value="AUTH_CONTINUE"/>
|
||||||
|
<property name="sess:agov.recovery.authenticatedWith" value="urn:qa.agov.ch:names:tc:authfactor:emailAndCode"/>
|
||||||
|
</AuthState>
|
||||||
<AuthState name="${state.entry}_codeLocked" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true" resumeState="false">
|
<AuthState name="${state.entry}_codeLocked" class="ch.nevis.esauth.auth.states.standard.AuthGeneric" final="true" resumeState="false">
|
||||||
<Response value="AUTH_ERROR">
|
<Response value="AUTH_ERROR">
|
||||||
<Gui name="recovery_check_noCode">
|
<Gui name="recovery_check_noCode">
|
||||||
|
|
|
@ -1,192 +1,191 @@
|
||||||
import org.codehaus.groovy.runtime.StackTraceUtils
|
import org.codehaus.groovy.runtime.StackTraceUtils
|
||||||
import groovy.xml.XmlSlurper
|
import groovy.xml.XmlSlurper
|
||||||
|
|
||||||
|
|
||||||
// AGOVaq conversion
|
// AGOVaq conversion
|
||||||
def maxLoiRoleToCtxClssConvertorMap = [
|
def maxLoiRoleToCtxClssConvertorMap = [
|
||||||
"level100": "urn:qa.agov.ch:names:tc:ac:classes:100",
|
"level100": "urn:qa.agov.ch:names:tc:ac:classes:100",
|
||||||
"level200": "urn:qa.agov.ch:names:tc:ac:classes:200",
|
"level200": "urn:qa.agov.ch:names:tc:ac:classes:200",
|
||||||
"level300": "urn:qa.agov.ch:names:tc:ac:classes:300",
|
"level300": "urn:qa.agov.ch:names:tc:ac:classes:300",
|
||||||
"level400": "urn:qa.agov.ch:names:tc:ac:classes:400",
|
"level400": "urn:qa.agov.ch:names:tc:ac:classes:400",
|
||||||
"level500": "urn:qa.agov.ch:names:tc:ac:classes:500"
|
"level500": "urn:qa.agov.ch:names:tc:ac:classes:500"
|
||||||
]
|
]
|
||||||
|
|
||||||
def getUserIdVerificationForRecovery(currentLoaRole) {
|
def getUserIdVerificationForRecovery(currentLoaRole) {
|
||||||
// application is AGOV-AccountStatus
|
// application is AGOV-AccountStatus
|
||||||
def list = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto'))
|
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()
|
def result = list.'**'.find {node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-AccountStatus,mustRecover'}?.value?.text()
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
// fallback if not explicitly set
|
// fallback if not explicitly set
|
||||||
def chDomicile = list.country.text() == 'ch'
|
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'
|
def lastIdVerification = list.'**'.find {node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-Loi,' + currentLoaRole}?.value?.text() ?: 'missing'
|
||||||
switch (currentLoaRole) {
|
switch (currentLoaRole) {
|
||||||
case 'level100':
|
case 'level100':
|
||||||
result = chDomicile ? 'SimpleLetter' : 'Video'
|
result = chDomicile ? 'SimpleLetter' : 'Video'
|
||||||
break
|
break
|
||||||
case 'level200':
|
case 'level200':
|
||||||
result = chDomicile ? 'Bmid' : 'Video'
|
result = chDomicile ? 'Bmid' : 'Video'
|
||||||
break
|
break
|
||||||
case 'level300':
|
case 'level300':
|
||||||
case 'level400':
|
case 'level400':
|
||||||
result = chDomicile ? lastIdVerification : 'Video'
|
result = chDomicile ? lastIdVerification : 'Video'
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
LOG.warn("unexpected loa on account: ${currentLoaRole}")
|
LOG.warn("unexpected loa on account: ${currentLoaRole}")
|
||||||
// safest default, should work in any case
|
// safest default, should work in any case
|
||||||
result = 'Video'
|
result = 'Video'
|
||||||
}
|
}
|
||||||
LOG.warn("Recovery method not set, choosing ${result} (based on currentLoad: ${currentLoaRole}, CH-domicile: ${chDomicile}, last verification method: ${lastIdVerification})")
|
LOG.warn("Recovery method not set, choosing ${result} (based on currentLoad: ${currentLoaRole}, CH-domicile: ${chDomicile}, last verification method: ${lastIdVerification})")
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAqLevelBasedOnIdVerificationForRecovery(idVerification, highestRoleLevel) {
|
def getAqLevelBasedOnIdVerificationForRecovery(idVerification, highestRoleLevel) {
|
||||||
def result = 'level'
|
def result = 'level'
|
||||||
|
|
||||||
switch (idVerification) {
|
switch (idVerification) {
|
||||||
case 'None':
|
case 'None':
|
||||||
result = result.concat('100')
|
result = result.concat('100')
|
||||||
break
|
break
|
||||||
case 'SimpleLetter':
|
case 'SimpleLetter':
|
||||||
result = result.concat('200')
|
result = result.concat('200')
|
||||||
break
|
break
|
||||||
case 'Video':
|
case 'Video':
|
||||||
case 'VideoSelfPaid':
|
case 'VideoSelfPaid':
|
||||||
case 'Bmid':
|
case 'Bmid':
|
||||||
case 'BmidSelfPaid':
|
case 'BmidSelfPaid':
|
||||||
case 'Counter':
|
case 'Counter':
|
||||||
result = result.concat((highestRoleLevel == 'level400') ? '400' : '300')
|
result = result.concat((highestRoleLevel == 'level400') ? '400' : '300')
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
LOG.warn("unexpected idVerification for recovery on account: ${idVerification}")
|
LOG.warn("unexpected idVerification for recovery on account: ${idVerification}")
|
||||||
// safest default, should work in any case
|
// safest default, should work in any case
|
||||||
result = highestRoleLevel
|
result = highestRoleLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
def getUserMustRecoverValidFrom() {
|
def getUserMustRecoverValidFrom() {
|
||||||
// set attibutes from DTO: -> validFrom
|
// set attibutes from DTO: -> validFrom
|
||||||
def payload = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto'))
|
def payload = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto'))
|
||||||
def authzNode = payload.'**'.find {node -> node.name() == 'authorizations' && node.role.name.text() == 'mustRecover'}
|
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()) : ''
|
return (authzNode) ? ((authzNode.validFrom && !authzNode.validFrom.text().isEmpty()) ? authzNode.validFrom?.text() : authzNode.ctlCreDat?.text()) : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// for autditing
|
// for autditing
|
||||||
def user = session['ch.adnovum.nevisidm.user.extId'] ?: 'unknown'
|
def user = session['ch.adnovum.nevisidm.user.extId'] ?: 'unknown'
|
||||||
def sourceIp = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: '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 userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown'
|
||||||
def maxLoi = null
|
def maxLoi = null
|
||||||
|
|
||||||
|
|
||||||
// new
|
// new
|
||||||
if (session['ch.adnovum.nevisidm.userDto'] != null && notes['lasterror'] == null) {
|
if (session['ch.adnovum.nevisidm.userDto'] != null && notes['lasterror'] == null) {
|
||||||
try {
|
try {
|
||||||
def userDto = new XmlSlurper().parseText(session['ch.adnovum.nevisidm.userDto'])
|
def userDto = new XmlSlurper().parseText(session['ch.adnovum.nevisidm.userDto'])
|
||||||
def userState = userDto.state
|
def userState = userDto.state
|
||||||
LOG.debug("Recovery: Dto is '${userDto}")
|
LOG.debug("Recovery: Dto is '${userDto}")
|
||||||
LOG.debug("Recovery: state is '${userState}")
|
LOG.debug("Recovery: state is '${userState}")
|
||||||
def session = request.getAuthSession(true)
|
def session = request.getAuthSession(true)
|
||||||
|
|
||||||
if (userState == 'ACTIVE') {
|
if (userState == 'ACTIVE') {
|
||||||
|
|
||||||
session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes:recovery')
|
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 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
|
def idVerification = null
|
||||||
if (maxLoi) {
|
def agovAqValidFrom = null
|
||||||
idVerification = userDto.'**'.find { node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-Loi,' + maxLoi}?.value?.text()
|
if (maxLoi) {
|
||||||
idVerification = idVerification ?: 'None'
|
idVerification = userDto.'**'.find { node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-Loi,' + maxLoi}?.value?.text()
|
||||||
agovAqValidFrom = userDto.'**'.find { node -> node.name() == 'authorizations' && node.role.name.text() == maxLoi}?.validFrom?.text()
|
idVerification = idVerification ?: 'None'
|
||||||
agovAqValidFrom = agovAqValidFrom?: userDto.'**'.find { node -> node.name() == 'authorizations' && node.role.name.text() == maxLoi}?.ctlCreDat?.text()
|
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 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' }
|
|
||||||
|
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
|
if (mustRecover) {
|
||||||
session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes: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
|
|
||||||
|
idVerification = getUserIdVerificationForRecovery(maxLoi ?: 'level100') ?: idVerification
|
||||||
agovAqValidFrom = getUserMustRecoverValidFrom()
|
|
||||||
|
agovAqValidFrom = getUserMustRecoverValidFrom()
|
||||||
maxLoi = getAqLevelBasedOnIdVerificationForRecovery(idVerification, maxLoi)
|
|
||||||
}
|
maxLoi = getAqLevelBasedOnIdVerificationForRecovery(idVerification, maxLoi)
|
||||||
|
}
|
||||||
LOG.debug("Recovery: MaxLoi is '${maxLoi}'")
|
|
||||||
LOG.debug("Recovery: IdVerification is ${idVerification}")
|
LOG.debug("Recovery: MaxLoi is '${maxLoi}'")
|
||||||
LOG.debug("Recovery: agovAqValidFrom is ${agovAqValidFrom}")
|
LOG.debug("Recovery: IdVerification is ${idVerification}")
|
||||||
LOG.debug("Recovery: mustRecover is '${mustRecover}'")
|
LOG.debug("Recovery: agovAqValidFrom is ${agovAqValidFrom}")
|
||||||
LOG.debug("Recovery: hasRecoveryRole is '${hasRecoveryRole}'")
|
LOG.debug("Recovery: mustRecover is '${mustRecover}'")
|
||||||
|
LOG.debug("Recovery: hasRecoveryRole is '${hasRecoveryRole}'")
|
||||||
if (maxLoi != null) {
|
|
||||||
if (maxLoiRoleToCtxClssConvertorMap.containsKey(maxLoi)) {
|
if (maxLoi != null) {
|
||||||
LOG.debug("Recovery: MaxLoiMapping is " + maxLoiRoleToCtxClssConvertorMap[maxLoi])
|
if (maxLoiRoleToCtxClssConvertorMap.containsKey(maxLoi)) {
|
||||||
response.setSessionAttribute('agov.recovery.currentAgovAq', '' + maxLoiRoleToCtxClssConvertorMap[maxLoi])
|
LOG.debug("Recovery: MaxLoiMapping is " + maxLoiRoleToCtxClssConvertorMap[maxLoi])
|
||||||
response.setSessionAttribute('agov.recovery.currentIdVerification', '' + idVerification)
|
response.setSessionAttribute('agov.recovery.currentAgovAq', '' + maxLoiRoleToCtxClssConvertorMap[maxLoi])
|
||||||
response.setSessionAttribute('agov.recovery.currentAgovAqRoleValidFrom', '' + agovAqValidFrom)
|
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
|
if ((maxLoi == 'level100') && (mustRecover == null)) {
|
||||||
LOG.debug("Recovery: emailAndCode")
|
// mustRecover role not set, so code needs to be checked
|
||||||
response.setSessionAttribute('agov.recovery.authenticatedWith', 'urn:qa.agov.ch:names:tc:authfactor:emailAndCode')
|
LOG.debug("Recovery: emailAndCode")
|
||||||
response.setResult('needCode')
|
response.setResult('needCode')
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
LOG.debug("Recovery: email")
|
LOG.debug("Recovery: email")
|
||||||
response.setSessionAttribute('agov.recovery.authenticatedWith', 'urn:qa.agov.ch:names:tc:authfactor:email')
|
response.setResult('ok')
|
||||||
response.setResult('ok')
|
return
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
} else {
|
||||||
} else {
|
LOG.error("Recovery: Failed to convert '${maxLoi}' to AGOVaq")
|
||||||
LOG.error("Recovery: Failed to convert '${maxLoi}' to AGOVaq")
|
response.setResult('error')
|
||||||
response.setResult('error')
|
return
|
||||||
return
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
// maxLoi is null
|
||||||
// maxLoi is null
|
LOG.debug("Recovery: no 'AGOV-Loi'-role assigned to user ${user}")
|
||||||
LOG.debug("Recovery: no 'AGOV-Loi'-role assigned to user ${user}")
|
if ((hasRecoveryRole != null) && (mustRecover == null)) {
|
||||||
if ((hasRecoveryRole != null) && (mustRecover == null)) {
|
response.setResult('notFullyRegistered')
|
||||||
response.setResult('notFullyRegistered')
|
return
|
||||||
return
|
} else {
|
||||||
} else {
|
LOG.error("Recovery: no 'AGOV-Loi'-role assigned to user ${user} and no recovery role ")
|
||||||
LOG.error("Recovery: no 'AGOV-Loi'-role assigned to user ${user} and no recovery role ")
|
response.setResult('error')
|
||||||
response.setResult('error')
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
// state != ACTIVE and no lasterror should not happen
|
||||||
// state != ACTIVE and no lasterror should not happen
|
LOG.error("Recovery: state='${userState}' but not lasterror set")
|
||||||
LOG.error("Recovery: state='${userState}' but not lasterror set")
|
response.setNote('lasterror', '9909')
|
||||||
response.setNote('lasterror', '9909')
|
response.setNote('lasterrorinfo', 'internal error')
|
||||||
response.setNote('lasterrorinfo', 'internal error')
|
response.setResult('error')
|
||||||
response.setResult('error')
|
return
|
||||||
return
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
e = StackTraceUtils.sanitize(e)
|
||||||
e = StackTraceUtils.sanitize(e)
|
def affectedLines = e.stackTrace.findAll { it.className.startsWith('Script') }.collect { "${it.methodName}:${it.lineNumber}" }
|
||||||
def affectedLines = e.stackTrace.findAll { it.className.startsWith('Script') }.collect { "${it.methodName}:${it.lineNumber}" }
|
LOG.error("FATAL: Recovery processing failed (at lines: ${affectedLines})", e)
|
||||||
LOG.error("FATAL: Recovery processing failed (at lines: ${affectedLines})", e)
|
response.setNote('lasterror', '9909')
|
||||||
response.setNote('lasterror', '9909')
|
response.setNote('lasterrorinfo', 'internal error')
|
||||||
response.setNote('lasterrorinfo', 'internal error')
|
response.setResult('error')
|
||||||
response.setResult('error')
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
LOG.error("Recovery: userDto missing or failure before (lasterror='${notes.getProperty('lasterror', '-')}')")
|
||||||
LOG.error("Recovery: userDto missing or failure before (lasterror='${notes.getProperty('lasterror', '-')}')")
|
response.setNote('lasterror', '9909')
|
||||||
response.setNote('lasterror', '9909')
|
response.setNote('lasterrorinfo', 'internal error')
|
||||||
response.setNote('lasterrorinfo', 'internal error')
|
response.setResult('error')
|
||||||
response.setResult('error')
|
return
|
||||||
return
|
|
|
@ -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 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'}
|
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 ) {
|
if ( recoveryCredential != null ) {
|
||||||
LOG.debug("Account '${user}' has an active recovery code, no need to create new code")
|
LOG.debug("Account '${user}' has an active recovery code, no need to create new code")
|
||||||
response.setResult('done')
|
response.setResult('done')
|
||||||
return
|
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()) {
|
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")
|
LOG.debug("Account '${user}' is in recovery, no need to create new code")
|
||||||
response.setResult('done')
|
response.setResult('done')
|
||||||
|
|
|
@ -3,6 +3,7 @@ pattern:
|
||||||
id: "594764b3b866d7855f6990a1"
|
id: "594764b3b866d7855f6990a1"
|
||||||
className: "ch.nevis.admin.v4.plugin.nevisauth.patterns2.GenericAuthenticationStep"
|
className: "ch.nevis.admin.v4.plugin.nevisauth.patterns2.GenericAuthenticationStep"
|
||||||
name: "Fetch_Country_Name"
|
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:
|
properties:
|
||||||
authStatesFile: "res://594764b3b866d7855f6990a1#authStatesFile"
|
authStatesFile: "res://594764b3b866d7855f6990a1#authStatesFile"
|
||||||
onSuccess:
|
onSuccess:
|
||||||
|
|
|
@ -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"
|
|
@ -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"
|
|
@ -965,6 +965,17 @@ variables:
|
||||||
minRequired: 0
|
minRequired: 0
|
||||||
value: null
|
value: null
|
||||||
requireOverloading: true
|
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:
|
verify_shadow_user-parameters:
|
||||||
className: "ch.nevis.admin.v4.plugin.base.generation.property.TextProperty"
|
className: "ch.nevis.admin.v4.plugin.base.generation.property.TextProperty"
|
||||||
parameters:
|
parameters:
|
||||||
|
|
Loading…
Reference in New Issue