Skip to content

Commit

Permalink
Merge pull request #1036 from navikt/krr-integrasjon
Browse files Browse the repository at this point in the history
Krr integrasjon
  • Loading branch information
oyvind-wedoe authored Jan 19, 2024
2 parents d6346a7 + 89c4cd9 commit 7d3ef9e
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 13 deletions.
1 change: 1 addition & 0 deletions deploy/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ externalHosts:
- host: arbeid-og-inntekt-q1.dev-fss-pub.nais.io
- host: nom-api.intern.dev.nav.no
- host: pdl-api.dev-fss-pub.nais.io
- host: digdir-krr-proxy.intern.dev.nav.no
inboundApplications:
- application: kabal-frontend
- application: klage-dittnav-api
Expand Down
1 change: 1 addition & 0 deletions deploy/prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ externalHosts:
- host: arbeid-og-inntekt.prod-fss-pub.nais.io
- host: nom-api.intern.nav.no
- host: pdl-api.prod-fss-pub.nais.io
- host: digdir-krr-proxy.intern.nav.no
inboundApplications:
- application: kabal-frontend
- application: klage-dittnav-api
Expand Down
33 changes: 23 additions & 10 deletions src/main/kotlin/no/nav/klage/oppgave/api/mapper/BehandlingMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import no.nav.klage.oppgave.api.view.*
import no.nav.klage.oppgave.clients.egenansatt.EgenAnsattService
import no.nav.klage.oppgave.clients.ereg.EregClient
import no.nav.klage.oppgave.clients.ereg.Organisasjon
import no.nav.klage.oppgave.clients.krrproxy.DigitalKontaktinformasjon
import no.nav.klage.oppgave.clients.krrproxy.KrrProxyClient
import no.nav.klage.oppgave.clients.norg2.Norg2Client
import no.nav.klage.oppgave.clients.pdl.PdlFacade
import no.nav.klage.oppgave.clients.pdl.Person
Expand All @@ -22,6 +24,7 @@ class BehandlingMapper(
private val norg2Client: Norg2Client,
private val eregClient: EregClient,
private val saksbehandlerRepository: SaksbehandlerRepository,
private val krrProxyClient: KrrProxyClient,
) {

companion object {
Expand Down Expand Up @@ -229,14 +232,16 @@ class BehandlingMapper(
fun getSakenGjelderView(sakenGjelder: SakenGjelder): BehandlingDetaljerView.SakenGjelderView {
if (sakenGjelder.erPerson()) {
val person = pdlFacade.getPersonInfo(sakenGjelder.partId.value)
val krrInfo = krrProxyClient.getDigitalKontaktinformasjonForFnr(sakenGjelder.partId.value)
return BehandlingDetaljerView.SakenGjelderView(
id = person.foedselsnr,
name = person.settSammenNavn(),
sex = person.kjoenn?.let { BehandlingDetaljerView.Sex.valueOf(it) }
?: BehandlingDetaljerView.Sex.UKJENT,
type = BehandlingDetaljerView.IdType.FNR,
available = person.doed == null,
statusList = getStatusList(person),
language = krrInfo?.spraak,
statusList = getStatusList(person, krrInfo),
)
} else {
throw RuntimeException("We don't support where sakenGjelder is virksomhet")
Expand All @@ -260,12 +265,14 @@ class BehandlingMapper(
private fun getPartView(identificator: String, isPerson: Boolean): BehandlingDetaljerView.PartView {
return if (isPerson) {
val person = pdlFacade.getPersonInfo(identificator)
val krrInfo = krrProxyClient.getDigitalKontaktinformasjonForFnr(identificator)
BehandlingDetaljerView.PartView(
id = person.foedselsnr,
name = person.settSammenNavn(),
type = BehandlingDetaljerView.IdType.FNR,
available = person.doed == null,
statusList = getStatusList(person),
language = krrInfo?.spraak,
statusList = getStatusList(person, krrInfo),
)
} else {
val organisasjon = eregClient.hentOrganisasjon(identificator)
Expand All @@ -274,6 +281,7 @@ class BehandlingMapper(
name = organisasjon.navn.sammensattnavn,
type = BehandlingDetaljerView.IdType.ORGNR,
available = organisasjon.isActive(),
language = null,
statusList = getStatusList(organisasjon),
)
}
Expand Down Expand Up @@ -389,40 +397,45 @@ class BehandlingMapper(
}
}

fun getStatusList(person: Person): List<BehandlingDetaljerView.PartStatus> {
fun getStatusList(pdlPerson: Person, krrInfo: DigitalKontaktinformasjon?): List<BehandlingDetaljerView.PartStatus> {
val statusList = mutableListOf<BehandlingDetaljerView.PartStatus>()

if (person.doed != null) {
if (pdlPerson.doed != null) {
statusList += BehandlingDetaljerView.PartStatus(
status = BehandlingDetaljerView.PartStatus.Status.DEAD,
date = person.doed,
date = pdlPerson.doed,
)
}
if (person.fullmakt) {
if (pdlPerson.fullmakt) {
statusList += BehandlingDetaljerView.PartStatus(
status = BehandlingDetaljerView.PartStatus.Status.FULLMAKT,
)
}
if (person.vergemaalEllerFremtidsfullmakt) {
if (pdlPerson.vergemaalEllerFremtidsfullmakt) {
statusList += BehandlingDetaljerView.PartStatus(
status = BehandlingDetaljerView.PartStatus.Status.VERGEMAAL,
)
}
if (person.harBeskyttelsesbehovFortrolig()) {
if (pdlPerson.harBeskyttelsesbehovFortrolig()) {
statusList += BehandlingDetaljerView.PartStatus(
status = BehandlingDetaljerView.PartStatus.Status.FORTROLIG,
)
}
if (person.harBeskyttelsesbehovStrengtFortrolig()) {
if (pdlPerson.harBeskyttelsesbehovStrengtFortrolig()) {
statusList += BehandlingDetaljerView.PartStatus(
status = BehandlingDetaljerView.PartStatus.Status.STRENGT_FORTROLIG,
)
}
if (egenAnsattService.erEgenAnsatt(person.foedselsnr)) {
if (egenAnsattService.erEgenAnsatt(pdlPerson.foedselsnr)) {
statusList += BehandlingDetaljerView.PartStatus(
status = BehandlingDetaljerView.PartStatus.Status.EGEN_ANSATT,
)
}
if (krrInfo?.reservert == true) {
statusList += BehandlingDetaljerView.PartStatus(
status = BehandlingDetaljerView.PartStatus.Status.RESERVERT_I_KRR,
)
}

return statusList
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ data class BehandlingDetaljerView(
val id: String
val name: String?
val available: Boolean
val language: String?
val statusList: List<PartStatus>
}

Expand All @@ -86,6 +87,7 @@ data class BehandlingDetaljerView(
EGEN_ANSATT,
VERGEMAAL,
FULLMAKT,
RESERVERT_I_KRR,
}
}

Expand All @@ -106,6 +108,7 @@ data class BehandlingDetaljerView(
override val name: String?,
override val type: IdType,
override val available: Boolean,
override val language: String?,
override val statusList: List<PartStatus>,
): PartBase, IdPart

Expand All @@ -114,6 +117,7 @@ data class BehandlingDetaljerView(
override val name: String?,
override val type: IdType,
override val available: Boolean,
override val language: String?,
override val statusList: List<PartStatus>,
val sex: Sex,
): PartBase, IdPart
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package no.nav.klage.oppgave.clients.krrproxy

import brave.Tracer
import no.nav.klage.oppgave.config.CacheWithJCacheConfiguration
import no.nav.klage.oppgave.util.TokenUtil
import no.nav.klage.oppgave.util.getLogger
import no.nav.klage.oppgave.util.getSecureLogger
import no.nav.klage.oppgave.util.logErrorResponse
import org.springframework.cache.annotation.Cacheable
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatusCode
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.reactive.function.client.WebClientResponseException
import org.springframework.web.reactive.function.client.bodyToMono
import reactor.core.publisher.Mono

@Component
class KrrProxyClient(
private val krrProxyWebClient: WebClient,
private val tokenUtil: TokenUtil,
private val tracer: Tracer
) {
companion object {
@Suppress("JAVA_CLASS_ON_COMPANION")
private val logger = getLogger(javaClass.enclosingClass)
private val secureLogger = getSecureLogger()
}

@Cacheable(CacheWithJCacheConfiguration.KRR_INFO_CACHE)
fun getDigitalKontaktinformasjonForFnr(fnr: String): DigitalKontaktinformasjon? {
logger.debug("Getting info from KRR")
return krrProxyWebClient.get()
.uri("/rest/v1/person")
.header("Nav-Call-Id", tracer.currentSpan().context().traceIdString())
.header(
HttpHeaders.AUTHORIZATION,
"Bearer ${tokenUtil.getOnBehalfOfTokenWithKrrProxyScope()}"
)
.header(
"Nav-Personident",
fnr
)
.retrieve()
.onStatus(HttpStatusCode::isError) { response ->
logErrorResponse(response, ::getDigitalKontaktinformasjonForFnr.name, secureLogger)
}
.bodyToMono<DigitalKontaktinformasjon>()
.onErrorResume { Mono.empty() }
.block()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package no.nav.klage.oppgave.clients.krrproxy

import java.time.LocalDate
import java.time.ZonedDateTime


data class DigitalKontaktinformasjon (
val personident: String? = null,
val aktiv: Boolean? = null,
val kanVarsles: Boolean? = null,
val reservasjonOppdatert: ZonedDateTime? = null,
val reservert: Boolean? = null,
val spraak: String? = null,
val spraakOppdatert: ZonedDateTime? = null,
val epostadresse: String? = null,
val epostadresseOppdatert: ZonedDateTime? = null,
val epostadresseVerifisert: ZonedDateTime? = null,
val mobiltelefonnummer: String? = null,
val mobiltelefonnummerOppdatert: ZonedDateTime? = null,
val mobiltelefonnummerVerifisert: ZonedDateTime? = null,
val sikkerDigitalPostkasse: SikkerDigitalPostkasse? = null,
)

data class SikkerDigitalPostkasse (
val adresse: String? = null,
val leverandoerAdresse: String? = null,
val leverandoerSertifikat: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ class CacheWithJCacheConfiguration(private val environment: Environment) : JCach
const val SAKSBEHANDLERE_I_ENHET_CACHE = "saksbehandlereienhet"
const val ANSATTE_I_ENHET_CACHE = "ansatteienhet"
const val GROUPMEMBERS_CACHE = "groupmembers"
const val KRR_INFO_CACHE = "krrinfo"

val cacheKeys =
listOf(ENHET_CACHE, TILGANGER_CACHE, ROLLER_CACHE, SAKSBEHANDLERE_I_ENHET_CACHE, GROUPMEMBERS_CACHE)
listOf(ENHET_CACHE, TILGANGER_CACHE, ROLLER_CACHE, SAKSBEHANDLERE_I_ENHET_CACHE, GROUPMEMBERS_CACHE, KRR_INFO_CACHE)

@Suppress("JAVA_CLASS_ON_COMPANION")
private val logger = getLogger(javaClass.enclosingClass)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package no.nav.klage.oppgave.config


import no.nav.klage.oppgave.util.getLogger
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.client.reactive.ReactorClientHttpConnector
import org.springframework.web.reactive.function.client.WebClient
import reactor.netty.http.client.HttpClient


@Configuration
class KrrProxyClientConfiguration(
private val webClientBuilder: WebClient.Builder
) {

companion object {
@Suppress("JAVA_CLASS_ON_COMPANION")
private val logger = getLogger(javaClass.enclosingClass)
}

@Value("\${KRR_PROXY_REST_URL}")
private lateinit var krrProxyURL: String

@Bean
fun krrProxyWebClient(): WebClient {
return webClientBuilder
.baseUrl(krrProxyURL)
.clientConnector(ReactorClientHttpConnector(HttpClient.newConnection()))
.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import no.nav.klage.kodeverk.PartIdType
import no.nav.klage.oppgave.api.mapper.BehandlingMapper
import no.nav.klage.oppgave.api.view.BehandlingDetaljerView
import no.nav.klage.oppgave.clients.ereg.EregClient
import no.nav.klage.oppgave.clients.krrproxy.KrrProxyClient
import no.nav.klage.oppgave.clients.pdl.PdlFacade
import no.nav.klage.oppgave.exceptions.MissingTilgangException
import no.nav.klage.oppgave.util.getLogger
Expand All @@ -17,6 +18,7 @@ class PartSearchService(
private val pdlFacade: PdlFacade,
private val tilgangService: TilgangService,
private val behandlingMapper: BehandlingMapper,
private val krrProxyClient: KrrProxyClient,
) {

companion object {
Expand All @@ -30,12 +32,14 @@ class PartSearchService(
PartIdType.PERSON -> {
if (skipAccessControl || tilgangService.harInnloggetSaksbehandlerTilgangTil(identifikator)) {
val person = pdlFacade.getPersonInfo(identifikator)
val krrInfo = krrProxyClient.getDigitalKontaktinformasjonForFnr(identifikator)
BehandlingDetaljerView.PartView(
id = person.foedselsnr,
name = person.settSammenNavn(),
type = BehandlingDetaljerView.IdType.FNR,
available = person.doed == null,
statusList = behandlingMapper.getStatusList(person)
language = krrInfo?.spraak,
statusList = behandlingMapper.getStatusList(person, krrInfo)
)
} else {
secureLogger.warn("Saksbehandler does not have access to view person")
Expand All @@ -50,6 +54,7 @@ class PartSearchService(
name = organisasjon.navn.sammensattnavn,
type = BehandlingDetaljerView.IdType.ORGNR,
available = organisasjon.isActive(),
language = null,
statusList = behandlingMapper.getStatusList(organisasjon),
)
}
Expand All @@ -63,14 +68,16 @@ class PartSearchService(
PartIdType.PERSON -> {
if (skipAccessControl || tilgangService.harInnloggetSaksbehandlerTilgangTil(identifikator)) {
val person = pdlFacade.getPersonInfo(identifikator)
val krrInfo = krrProxyClient.getDigitalKontaktinformasjonForFnr(identifikator)
BehandlingDetaljerView.SakenGjelderView(
id = person.foedselsnr,
name = person.settSammenNavn(),
type = BehandlingDetaljerView.IdType.FNR,
available = person.doed == null,
sex = person.kjoenn?.let { BehandlingDetaljerView.Sex.valueOf(it) }
?: BehandlingDetaljerView.Sex.UKJENT,
statusList = behandlingMapper.getStatusList(person),
language = krrInfo?.spraak,
statusList = behandlingMapper.getStatusList(person, krrInfo),
)
} else {
secureLogger.warn("Saksbehandler does not have access to view person")
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/no/nav/klage/oppgave/util/TokenUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ class TokenUtil(
return response.accessToken
}

fun getOnBehalfOfTokenWithKrrProxyScope(): String {
val clientProperties = clientConfigurationProperties.registration["krr-proxy-onbehalfof"]
val response = oAuth2AccessTokenService.getAccessToken(clientProperties)
return response.accessToken
}

fun getOnBehalfOfTokenWithKlageFSSProxyScope(): String {
val clientProperties = clientConfigurationProperties.registration["klage-fss-proxy-onbehalfof"]
val response = oAuth2AccessTokenService.getAccessToken(clientProperties)
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application-dev-gcp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ DVH_STATISTIKK_TOPIC: klage.kabal-statistikk.v1
BEHANDLING_ENDRET_TOPIC_V2: klage.behandling-endret.v2
BEHANDLING_EVENTS_TOPIC: klage.behandling-events.v1

KRR_PROXY_REST_URL: https://digdir-krr-proxy.intern.dev.nav.no/
KRR_PROXY_SCOPE: dev-gcp.team-rocket.digdir-krr-proxy

AIVEN_ES_HOST: elastic-klage-oppgave-es-nav-dev.aivencloud.com
AIVEN_ES_PORT: 26482
AIVEN_ES_SCHEME: https
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application-prod-gcp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ DVH_STATISTIKK_TOPIC: klage.kabal-statistikk.v1
BEHANDLING_ENDRET_TOPIC_V2: klage.behandling-endret.v2
BEHANDLING_EVENTS_TOPIC: klage.behandling-events.v1

KRR_PROXY_REST_URL: https://digdir-krr-proxy.intern.nav.no/
KRR_PROXY_SCOPE: prod-gcp.team-rocket.digdir-krr-proxy

AIVEN_ES_HOST: elastic-klage-oppgave-es-nav-prod.aivencloud.com
AIVEN_ES_PORT: 26482
AIVEN_ES_SCHEME: https
Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,14 @@ no.nav.security.jwt:
client-id: ${AZURE_APP_CLIENT_ID}
client-jwk: ${AZURE_APP_JWK}
client-auth-method: private_key_jwt
krr-proxy-onbehalfof:
token-endpoint-url: https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token
grant-type: urn:ietf:params:oauth:grant-type:jwt-bearer
scope: api://${KRR_PROXY_SCOPE}/.default
authentication:
client-id: ${AZURE_APP_CLIENT_ID}
client-jwk: ${AZURE_APP_JWK}
client-auth-method: private_key_jwt
klage-fss-proxy-onbehalfof:
token-endpoint-url: https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token
grant-type: urn:ietf:params:oauth:grant-type:jwt-bearer
Expand Down
Loading

0 comments on commit 7d3ef9e

Please sign in to comment.