1
1
package no.nav.security.mock.oauth2.http
2
2
3
+ import com.fasterxml.jackson.core.JacksonException
4
+ import com.fasterxml.jackson.databind.node.ObjectNode
5
+ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
3
6
import com.nimbusds.oauth2.sdk.ErrorObject
4
7
import com.nimbusds.oauth2.sdk.GeneralException
5
8
import com.nimbusds.oauth2.sdk.GrantType
@@ -20,6 +23,8 @@ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.END_SESSION
20
23
import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.JWKS
21
24
import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.OAUTH2_WELL_KNOWN
22
25
import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.OIDC_WELL_KNOWN
26
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.TESTUTILS_JWKS
27
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.TESTUTILS_SIGN
23
28
import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.TOKEN
24
29
import no.nav.security.mock.oauth2.extensions.isPrompt
25
30
import no.nav.security.mock.oauth2.extensions.issuerId
@@ -82,6 +87,7 @@ class OAuth2HttpRequestHandler(private val config: OAuth2Config) {
82
87
endSession()
83
88
userInfo(config.tokenProvider)
84
89
preflight()
90
+ testutils()
85
91
get(" /favicon.ico" ) { OAuth2HttpResponse (status = 200 ) }
86
92
attach(debuggerRequestHandler)
87
93
}
@@ -157,4 +163,52 @@ class OAuth2HttpRequestHandler(private val config: OAuth2Config) {
157
163
config.tokenCallbacks.firstOrNull { it.issuerId() == issuerId } ? : DefaultOAuth2TokenCallback (issuerId = issuerId)
158
164
}
159
165
}
166
+
167
+ private fun Route.Builder.testutils () = apply {
168
+
169
+ get(TESTUTILS_JWKS ) {
170
+ val jwk = config.tokenProvider.fullJwkSet(it.url.issuerId())
171
+ json(jwk.toJSONObject(false ))
172
+ }
173
+ post(TESTUTILS_SIGN ) {
174
+ val issuerId = it.url.issuerId()
175
+ val om = jacksonObjectMapper()
176
+ try {
177
+ val parsedbody = om.readValue(it.body, ObjectNode ::class .java)
178
+
179
+ val claimsMap = when {
180
+ parsedbody.has(" claims" ) -> {
181
+ val claims = mutableMapOf<String , String >()
182
+ parsedbody.get(" claims" ).fields().forEach {
183
+ claims[it.key] = it.value.toString()
184
+ }
185
+ claims.toMap()
186
+ }
187
+ else -> mapOf ()
188
+ }
189
+ val expiryDuration = when {
190
+ parsedbody.has(" expiry" ) -> {
191
+ val expirytxt = parsedbody.get(" expiry" ).asText(" PT1H" )
192
+ java.time.Duration .parse(expirytxt)
193
+ }
194
+ else -> java.time.Duration .parse(" PT1H" )
195
+ }
196
+ val signedJwt = config.tokenProvider.jwt(claimsMap, expiryDuration, issuerId)
197
+
198
+ OAuth2HttpResponse (status = 200 , body = (signedJwt.serialize()))
199
+
200
+ } catch (ex: JacksonException ) {
201
+ OAuth2HttpResponse (status = 400 , body = ex.message.toString())
202
+ } catch (ex: java.time.format.DateTimeParseException ) {
203
+ val outputStr = ex.message.toString() + listOf (
204
+ " \n " + " `" + ex.parsedString + " `" ,
205
+ " \n Examples of java.time.Duration string format:\n " ,
206
+ " P1D (1 day), " ,
207
+ " PT1H (1 hour), " ,
208
+ " P0DT0H10M30S (0 days, 0 hours, 10 minutes, 30 seconds)" ,
209
+ ).joinToString(" " )
210
+ OAuth2HttpResponse (status = 400 , body = outputStr)
211
+ }
212
+ }
213
+ }
160
214
}
0 commit comments