new configuration version
This commit is contained in:
parent
ecdb8bdfb5
commit
5e57baad3b
|
@ -45,7 +45,7 @@ spec:
|
|||
podDisruptionBudget:
|
||||
maxUnavailable: "50%"
|
||||
git:
|
||||
tag: "r-9af6a792e2720efb1d09318c1e3f4a2ab355af31"
|
||||
tag: "r-db9522d1110b41177e7d034419ef1fb68f95b0b8"
|
||||
dir: "DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth"
|
||||
credentials: "git-credentials"
|
||||
keystores:
|
||||
|
|
|
@ -68,6 +68,32 @@ def getUserIdVerificationForRecovery() {
|
|||
return result
|
||||
}
|
||||
|
||||
def getAqLevelBasedOnIdVerificationForRecovery(idVerification, highestRoleLevelNumber) {
|
||||
def result = 'urn:qa.agov.ch:names:tc:ac:classes:'
|
||||
|
||||
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((highestRoleLevelNumber == 400) ? '400' : '300')
|
||||
break
|
||||
default:
|
||||
LOG.warn("unexpected idVerification for recovery on account: ${idVerification}")
|
||||
// safest default, should work in any case
|
||||
result = result.concat('' + highestRoleLevelNumber)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
def getUserMustRecoverValidFrom() {
|
||||
// set attibutes from DTO: -> validFrom
|
||||
def payload = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto'))
|
||||
|
@ -95,9 +121,9 @@ try {
|
|||
adressVerification = adressVerificationList[0]
|
||||
}
|
||||
|
||||
LOG.debug('Requested role level '+ requestedRoleLevelNumber)
|
||||
LOG.debug('idVerification: ' + getUserAGOVLoiIdVerification())
|
||||
LOG.debug('adressVerification : ' + adressVerification)
|
||||
LOG.debug('CheckLoa: Requested role level '+ requestedRoleLevelNumber)
|
||||
LOG.debug('CheckLoa: idVerification: ' + getUserAGOVLoiIdVerification())
|
||||
LOG.debug('CheckLoa: adressVerification : ' + adressVerification)
|
||||
|
||||
def idVerificationMethodList = getUserAGOVLoiIdVerification()
|
||||
|
||||
|
@ -143,12 +169,12 @@ try {
|
|||
}
|
||||
}
|
||||
}
|
||||
LOG.debug('Highest role Level' + highestRoleLevelNumber.toString() +' contextclassref' + requestedRoleLevelNumber.toString())
|
||||
LOG.debug(' Compare' + (highestRoleLevelNumber>=requestedRoleLevelNumber))
|
||||
LOG.debug('CheckLoa: Highest role Level' + highestRoleLevelNumber.toString() +' contextclassref' + requestedRoleLevelNumber.toString())
|
||||
LOG.debug('CheckLoa: Compare' + (highestRoleLevelNumber>=requestedRoleLevelNumber))
|
||||
|
||||
//set attribute Actual Role Level
|
||||
session.setAttribute('agov.actualRoleLevel', '' + highestRoleLevelNumber)
|
||||
LOG.debug('actual role level (agov) '+ highestRoleLevelNumber)
|
||||
LOG.debug('CheckLoa: actual role level (agov) '+ highestRoleLevelNumber)
|
||||
|
||||
if (highestRoleLevelNumber > 0) {
|
||||
// set attribute contextClassRefToSet
|
||||
|
@ -165,18 +191,19 @@ try {
|
|||
session.setAttribute('agov.recovery.authenticatedWith', session.getAttribute('authenticatedWith') ?: 'unknown' )
|
||||
|
||||
def origIdVerification = getUserAGOVLoiIdVerification(highestRoleLevelNumber.toString()) ?: 'None'
|
||||
if (highestRoleLevelNumber < 300) {
|
||||
// plus 100, if mustRecover
|
||||
highestRoleLevelNumber += 100
|
||||
}
|
||||
session.setAttribute('agov.recovery.currentAgovAq', 'urn:qa.agov.ch:names:tc:ac:classes:'.concat(highestRoleLevelNumber.toString()) )
|
||||
|
||||
def idVerification = getUserIdVerificationForRecovery() ?: origIdVerification
|
||||
session.setAttribute('agov.recovery.currentIdVerification', '' + idVerification )
|
||||
|
||||
// align currentAgovAq with the method selected for idVerification
|
||||
def currentAgovAqForRecovery = getAqLevelBasedOnIdVerificationForRecovery(idVerification, highestRoleLevelNumber)
|
||||
session.setAttribute('agov.recovery.currentAgovAq', '' + currentAgovAqForRecovery)
|
||||
|
||||
def validFrom = getUserMustRecoverValidFrom() ?: ''
|
||||
session.setAttribute('agov.recovery.currentAgovAqRoleValidFrom', '' + validFrom )
|
||||
|
||||
LOG.debug("CheckLoa: mustRecover: origIdVerification=${origIdVerification}, idVerification=${idVerification}, currentAgovAqForRecovery=${currentAgovAqForRecovery}")
|
||||
|
||||
response.setResult('exit.2')
|
||||
return
|
||||
|
||||
|
@ -184,7 +211,7 @@ try {
|
|||
session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes:recovery')
|
||||
session.setAttribute('agov.recovery.authenticatedWith', session.getAttribute('authenticatedWith') ?: 'unknown')
|
||||
session.setAttribute('agov.recovery.currentAgovAq', session.getAttribute('contextClassRefToSet') ?: 'urn:qa.agov.ch:names:tc:ac:classes:100' )
|
||||
LOG.debug('idVerification2= '+ getUserAGOVLoiIdVerification(highestRoleLevelNumber.toString()))
|
||||
LOG.debug('CheckLoa: idVerification2= '+ getUserAGOVLoiIdVerification(highestRoleLevelNumber.toString()))
|
||||
def idVerification = getUserAGOVLoiIdVerification(highestRoleLevelNumber.toString())
|
||||
session.setAttribute('agov.recovery.currentIdVerification', (idVerification.isEmpty() ? 'None' : idVerification.first()))
|
||||
def validFrom = getUserAGOVLoiValidFrom('level'.concat(highestRoleLevelNumber.toString())) ?: ''
|
||||
|
@ -202,8 +229,8 @@ try {
|
|||
def validFrom = getUserAGOVLoiValidFrom('level'.concat(highestRoleLevelNumber.toString()))
|
||||
def validTo = getUserAGOVLoiValidTo('level'.concat(highestRoleLevelNumber.toString()))
|
||||
|
||||
LOG.debug('ValidFrom :' + validFrom)
|
||||
LOG.debug('ValidTo :' + validTo)
|
||||
LOG.debug('CheckLoa: ValidFrom :' + validFrom)
|
||||
LOG.debug('CheckLoa: ValidTo :' + validTo)
|
||||
|
||||
if(validFrom != '') {
|
||||
session.setAttribute('ValidFrom', '' + validFrom)
|
||||
|
|
|
@ -4,7 +4,6 @@ import ch.nevis.idm.client.IdmRestClientFactory
|
|||
import ch.nevis.idm.client.HTTPRequestWrapper
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
import groovy.xml.XmlSlurper
|
||||
|
||||
// Accounting
|
||||
def requester = session['ch.nevis.auth.saml.request.scoping.requesterId'] ?: 'unknown'
|
||||
|
@ -15,91 +14,112 @@ def credentialType = session['authenticatedWith'] ?: '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'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IdmRestClient idmRestClient = IdmRestClientFactory.get(parameters)
|
||||
|
||||
String clientExtId = session.get('ch.adnovum.nevisidm.user.clientExtId')
|
||||
String userExtId = session.get('ch.adnovum.nevisidm.user.extId')
|
||||
String sessionId = session.get('ch.nevis.session.conversationId')
|
||||
String loginId = session.get('ch.adnovum.nevisidm.user.loginId')
|
||||
String profileExtId = session.get('ch.adnovum.nevisidm.profileExtId')
|
||||
|
||||
String endPoint = "${parameters.get('utility-service.baseUrl')}/api/v1/recovery/code"
|
||||
String unitExtid= parameters.get('unitExtid')
|
||||
String level100RoleExtid = parameters.get('level100.roleExtid')
|
||||
|
||||
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.state.text() == 'ACTIVE' && node.context.text() == 'RECOVERY'}
|
||||
String baseUrl = "${parameters.get('idm.baseUrl')}/core/v1/$clientExtId"
|
||||
boolean audited = false
|
||||
String agovAq100AuthEndpoint = null
|
||||
String endpoint = null
|
||||
|
||||
// 1a) 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
|
||||
}
|
||||
// 1) create the profile if needed
|
||||
if (profileExtId == null || profileExtId.isEmpty()) {
|
||||
|
||||
// 1b) 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')
|
||||
return
|
||||
}
|
||||
endpoint = "${baseUrl}/users/${userExtId}/profiles"
|
||||
profileExtId = UUID.randomUUID().toString()
|
||||
|
||||
def postRequest = new HTTPRequestWrapper()
|
||||
postRequest.addToHeaders('Content-Type', ['application/json'])
|
||||
|
||||
// 2) set cookie for recoveryCode
|
||||
if (outargs.containsKey('out.JWTToken')) {
|
||||
def token = outargs.getProperty('out.JWTToken').bytes.encodeBase64().toString()
|
||||
def agovRecoveryCodeCookie = "agovRecoveryCode=${token }; Domain=${parameters.get('cookie.domain')}; Path=/; SameSite=Strict; Secure; HttpOnly"
|
||||
response.setHeader('Set-Cookie', agovRecoveryCodeCookie)
|
||||
outargs.remove('out.JWTToken')
|
||||
}
|
||||
def dto = "{\"extId\":\"${profileExtId}\",\"unitExtId\":\"${unitExtid}\",\"profileState\":\"active\",\"name\":\"Profile-${loginId}\",\"isDefaultProfile\":true,\"modificationComment\":\"Repaired for request ${requestId}\"}"
|
||||
postRequest.setPayLoad(dto.getBytes('UTF-8'))
|
||||
|
||||
// 3) generate code if not yet done
|
||||
if (!session['agov.new.recovery.code.generated']) {
|
||||
inargs.remove('submit')
|
||||
try {
|
||||
def postRequest = new HTTPRequestWrapper()
|
||||
postRequest.addToHeaders('Content-Type', ['application/json'])
|
||||
def result = idmRestClient.postWithResponse(endpoint, postRequest)
|
||||
if (result.getStatusCode() != 201) {
|
||||
LOG.error("Event='DATAERROR', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='Failed to create the missing profile (http status code ${result.getStatusCode()})'")
|
||||
|
||||
postRequest.setPayLoad("{\"userExtId\":\"$userExtId\",\"userSessionId\": \"$sessionId\"}".getBytes('UTF-8'))
|
||||
|
||||
def result = idmRestClient.postWithResponse(endPoint, postRequest)
|
||||
if (result.getStatusCode() != 200) {
|
||||
LOG.debug("Payload: ${new String(postRequest.getPayLoad())}")
|
||||
LOG.debug("Result: ${result}")
|
||||
LOG.warn("Event='RCVRY-CODE', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='Failed to create code (http status code ${result.getStatusCode()})")
|
||||
response.setResult('failed')
|
||||
return
|
||||
}
|
||||
response.setNote('saml.errorCode', 'Responder')
|
||||
response.setNote('saml.errorMessage', "account of the user with agovId ${userExtId} is in a corrupt state, should contact agov help")
|
||||
|
||||
def json = new JsonSlurper().parseText(new String(result.getPayLoad(), 'UTF-8'))
|
||||
|
||||
notes.setProperty('agov.new.recovery.code', json['recoveryCode']['code'].replaceAll('^(....)(....)(.*)$', '$1-$2-$3'))
|
||||
LOG.debug("agov.new.recovery.code: ${notes['agov.new.recovery.code']}")
|
||||
|
||||
response.setSessionAttribute('agov.new.recovery.code.generated', 'true')
|
||||
def validTil = "${json['recoveryCode']['validUntil'][2]}.${json['recoveryCode']['validUntil'][1]}.${json['recoveryCode']['validUntil'][0]}"
|
||||
response.setSessionAttribute('agov.new.recovery.code.validTil', validTil)
|
||||
response.setSessionAttribute('agov.new.recovery.code.pdfAuthToken', json['authToken'])
|
||||
|
||||
LOG.info("Event='RCVRY-CODE', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}'")
|
||||
|
||||
} catch(Exception e) {
|
||||
LOG.warn("Event='RCVRY-CODE', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='Failed to create code (http status code ${e.getMessage()})")
|
||||
LOG.error("Recoverycode processing failed: $e")
|
||||
response.setResult('failed')
|
||||
return
|
||||
} else {
|
||||
LOG.warn("Event='DATAERROR', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='created missing profile'")
|
||||
audited = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2) add level 100 role if needed
|
||||
if (!Arrays.stream(response.getActualRoles()).filter( r -> r.contains('AGOV-Loi.level100')).findAny().isPresent()) {
|
||||
endpoint = "${baseUrl}/profiles/${profileExtId}/authorizations"
|
||||
def postRequest = new HTTPRequestWrapper()
|
||||
postRequest.addToHeaders('Content-Type', ['application/json'])
|
||||
|
||||
def dto = "{\"extId\":\"${UUID.randomUUID().toString()}\",\"roleExtId\":\"${level100RoleExtid}\"}"
|
||||
postRequest.setPayLoad(dto.getBytes('UTF-8'))
|
||||
|
||||
def result = idmRestClient.postWithResponse(endpoint, postRequest)
|
||||
if (result.getStatusCode() != 201) {
|
||||
LOG.error("Event='DATAERROR', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='Failed to create the missing AGOVaq 100 role (http status code ${result.getStatusCode()})'")
|
||||
|
||||
response.setNote('saml.errorCode', 'Responder')
|
||||
response.setNote('saml.errorMessage', "account of the user with agovId ${userExtId} is in a corrupt state, should contact agov help")
|
||||
|
||||
response.setResult('failed')
|
||||
return
|
||||
} else if (!audited) {
|
||||
LOG.warn("Event='DATAERROR', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='created missing AGOVaq 100 role'")
|
||||
audited = true
|
||||
}
|
||||
agovAq100AuthEndpoint = result.getLocation()
|
||||
}
|
||||
|
||||
|
||||
// 3) set the AQ level 100 verification to None
|
||||
if (!session['ch.adnovum.nevisidm.userDto'].contains("<properties><name>idVerification</name><value>None</value><scopeName>AGOV-Loi,level100</scopeName></properties>")) {
|
||||
|
||||
if (agovAq100AuthEndpoint == null) {
|
||||
endpoint = "${baseUrl}/profiles/${profileExtId}/authorizations"
|
||||
|
||||
def result = idmRestClient.get(endpoint)
|
||||
def json = new JsonSlurper().parseText(result)
|
||||
|
||||
json['items'].eachWithIndex { az, i ->
|
||||
if (az.roleExtId == level100RoleExtid) {
|
||||
agovAq100AuthEndpoint = "${endpoint}/${az.extId}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response.setResult('encryptCode')
|
||||
return
|
||||
endpoint = "${agovAq100AuthEndpoint}/properties"
|
||||
|
||||
def patchRequest = new HTTPRequestWrapper()
|
||||
patchRequest.addToHeaders('Content-Type', ['application/json'])
|
||||
|
||||
patchRequest.setPayLoad('{"idVerification":"None"}'.getBytes('UTF-8'))
|
||||
|
||||
def result = idmRestClient.patchWithResponse(endpoint, patchRequest)
|
||||
|
||||
if (result.getStatusCode() != 200) {
|
||||
LOG.error("Event='DATAERROR', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='Failed to patch the AGOVaq 100 role (http status code ${result.getStatusCode()})'")
|
||||
|
||||
} else if (!audited) {
|
||||
LOG.warn("Event='DATAERROR', Requester='${requester}', RequestId='${requestId}', RequestedAq=${requestedAq}, User=${user}, CredentialType='${credentialType}', SourceIp=${sourceIp}, UserAgent='${userAgent}', reason='patched AGOVaq 100 role with idVerification'")
|
||||
audited = true
|
||||
}
|
||||
}
|
||||
|
||||
if (inargs['submit']) {
|
||||
def agovRecoveryCodeCookie = "agovRecoveryCode=deleted; Domain=${parameters.get('cookie.domain')}; Path=/; Max-Age=0; SameSite=Strict; Secure; HttpOnly"
|
||||
response.setHeader('Set-Cookie', agovRecoveryCodeCookie)
|
||||
|
||||
if (audited) {
|
||||
response.setResult('reload')
|
||||
} else {
|
||||
response.setResult('done')
|
||||
return
|
||||
}
|
||||
|
||||
// show the GUI
|
||||
response.setStatus(AuthResponse.AUTH_CONTINUE)
|
||||
}
|
|
@ -4,6 +4,7 @@ import ch.nevis.idm.client.IdmRestClientFactory
|
|||
import ch.nevis.idm.client.HTTPRequestWrapper
|
||||
|
||||
import groovy.json.JsonSlurper
|
||||
import groovy.xml.XmlSlurper
|
||||
|
||||
// Accounting
|
||||
def requester = session['ch.nevis.auth.saml.request.scoping.requesterId'] ?: 'unknown'
|
||||
|
@ -26,8 +27,11 @@ String sessionId = session.get('ch.nevis.session.conversationId')
|
|||
|
||||
String endPoint = "${parameters.get('utility-service.baseUrl')}/api/v1/recovery/code"
|
||||
|
||||
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.state.text() == 'ACTIVE' && node.context.text() == 'RECOVERY'}
|
||||
|
||||
// 1a) check if user has a credential
|
||||
if (session['ch.nevis.idm.User.cred.context_password1.state'] == 'ACTIVE' ) {
|
||||
if ( recoveryCredential != null ) {
|
||||
LOG.debug("Account '${user}' has an active recovery code, no need to create new code")
|
||||
response.setResult('done')
|
||||
return
|
||||
|
|
|
@ -521,6 +521,8 @@
|
|||
<!-- source: pattern://c686c1bdd5355351f7f98cc8 -->
|
||||
<property name="user.cred.context_password1.state" value="true"/>
|
||||
<!-- source: pattern://c686c1bdd5355351f7f98cc8 -->
|
||||
<property name="user.cred.context_password1.context" value="true"/>
|
||||
<!-- source: pattern://c686c1bdd5355351f7f98cc8 -->
|
||||
<property name="chooseDefaultProfile" value="true"/>
|
||||
<!-- source: pattern://c686c1bdd5355351f7f98cc8 -->
|
||||
<property name="forceDataReload" value="true"/>
|
||||
|
@ -653,6 +655,8 @@
|
|||
<!-- source: pattern://7fb39bfd6c34685866a22180 -->
|
||||
<property name="user.cred.context_password1.state" value="true"/>
|
||||
<!-- source: pattern://7fb39bfd6c34685866a22180 -->
|
||||
<property name="user.cred.context_password1.context" value="true"/>
|
||||
<!-- source: pattern://7fb39bfd6c34685866a22180 -->
|
||||
<property name="userExtId" value="${sess:ch.nevis.session.userid}"/>
|
||||
<!-- source: pattern://7fb39bfd6c34685866a22180 -->
|
||||
<property name="chooseDefaultProfile" value="true"/>
|
||||
|
@ -722,6 +726,8 @@
|
|||
<!-- source: pattern://f393012a278e525956a362d3 -->
|
||||
<property name="user.cred.context_password1.state" value="true"/>
|
||||
<!-- source: pattern://f393012a278e525956a362d3 -->
|
||||
<property name="user.cred.context_password1.context" value="true"/>
|
||||
<!-- source: pattern://f393012a278e525956a362d3 -->
|
||||
<property name="chooseDefaultProfile" value="true"/>
|
||||
<!-- source: pattern://f393012a278e525956a362d3 -->
|
||||
<property name="forceDataReload" value="true"/>
|
||||
|
@ -1425,7 +1431,7 @@
|
|||
<!-- source: pattern://27cefc3861bce987f6766342 -->
|
||||
<property name="out.attribute.http://schemas.agov.ch/ws/2024/02/identity/claims/address/country" value="#{ (sess['agov.appAddressRequired'] == 'true') ? sess['ch.nevis.idm.User.country'].toUpperCase() : '' }"/>
|
||||
<!-- source: pattern://27cefc3861bce987f6766342 -->
|
||||
<property name="out.attribute.http://schemas.agov.ch/ws/2024/02/identity/claims/address/qa/verificationMethod" value="#{ (sess['agov.appAddressRequired'] == 'true') ? sess['agov.adressVerification'] : '' }"/>
|
||||
<property name="out.attribute.http://schemas.agov.ch/ws/2024/02/identity/claims/address/qa/verificationMethod" value="#{ (sess['agov.appAddressRequired'] == 'true') ? ''.concat(sess.get('agov.adressVerification')).replace('Location', 'Domicile') : '' }"/>
|
||||
<!-- source: pattern://27cefc3861bce987f6766342 -->
|
||||
<property name="out.attribute.http://schemas.agov.ch/ws/2024/02/identity/claims/address/countryName" value="#{ (sess['agov.appAddressRequired'] == 'true') ? sess['agov.countryName'] : ''}"/>
|
||||
<!-- source: pattern://27cefc3861bce987f6766342 -->
|
||||
|
@ -1562,6 +1568,8 @@
|
|||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="cancel, hasCaptchaInfos" next="Auth_Realm_Recovery_Recovery_handleCode"/>
|
||||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="cancel, hasCaptchaInfos, visible" next="Auth_Realm_Recovery_Recovery_handleCode"/>
|
||||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="default" next="Auth_Realm_Recovery_Recovery_fetchCaptchaInfos"/>
|
||||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="hasCaptchaInfos" next="Auth_Realm_Recovery_Recovery_Auth_loginFactorQuestion"/>
|
||||
|
@ -1572,6 +1580,8 @@
|
|||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="hasCaptchaInfos, invalidUrlTicket" next="Auth_Realm_Recovery_Recovery_Auth_enterEmail"/>
|
||||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="hasCaptchaInfos, invalidUrlTicket, visible" next="Auth_Realm_Recovery_Recovery_Auth_enterEmail"/>
|
||||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="hasCode" next="Auth_Realm_Recovery_Recovery_handleCode"/>
|
||||
<!-- source: pattern://584964c837512845d7940809 -->
|
||||
<ResultCond name="hasCode, hasCaptchaInfos" next="Auth_Realm_Recovery_Recovery_handleCode"/>
|
||||
|
|
|
@ -11,14 +11,6 @@ def maxLoiRoleToCtxClssConvertorMap = [
|
|||
"level500": "urn:qa.agov.ch:names:tc:ac:classes:500"
|
||||
]
|
||||
|
||||
def maxLoiRecoveryStepupMap = [
|
||||
"level100": "level200",
|
||||
"level200": "level300",
|
||||
"level300": "level300",
|
||||
"level400": "level400",
|
||||
"level500": "level500"
|
||||
]
|
||||
|
||||
def getUserIdVerificationForRecovery(currentLoaRole) {
|
||||
// application is AGOV-AccountStatus
|
||||
def list = new XmlSlurper().parseText(session.get('ch.adnovum.nevisidm.userDto'))
|
||||
|
@ -49,6 +41,32 @@ def getUserIdVerificationForRecovery(currentLoaRole) {
|
|||
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'))
|
||||
|
@ -98,18 +116,17 @@ if (session['ch.adnovum.nevisidm.userDto'] != null && notes['lasterror'] == null
|
|||
// attributes are defined over the mustRecover authorization
|
||||
session.setAttribute('agov.recovery.authnContextClassRef', 'urn:qa.agov.ch:names:tc:ac:classes:mustRecover')
|
||||
|
||||
def recoveryVerification = userDto.'**'.find { node -> node.name() == 'properties' && node.name.text() == 'idVerification' && node.scopeName.text() == 'AGOV-AccountStatus,mustRecover' }?.value?.text()
|
||||
idVerification = getUserIdVerificationForRecovery(maxLoi ?: 'level100') ?: idVerification
|
||||
|
||||
agovAqValidFrom = getUserMustRecoverValidFrom()
|
||||
|
||||
maxLoi = maxLoiRecoveryStepupMap[maxLoi ?: 'level100'] ?: 'level100'
|
||||
|
||||
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) {
|
||||
|
|
|
@ -46,7 +46,7 @@ spec:
|
|||
podDisruptionBudget:
|
||||
maxUnavailable: "50%"
|
||||
git:
|
||||
tag: "r-9af6a792e2720efb1d09318c1e3f4a2ab355af31"
|
||||
tag: "r-db9522d1110b41177e7d034419ef1fb68f95b0b8"
|
||||
dir: "DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/fido2"
|
||||
credentials: "git-credentials"
|
||||
keystores:
|
||||
|
|
|
@ -48,4 +48,4 @@ fido2:
|
|||
- ES256
|
||||
- ES384
|
||||
- ES512
|
||||
display-name-source: loginId
|
||||
display-name-source: email
|
|
@ -44,7 +44,7 @@ spec:
|
|||
podDisruptionBudget:
|
||||
maxUnavailable: "50%"
|
||||
git:
|
||||
tag: "r-9af6a792e2720efb1d09318c1e3f4a2ab355af31"
|
||||
tag: "r-db9522d1110b41177e7d034419ef1fb68f95b0b8"
|
||||
dir: "DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/logrend"
|
||||
credentials: "git-credentials"
|
||||
podSecurity:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
$text.get("footer.text")
|
||||
<a target="_blank" class='text-hyperlink dark:text-dark-hyperlink underline' href='$text.get("footer.link")'>$text.get("footer.link.label")</a>
|
||||
</div>
|
||||
<p>1.5.0.1980-20240604T133737Z</p>
|
||||
<p>1.5.3.51-20240709T140654Z</p>
|
||||
</footer>
|
||||
<script src="${login.appDataPath}/static/bundle.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
<input class="hidden" name="authRequestId" type="hidden" value="$gui.getGuiElem('authRequestId').value"/>
|
||||
</form>
|
||||
</div>
|
||||
<img alt="" src="${login.appDataPath}/static/js-code/images/recovery.svg"
|
||||
<img alt="" src="${login.appDataPath}/static/images/recovery.svg"
|
||||
class="md:max-w-[520px] max-w-[350px] sm:max-w-[300px] w-full md:basis-1/2 dark:hidden hidden md:block">
|
||||
<img alt="" src="${login.appDataPath}/static/images/recovery_dark.svg"
|
||||
class="md:max-w-[520px] max-w-[350px] sm:max-w-[300px] w-full md:basis-1/2 hidden dark:md:block">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
$text.get("footer.text")
|
||||
<a target="_blank" class='text-hyperlink dark:text-dark-hyperlink underline' href='$text.get("footer.link")'>$text.get("footer.link.label")</a>
|
||||
</div>
|
||||
<p>1.5.0.1980-20240604T133737Z</p>
|
||||
<p>1.5.3.51-20240709T140654Z</p>
|
||||
</footer>
|
||||
<script src="${login.appDataPath}/static/bundle.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
<input class="hidden" name="authRequestId" type="hidden" value="$gui.getGuiElem('authRequestId').value"/>
|
||||
</form>
|
||||
</div>
|
||||
<img alt="" src="${login.appDataPath}/static/js-code/images/recovery.svg"
|
||||
<img alt="" src="${login.appDataPath}/static/images/recovery.svg"
|
||||
class="md:max-w-[520px] max-w-[350px] sm:max-w-[300px] w-full md:basis-1/2 dark:hidden hidden md:block">
|
||||
<img alt="" src="${login.appDataPath}/static/images/recovery_dark.svg"
|
||||
class="md:max-w-[520px] max-w-[350px] sm:max-w-[300px] w-full md:basis-1/2 hidden dark:md:block">
|
||||
|
|
|
@ -46,7 +46,7 @@ spec:
|
|||
podDisruptionBudget:
|
||||
maxUnavailable: "50%"
|
||||
git:
|
||||
tag: "r-9af6a792e2720efb1d09318c1e3f4a2ab355af31"
|
||||
tag: "r-db9522d1110b41177e7d034419ef1fb68f95b0b8"
|
||||
dir: "DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp"
|
||||
credentials: "git-credentials"
|
||||
keystores:
|
||||
|
|
|
@ -62,8 +62,6 @@
|
|||
<p class="font-body text-body-l text-black dark:text-white mx-auto text-center">We are working on it. Please try again
|
||||
later.</p>
|
||||
</div>
|
||||
|
||||
<!-- TODO update here when italian is available -->
|
||||
</div>
|
||||
|
||||
<script src="/resources/static/bundle.js"></script>
|
||||
|
|
Loading…
Reference in New Issue