import ch.nevis.esauth.auth.engine.AuthResponse import ch.nevis.idm.client.IdmRestClient import ch.nevis.idm.client.IdmRestClientFactory import ch.nevis.idm.client.HTTPRequestWrapper import groovy.json.JsonSlurper // Accounting def requester = session['ch.nevis.auth.saml.request.scoping.requesterId'] ?: 'unknown' def requestId = session['ch.nevis.auth.saml.request.id'] ?: 'unknown' def requestedAq = session['agov.requestedRoleLevel'] ?: 'unknown' def user = session['ch.adnovum.nevisidm.user.extId'] ?: 'unknown' 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 loginId = session.get('ch.adnovum.nevisidm.user.loginId') String profileExtId = session.get('ch.adnovum.nevisidm.profileExtId') String unitExtid= parameters.get('unitExtid') String level100RoleExtid = parameters.get('level100.roleExtid') String baseUrl = "${parameters.get('idm.baseUrl')}/core/v1/$clientExtId" boolean audited = false String aq100AuthRestURL = null String endpoint = null // 1) create the profile if needed if (profileExtId == null || profileExtId.isEmpty()) { endpoint = "${baseUrl}/users/${userExtId}/profiles" profileExtId = UUID.randomUUID().toString() def postRequest = new HTTPRequestWrapper() postRequest.addToHeaders('Content-Type', ['application/json']) def dto = "{\"extId\":\"${profileExtId}\",\"unitExtId\":\"${unitExtid}\",\"profileState\":\"active\",\"name\":\"Profile-${loginId}\",\"isDefaultProfile\":true,\"modificationComment\":\"Repaired for request ${requestId}\"}" 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 profile (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 { 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 } aq100AuthRestURL = result.getLocation() } // 3) set the AQ level 100 verification to None if (!session['ch.adnovum.nevisidm.userDto'].contains("idVerificationNoneAGOV-Loi,level100")) { if (aq100AuthRestURL == 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) { aq100AuthRestURL = "${endpoint}/${az.extId}" } } } endpoint = "${aq100AuthRestURL}/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 (audited) { response.setResult('reload') } else { response.setResult('done') }