Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bruk tokenX mot k9-sak #273

Merged
merged 1 commit into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker-compose-env/vtp.env
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ KAFKA_CREDSTORE_PASSWORD=changeit
KAFKA_OVERRIDE_KEYSTORE_PASSWORD=devillokeystore1234

NO_NAV_GATEWAYS_K9_SAK=http://k9-sak:8080/k9/sak
K9_SAK_AZURE_AUDIENCE=api://vtp/.default
K9_SAK_TOKENX_AUDIENCE=dev-fss:k9saksbehandling:k9-sak
SWAGGER_ENABLED=true

LOGGING_LEVEL_NO_NAV_SECURITY=DEBUG
2 changes: 1 addition & 1 deletion nais/dev-gcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"K9_SELVBETJENING_OPPSLAG_AZURE_AUDIENCE": "api://dev-gcp.dusseldorf.k9-selvbetjening-oppslag/.default",

"NO_NAV_GATEWAYS_K9_SAK": "https://k9-sak.dev-fss-pub.nais.io/k9/sak",
"K9_SAK_AZURE_AUDIENCE": "api://dev-fss.k9saksbehandling.k9-sak/.default",
"K9_SAK_TOKENX_AUDIENCE": "dev-fss:k9saksbehandling:k9-sak",

"NO_NAV_GATEWAYS_SAF_SELVBETJENING_BASE_URL": "https://safselvbetjening-q1.dev-fss-pub.nais.io",
"SAFSELVBETJENING_TOKEN_X_AUDIENCE": "dev-fss:teamdokumenthandtering:safselvbetjening-q1",
Expand Down
2 changes: 1 addition & 1 deletion nais/prod-gcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"SAFSELVBETJENING_TOKEN_X_AUDIENCE": "prod-fss:teamdokumenthandtering:safselvbetjening",

"NO_NAV_GATEWAYS_K9_SAK": "https://k9-sak.prod-fss-pub.nais.io/k9/sak",
"K9_SAK_AZURE_AUDIENCE": "api://prod-fss.k9saksbehandling.k9-sak/.default",
"K9_SAK_TOKENX_AUDIENCE": "prod-fss:k9saksbehandling:k9-sak",

"NO_NAV_GATEWAYS_SIF_INNSYN_API_BASE_URL": "http://sif-innsyn-api",
"SIF_INNSYN_API_TOKEN_X_AUDIENCE": "prod-gcp:dusseldorf:sif-innsyn-api",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import no.nav.sifinnsynapi.Routes
import no.nav.sifinnsynapi.common.AktørId
import no.nav.sifinnsynapi.common.IkkeAktivertIProduksjon
import no.nav.sifinnsynapi.config.Issuers
import no.nav.sifinnsynapi.oppslag.OppslagsService
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.PostMapping
Expand All @@ -22,15 +21,11 @@ import org.springframework.web.bind.annotation.RestController
)
class K9SakController(
private val k9SakService: K9SakService,
private val oppslagsService: OppslagsService
) {
@PostMapping(Routes.K9SAK_OMSORGSDAGER_KRONISK_SYKT_BARN_GYLDIG_VEDTAK, produces = [MediaType.APPLICATION_JSON_VALUE])
@ResponseStatus(HttpStatus.OK)
fun hentSisteGyldigeVedtakForAktorId(@RequestBody requestDto: OmsorgsdagerKronsinskSuktBarnRequestDto ): HentSisteGyldigeVedtakForAktorIdResponse? {
val aktørId = oppslagsService.hentSøker()?.aktørId?: throw IllegalStateException("Fant ikke aktørId for innlogget bruker")

return k9SakService.hentSisteGyldigeVedtakForAktorId(HentSisteGyldigeVedtakForAktorIdDto(
aktørId = AktørId(aktørId),
pleietrengendeAktørId = requestDto.pleietrengendeAktørId
))
}
Expand Down
11 changes: 5 additions & 6 deletions src/main/kotlin/no/nav/sifinnsynapi/k9sak/K9SakKlientKonfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ class K9SakKlientKonfig(
private companion object {
val logger: Logger = LoggerFactory.getLogger(K9SakKlientKonfig::class.java)

const val AZURE_K9_SAK = "azure-k9-sak"
const val TOKENX_K9_SAK = "tokenx-k9-sak"
}

private val azureK9SakClientProperties =
oauth2Config.registration[AZURE_K9_SAK]
?: throw RuntimeException("could not find oauth2 client config for $AZURE_K9_SAK")
private val tokenXK9SakClientProperties =
oauth2Config.registration[TOKENX_K9_SAK]
?: throw RuntimeException("could not find oauth2 client config for $TOKENX_K9_SAK")

@Bean(name = ["k9SakKlient"])
fun restTemplate(
Expand All @@ -54,9 +54,8 @@ class K9SakKlientKonfig(
when {
request.uri.path == "/isalive" -> {} // ignorer


else -> {
oAuth2AccessTokenService.getAccessToken(azureK9SakClientProperties).accessToken?.let {
oAuth2AccessTokenService.getAccessToken(tokenXK9SakClientProperties).accessToken?.let {
request.headers.setBearerAuth(it)
}?: throw SecurityException("Access token er null")
}
Expand Down
4 changes: 0 additions & 4 deletions src/main/kotlin/no/nav/sifinnsynapi/k9sak/K9SakService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import no.nav.sifinnsynapi.common.AktørId
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.actuate.health.Health
import org.springframework.boot.actuate.health.ReactiveHealthIndicator
import org.springframework.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
Expand All @@ -21,7 +19,6 @@ import org.springframework.web.client.HttpClientErrorException
import org.springframework.web.client.HttpServerErrorException
import org.springframework.web.client.ResourceAccessException
import org.springframework.web.client.RestTemplate
import reactor.core.publisher.Mono
import java.net.URI
import java.time.LocalDate

Expand Down Expand Up @@ -91,7 +88,6 @@ class K9SakService(
}

data class HentSisteGyldigeVedtakForAktorIdDto(
val aktørId: AktørId,
val pleietrengendeAktørId: AktørId
)

Expand Down
13 changes: 7 additions & 6 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ no.nav:
token-exchange:
audience: ${SIF_INNSYN_API_TOKEN_X_AUDIENCE}

azure-k9-sak:
token-endpoint-url: ${AZURE_OPENID_CONFIG_TOKEN_ENDPOINT}
grant-type: client_credentials
scope: ${K9_SAK_AZURE_AUDIENCE}
tokenx-k9-sak:
token-endpoint-url: ${TOKEN_X_TOKEN_ENDPOINT}
grant-type: urn:ietf:params:oauth:grant-type:token-exchange
authentication:
client-auth-method: private_key_jwt
client-id: ${AZURE_APP_CLIENT_ID}
client-jwk: ${AZURE_APP_JWK}
client-id: ${TOKEN_X_CLIENT_ID}
client-jwk: ${TOKEN_X_PRIVATE_JWK}
token-exchange:
audience: ${K9_SAK_TOKENX_AUDIENCE}

topic:
# Bryter betegner av/på funksjon for kafkalytter. True (på), False (av).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import no.nav.k9.sak.typer.Saksnummer
import no.nav.security.mock.oauth2.MockOAuth2Server
import no.nav.security.token.support.spring.test.EnableMockOAuth2Server
import no.nav.sifinnsynapi.config.SecurityConfiguration
import no.nav.sifinnsynapi.oppslag.OppslagsService
import no.nav.sifinnsynapi.oppslag.SøkerOppslagRespons
import no.nav.sifinnsynapi.util.CallIdGenerator
import no.nav.sifinnsynapi.utils.hentToken
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -40,17 +38,13 @@ class K9SakControllerTest {
@MockkBean
lateinit var k9SakService: K9SakService

@MockkBean
lateinit var oppslagsService: OppslagsService

@Test
fun `fungerer fint`() {
every { k9SakService.hentSisteGyldigeVedtakForAktorId(any()) } returns HentSisteGyldigeVedtakForAktorIdResponse(
harInnvilgedeBehandlinger = true,
saksnummer = Saksnummer("123456"),
vedtaksdato = LocalDate.now()
)
every { oppslagsService.hentSøker() } returns SøkerOppslagRespons(aktørId = "123456")

mockMvc.post("/k9sak/omsorgsdager-kronisk-sykt-barn/har-gyldig-vedtak") {
contentType = MediaType.APPLICATION_JSON
Expand Down Expand Up @@ -89,42 +83,10 @@ class K9SakControllerTest {
}.andExpect { status { isUnauthorized() } }
}

@Test
fun `forventer å feile dersom aktørId mangler`() {
every { oppslagsService.hentSøker() } throws IllegalStateException("Fant ikke aktørId for innlogget bruker")

mockMvc.post("/k9sak/omsorgsdager-kronisk-sykt-barn/har-gyldig-vedtak") {
contentType = MediaType.APPLICATION_JSON
headers { setBearerAuth(mockOAuth2Server.hentToken("123456789").serialize()) }
content = """
{
"pleietrengendeAktørId": "123456"
}
""".trimIndent()
}.andExpect {
status { isInternalServerError() }
content {
json(
"""
{
"type": "/problem-details/internal-server-error",
"title": "Et uventet feil har oppstått",
"status": 500,
"detail": "Fant ikke aktørId for innlogget bruker",
"instance": "http://localhost/k9sak/omsorgsdager-kronisk-sykt-barn/har-gyldig-vedtak"
}
""".trimIndent()
)
}
}
}

@Test
fun `forventer feil når kall mot k9 feiler`() {
every { k9SakService.hentSisteGyldigeVedtakForAktorId(any()) } throws K9SakException("Ugyldig pleietrengendeAktørId", HttpStatus.BAD_REQUEST)

every { oppslagsService.hentSøker() } returns SøkerOppslagRespons(aktørId = "123456")

mockMvc.post("/k9sak/omsorgsdager-kronisk-sykt-barn/har-gyldig-vedtak") {
contentType = MediaType.APPLICATION_JSON
headers { setBearerAuth(mockOAuth2Server.hentToken("123456789").serialize()) }
Expand Down
39 changes: 25 additions & 14 deletions src/test/kotlin/no/nav/sifinnsynapi/k9sak/K9SakServiceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@ package no.nav.sifinnsynapi.k9sak
import com.github.tomakehurst.wiremock.client.WireMock
import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor
import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo
import com.ninjasquad.springmockk.MockkBean
import io.mockk.every
import no.nav.k9.sak.typer.Saksnummer
import no.nav.security.mock.oauth2.MockOAuth2Server
import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenResponse
import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenService
import no.nav.security.token.support.spring.test.EnableMockOAuth2Server
import no.nav.sifinnsynapi.common.AktørId
import no.nav.sifinnsynapi.utils.hentToken
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -27,18 +34,30 @@ internal class K9SakServiceTest {
@Autowired
lateinit var k9SakService: K9SakService

@Autowired
lateinit var mockOAuth2Server: MockOAuth2Server

@MockkBean
lateinit var oAuth2AccessTokenService: OAuth2AccessTokenService


private companion object {
private val omsorgsdagerKroniskSyktBarnHarGyldigVedtakUrl =
"/k9-sak-mock/k9/sak/api/brukerdialog/omsorgsdager-kronisk-sykt-barn/har-gyldig-vedtak"
}

@BeforeEach
fun setUp() {
var token = mockOAuth2Server.hentToken("123456789", audience = "dev-fss:k9saksbehandling:k9-sak").serialize()
every { oAuth2AccessTokenService.getAccessToken(any()) } returns OAuth2AccessTokenResponse(token)
}

@Test
fun `k9-sak svarer som forventet`() {
val aktør = AktørId("1234")
val pleietrengendeAktør = AktørId("2345")

stubK9Sak(
aktør, pleietrengendeAktør, 200,
pleietrengendeAktør, 200,
// language=JSON
"""
{
Expand All @@ -51,19 +70,17 @@ internal class K9SakServiceTest {

k9SakService.hentSisteGyldigeVedtakForAktorId(
HentSisteGyldigeVedtakForAktorIdDto(
aktør,
pleietrengendeAktør
)
)
}

@Test
fun `k9-sak svarer med ingen behandling funnet`() {
val aktør = AktørId("1234")
val pleietrengendeAktør = AktørId("2345")

stubK9Sak(
aktør, pleietrengendeAktør, 200,
pleietrengendeAktør, 200,
// language=JSON
"""
{
Expand All @@ -76,19 +93,17 @@ internal class K9SakServiceTest {

k9SakService.hentSisteGyldigeVedtakForAktorId(
HentSisteGyldigeVedtakForAktorIdDto(
aktør,
pleietrengendeAktør
)
)
}

@Test
fun `server exceptions blir håndtert`() {
val aktør = AktørId("1234")
val pleietrengendeAktør = AktørId("2345")

stubK9Sak(
aktør, pleietrengendeAktør, 500,
pleietrengendeAktør, 500,
// language=JSON
"""
{
Expand All @@ -102,7 +117,6 @@ internal class K9SakServiceTest {
assertThrows<K9SakException> {
k9SakService.hentSisteGyldigeVedtakForAktorId(
HentSisteGyldigeVedtakForAktorIdDto(
aktør,
pleietrengendeAktør
)
)
Expand All @@ -116,11 +130,10 @@ internal class K9SakServiceTest {

@Test
fun `klient exceptions blir håndtert`() {
val aktør = AktørId("1234")
val pleietrengendeAktør = AktørId("2345")

stubK9Sak(
aktør, pleietrengendeAktør, 401,
pleietrengendeAktør, 401,
// language=JSON
"""
{
Expand All @@ -134,7 +147,6 @@ internal class K9SakServiceTest {
assertThrows<K9SakException> {
k9SakService.hentSisteGyldigeVedtakForAktorId(
HentSisteGyldigeVedtakForAktorIdDto(
aktør,
pleietrengendeAktør
)
)
Expand All @@ -147,7 +159,7 @@ internal class K9SakServiceTest {
}


private fun stubK9Sak(aktørId: AktørId, pleietrengendeAktørId: AktørId, status: Int, responseBody: String) {
private fun stubK9Sak(pleietrengendeAktørId: AktørId, status: Int, responseBody: String) {
WireMock.stubFor(
WireMock.post(WireMock.urlPathMatching(omsorgsdagerKroniskSyktBarnHarGyldigVedtakUrl))
.withHeader("Authorization", WireMock.matching(".*"))
Expand All @@ -156,7 +168,6 @@ internal class K9SakServiceTest {
//language=json
"""
{
"aktørId": "${aktørId.aktørId}",
"pleietrengendeAktørId": "${pleietrengendeAktørId.aktørId}"
}
""".trimIndent()
Expand Down
22 changes: 12 additions & 10 deletions src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,12 @@ no.nav:
client-id: dev-gcp:dusseldorf:k9-sak-innsyn-api
client-jwk: src/test/resources/private_jwk.json

azure-k9-sak:
token-endpoint-url: http://localhost:${mock-oauth2-server.port}/oauth2/v2.0/token
grant-type: client_credentials
scope: api://dev-fss:k9saksbehandling:k9-sak
authentication:
client-auth-method: private_key_jwt
client-id: dev-gcp:dusseldorf:k9-sak-innsyn-api
client-jwk: src/test/resources/private_jwk.json

tokenx-safselvbetjening:
token-endpoint-url: http://localhost:${mock-oauth2-server.port}/default/token
grant-type: urn:ietf:params:oauth:grant-type:token-exchange
authentication:
client-auth-method: private_key_jwt
client-id: "dev-gcp:dusseldorf:sif-innsyn-api"
client-id: "dev-gcp:dusseldorf:k9-sak-innsyn-api"
client-jwk: src/test/resources/tokenx-jwk.json
token-exchange:
audience: dev-fss:teamdokumenthandtering:safselvbetjening
Expand All @@ -62,6 +53,17 @@ no.nav:
client-jwk: src/test/resources/tokenx-jwk.json
token-exchange:
audience: dev-gcp:dusseldorf:sif-innsyn-api

tokenx-k9-sak:
token-endpoint-url: http://localhost:${mock-oauth2-server.port}/default/token
grant-type: urn:ietf:params:oauth:grant-type:token-exchange
authentication:
client-auth-method: private_key_jwt
client-id: "dev-gcp:dusseldorf:k9-sak-innsyn-api"
client-jwk: src/test/resources/tokenx-jwk.json
token-exchange:
audience: dev-fss:k9saksbehandling:k9-sak

metrics:
interval: 36000

Expand Down
Loading