Skip to content

Commit c43460c

Browse files
committed
La til issuer info i sikkerhetsnivå
1 parent afb260c commit c43460c

File tree

12 files changed

+50
-30
lines changed

12 files changed

+50
-30
lines changed

apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/RequestScope.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.ktor.server.auth.principal
44
import io.ktor.server.request.path
55
import io.ktor.server.routing.RoutingContext
66
import io.opentelemetry.instrumentation.annotations.WithSpan
7+
import no.nav.paw.arbeidssokerregisteret.utils.AzureACR
78
import no.nav.paw.arbeidssokerregisteret.utils.AzureAzpName
89
import no.nav.paw.arbeidssokerregisteret.utils.AzureName
910
import no.nav.paw.arbeidssokerregisteret.utils.AzureNavIdent
@@ -21,7 +22,9 @@ data class RequestScope(
2122
val callId: String?,
2223
val traceparent: String?,
2324
val navConsumerId: String?
24-
)
25+
) {
26+
val issuer: String = claims.issuer
27+
}
2528

2629
@WithSpan
2730
fun RoutingContext.requestScope(): RequestScope {
@@ -34,6 +37,7 @@ fun RoutingContext.requestScope(): RequestScope {
3437
AzureNavIdent,
3538
AzureRoles,
3639
AzureAzpName,
40+
AzureACR,
3741
TokenXPID,
3842
TokenXACR
3943
) ?: ResolvedClaims()

apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/ResultatTilHendelse.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.BrukerType
2424
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.Metadata
2525
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.OpplysningerOmArbeidssoeker
2626
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.TidspunktFraKilde
27+
import no.nav.paw.arbeidssokerregisteret.utils.AzureACR
2728
import no.nav.paw.collections.PawNonEmptyList
2829
import java.time.Instant
2930
import java.util.*
@@ -150,13 +151,13 @@ fun RequestScope.brukerFraClaims(): Bruker {
150151
Bruker(
151152
type = BrukerType.VEILEDER,
152153
id = it.ident,
153-
sikkerhetsnivaa = null
154+
sikkerhetsnivaa = "${claims.issuer}:${claims[AzureACR] ?: "undefined"}"
154155
)
155156
} ?: m2mToken(claims)?.let {
156157
Bruker(
157158
type = BrukerType.SYSTEM,
158159
id = it.tjeneste,
159-
sikkerhetsnivaa = null
160+
sikkerhetsnivaa = "${claims.issuer}:${claims[AzureACR] ?: "undefined"}"
160161
)
161162
} ?: throw IllegalStateException("Kunne ikke finne bruker i claims")
162163
}

apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/domain/Sluttbruker.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ data class Sluttbruker(
1111

1212
fun sluttbruker(claims: ResolvedClaims): Sluttbruker? {
1313
val identitetsnummer = claims[TokenXPID]
14-
val sikkerhetsnivaa = claims[TokenXACR]
14+
val sikkerhetsnivaa = "${claims.issuer}:${claims[TokenXACR] ?: "undefined"}"
1515
return identitetsnummer?.let { Sluttbruker(it, sikkerhetsnivaa) }
1616
}

apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/utils/Claim.kt

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ data object AzureNavIdent : SingeClaim<String>("azure", "NAVident", Any::toStrin
2626
data object AzureOID : SingeClaim<UUID>("azure", "oid", Any::asUUID)
2727
data object AzureRoles : ListClaim<String>("azure", "roles", Any::asListOfStrings)
2828
data object AzureAzpName : SingeClaim<String>("azure", "azp_name", Any::toString)
29+
data object AzureACR : SingeClaim<String>("azure", "acr", Any::toString)
2930
data object TokenXPID : SingeClaim<Identitetsnummer>("tokenx", "pid", Any::asIdentitetsnummer)
3031
data object TokenXACR : SingeClaim<String>("tokenx", "acr", Any::toString)
3132

apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/utils/ResolvedClaims.kt

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ class ResolvedClaims private constructor(
77
) {
88
constructor() : this(emptyMap())
99

10+
val issuer: String = map.keys.firstOrNull()?.issuer ?: "undefined"
11+
1012
override fun toString(): String {
1113
return map.map { (key, value) -> "${key}=$value" }
1214
.let { "ResolvedClaims($it)" }

apps/api-start-stopp-perioder/src/test/kotlin/no/nav/paw/arbeidssokerregisteret/ApiV2TestCaseRunner.kt

+5-4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class ApiV2TestCaseRunner : FreeSpec({
6262
"Test API V2 ${testCase::class.simpleName?.readable()}" - {
6363
"Verifiser API V2" - {
6464
with(initTestCaseContext(InngangsReglerV2)) {
65+
val testConfiguration = TestCaseBuilder(mockOAuthServer, autorisasjonService)
66+
.also { testCase.configure(it) }
6567
"Verifiser API response" {
6668
testApplication {
6769
application {
@@ -79,13 +81,11 @@ class ApiV2TestCaseRunner : FreeSpec({
7981
val person = (testCase as? StartPeriodeTestCase)?.person
8082
logger.info("Running test for $id")
8183
personInfoService.setPersonInfo(id, person)
82-
val testConfiguration = TestCaseBuilder(mockOAuthServer, autorisasjonService)
83-
.also { testCase.configure(it) }
8484
val statusV2 =
8585
client.startStoppPeriode(
8686
periodeTilstand = testCase.tilstand,
8787
identitetsnummer = id,
88-
token = testConfiguration.authToken,
88+
token = testConfiguration.authToken?.second,
8989
godkjent = (testCase as? StartPeriodeTestCase)?.forhaandsGodkjent ?: false,
9090
feilretting = testCase.feilretting
9191
)
@@ -119,7 +119,8 @@ class ApiV2TestCaseRunner : FreeSpec({
119119
if (expectedRecord != null) {
120120
verify(
121121
actual = producer.next(),
122-
expected = expectedRecord
122+
expected = expectedRecord,
123+
brukerAuth = testConfiguration.authToken?.first
123124
)
124125
producer.next().shouldBeNull()
125126
} else {

apps/api-start-stopp-perioder/src/test/kotlin/no/nav/paw/arbeidssokerregisteret/ApplicationTestContext.kt

+21-12
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import no.nav.paw.arbeidssokerregisteret.domain.Identitetsnummer
2525
import no.nav.paw.arbeidssokerregisteret.domain.NavAnsatt
2626
import no.nav.paw.arbeidssokerregisteret.intern.v1.HarOpplysninger
2727
import no.nav.paw.arbeidssokerregisteret.intern.v1.Hendelse
28-
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.AvviksType
28+
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.BrukerType
2929
import no.nav.paw.arbeidssokerregisteret.services.AutorisasjonService
3030
import no.nav.paw.arbeidssokerregisteret.services.PersonInfoService
3131
import no.nav.paw.arbeidssokerregisteret.testdata.mustBe
@@ -56,24 +56,23 @@ fun HttpClientConfig<out io.ktor.client.engine.HttpClientEngineConfig>.defaultCo
5656
}
5757

5858

59-
fun MockOAuth2Server.personToken(id: String, acr: String = "idporten-loa-high"): SignedJWT = issueToken(
60-
claims = mapOf(
61-
"acr" to acr,
62-
"pid" to id
63-
)
64-
)
59+
fun MockOAuth2Server.personToken(id: String, acr: String = "idporten-loa-high"): Pair<Map<String, Any>, SignedJWT> =
60+
mapOf(
61+
"acr" to acr,
62+
"pid" to id
63+
).let { it.plus("issuer" to "tokenx") to issueToken(claims = it) }
6564

66-
fun MockOAuth2Server.ansattToken(navAnsatt: NavAnsatt): SignedJWT = issueToken(
67-
claims = mapOf(
65+
fun MockOAuth2Server.ansattToken(navAnsatt: NavAnsatt): Pair<Map<String, Any>, SignedJWT> =
66+
mapOf(
6867
"oid" to navAnsatt.azureId,
6968
"NAVident" to navAnsatt.ident
70-
)
71-
)
69+
).let { it.plus("issuer" to "azure") to issueToken(claims = it) }
7270

7371

7472
fun verify(
7573
actual: ProducerRecord<Long, Hendelse>?,
76-
expected: ProducerRecord<Long, out Hendelse>
74+
expected: ProducerRecord<Long, out Hendelse>,
75+
brukerAuth: Map<String, Any>?
7776
) {
7877
if (actual == null) {
7978
fail("Forventet at melding skulle bli produsert, men ingen melding ble funnet")
@@ -85,6 +84,16 @@ fun verify(
8584
actualValue.id shouldBe expectedValue.id
8685
actualValue.identitetsnummer shouldBe expectedValue.identitetsnummer
8786
actualValue.metadata.utfoertAv.id shouldBe expectedValue.metadata.utfoertAv.id
87+
if (brukerAuth == null) {
88+
actualValue.metadata.utfoertAv.sikkerhetsnivaa shouldBe null
89+
} else {
90+
if (brukerAuth["issuer"] == "azure") {
91+
actualValue.metadata.utfoertAv.type shouldBe BrukerType.VEILEDER
92+
} else {
93+
actualValue.metadata.utfoertAv.type shouldBe BrukerType.SLUTTBRUKER
94+
}
95+
actualValue.metadata.utfoertAv.sikkerhetsnivaa shouldBe "${brukerAuth["issuer"]}:${brukerAuth["acr"] ?: "undefined"}"
96+
}
8897
actualValue.metadata.utfoertAv.type shouldBe expectedValue.metadata.utfoertAv.type
8998
actualValue.metadata.tidspunktFraKilde?.avviksType shouldBe expectedValue.metadata.tidspunktFraKilde?.avviksType
9099
actualValue.metadata.tidspunktFraKilde?.tidspunkt mustBe expectedValue.metadata.tidspunktFraKilde?.tidspunkt

apps/api-start-stopp-perioder/src/test/kotlin/no/nav/paw/arbeidssokerregisteret/testdata/HentPersonReturnererNull.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ data object HentPersonReturnererNull : StartPeriodeTestCase {
2525
override val person = null
2626

2727
override val configure: TestCaseBuilder.() -> Unit = {
28-
authToken = mockOAuth2Server.personToken(id)
28+
authToken = mockOAuth2Server.personToken(id, "Level4")
2929
}
3030

3131
override val producesHttpResponse: HttpStatusCode = HttpStatusCode.Forbidden
@@ -58,7 +58,7 @@ data object HentPersonReturnererNull : StartPeriodeTestCase {
5858
utfoertAv = Bruker(
5959
id = id,
6060
type = BrukerType.SLUTTBRUKER,
61-
sikkerhetsnivaa = "idporten-loa-high"
61+
sikkerhetsnivaa = ""
6262
),
6363
aarsak = "any",
6464
tidspunktFraKilde = null

apps/api-start-stopp-perioder/src/test/kotlin/no/nav/paw/arbeidssokerregisteret/testdata/TestCase.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ class TestCaseBuilder(
4747
val mockOAuth2Server: MockOAuth2Server,
4848
val autorisasjonService: AutorisasjonService
4949
) {
50-
var authToken: SignedJWT? = null
50+
var authToken: Pair<Map<String, Any>, SignedJWT>? = null
5151
}

lib/security/src/main/kotlin/no/nav/paw/security/authentication/model/Bruker.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ data class Sluttbruker(
1313
val sikkerhetsnivaa: String?
1414
) : Bruker<Identitetsnummer>(ident)
1515

16-
data class NavAnsatt(val oid: UUID, override val ident: String) : Bruker<String>(ident)
16+
data class NavAnsatt(val oid: UUID, override val ident: String, val sikkerhetsnivaa: String?) : Bruker<String>(ident)
1717
data class Anonym(val oid: UUID? = null) : Bruker<String>("N/A")

lib/security/src/main/kotlin/no/nav/paw/security/authentication/model/SecurityContext.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ data class SecurityContext(
1818
val accessToken: AccessToken
1919
)
2020

21+
fun AccessToken.sikkerhetsnivaa(): String = "${issuer.name}:${claims.getOrNull(ACR) ?: "undefined"}"
22+
2123
fun ApplicationCall.resolveSecurityContext(): SecurityContext {
2224
val principal = principal<TokenValidationContextPrincipal>()
2325
val tokenContext = principal?.context
@@ -31,7 +33,7 @@ fun ApplicationCall.resolveSecurityContext(): SecurityContext {
3133
logger.debug("TokenX token -> Sluttbruker")
3234
Sluttbruker(
3335
ident = accessToken.claims.getOrThrow(PID),
34-
sikkerhetsnivaa = accessToken.claims.getOrNull(ACR)
36+
sikkerhetsnivaa = accessToken.sikkerhetsnivaa(),
3537
)
3638
}
3739

@@ -43,19 +45,19 @@ fun ApplicationCall.resolveSecurityContext(): SecurityContext {
4345
Anonym(accessToken.claims.getOrThrow(OID))
4446
} else {
4547
logger.debug("AzureAd M2M token -> NavAnsatt")
46-
NavAnsatt(accessToken.claims.getOrThrow(OID), navIdentHeader)
48+
NavAnsatt(accessToken.claims.getOrThrow(OID), ident = navIdentHeader, sikkerhetsnivaa = accessToken.sikkerhetsnivaa())
4749
}
4850
} else {
4951
logger.debug("AzureAd token -> NavAnsatt")
50-
NavAnsatt(accessToken.claims.getOrThrow(OID), accessToken.claims.getOrThrow(NavIdent))
52+
NavAnsatt(accessToken.claims.getOrThrow(OID), accessToken.claims.getOrThrow(NavIdent), accessToken.sikkerhetsnivaa())
5153
}
5254
}
5355

5456
is IdPorten -> {
5557
logger.debug("IdPorten token -> Sluttbruker")
5658
Sluttbruker(
5759
ident = accessToken.claims.getOrThrow(PID),
58-
sikkerhetsnivaa = accessToken.claims.getOrNull(ACR)
60+
sikkerhetsnivaa = accessToken.sikkerhetsnivaa()
5961
)
6062
}
6163

lib/security/src/main/kotlin/no/nav/paw/security/authentication/model/Token.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package no.nav.paw.security.authentication.model
33
sealed class Token(val issuer: Issuer, val claims: List<Claim<*>>)
44

55
data object TokenXToken : Token(TokenX, listOf(PID, ACR))
6-
data object AzureAdToken : Token(AzureAd, listOf(OID, Name, NavIdent, Roles))
6+
data object AzureAdToken : Token(AzureAd, listOf(OID, Name, NavIdent, Roles, ACR))
77
data object IdPortenToken : Token(IdPorten, listOf(PID, ACR))
8-
data object MaskinPortenToken : Token(MaskinPorten, emptyList())
8+
data object MaskinPortenToken : Token(MaskinPorten, listOf(ACR))
99

1010
val validTokens: List<Token> = listOf(TokenXToken, AzureAdToken, IdPortenToken, MaskinPortenToken)

0 commit comments

Comments
 (0)