@@ -2,48 +2,85 @@ package no.nav.security.mock.oauth2.extensions
2
2
3
3
import com.nimbusds.oauth2.sdk.OAuth2Error
4
4
import no.nav.security.mock.oauth2.OAuth2Exception
5
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.AUTHORIZATION
6
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.DEBUGGER
7
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.DEBUGGER_CALLBACK
8
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.END_SESSION
9
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.JWKS
10
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.OAUTH2_WELL_KNOWN
11
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.OIDC_WELL_KNOWN
12
+ import no.nav.security.mock.oauth2.extensions.OAuth2Endpoints.TOKEN
5
13
import okhttp3.HttpUrl
6
14
7
- fun HttpUrl.isWellKnownUrl (): Boolean = this == this .toWellKnownUrl() || this == this .toOAuth2AuthorizationServerMetadataUrl()
8
- fun HttpUrl.isAuthorizationEndpointUrl (): Boolean = this .withoutQuery() == this .toAuthorizationEndpointUrl()
9
- fun HttpUrl.isTokenEndpointUrl (): Boolean = this == this .toTokenEndpointUrl()
10
- fun HttpUrl.isEndSessionEndpointUrl (): Boolean = this .withoutQuery() == this .toEndSessionEndpointUrl()
11
- fun HttpUrl.isJwksUrl (): Boolean = this == this .toJwksUrl()
12
- fun HttpUrl.isDebuggerUrl (): Boolean = this .withoutQuery() == this .toDebuggerUrl()
13
- fun HttpUrl.isDebuggerCallbackUrl (): Boolean = this .withoutQuery() == this .toDebuggerCallbackUrl()
14
-
15
- fun HttpUrl.toOAuth2AuthorizationServerMetadataUrl () = this .resolvePath(" /${issuerId()} /.well-known/oauth-authorization-server" )
16
- fun HttpUrl.toWellKnownUrl (): HttpUrl = this .resolvePath(" /${issuerId()} /.well-known/openid-configuration" )
17
- fun HttpUrl.toAuthorizationEndpointUrl (): HttpUrl = this .resolvePath(" /${issuerId()} /authorize" )
18
- fun HttpUrl.toEndSessionEndpointUrl (): HttpUrl = this .resolvePath(" /${issuerId()} /endsession" )
19
- fun HttpUrl.toTokenEndpointUrl (): HttpUrl = this .resolvePath(" /${issuerId()} /token" )
20
- fun HttpUrl.toJwksUrl (): HttpUrl = this .resolvePath(" /${issuerId()} /jwks" )
21
- fun HttpUrl.toIssuerUrl (): HttpUrl = this .resolvePath(" /${issuerId()} " )
22
- fun HttpUrl.toDebuggerUrl (): HttpUrl = this .resolvePath(" /${issuerId()} /debugger" )
23
- fun HttpUrl.toDebuggerCallbackUrl (): HttpUrl = this .resolvePath(" /${issuerId()} /debugger/callback" )
24
-
25
- fun HttpUrl.issuerId (): String = this .pathSegments.getOrNull(0 )
26
- ? : throw OAuth2Exception (OAuth2Error .INVALID_REQUEST , " issuerId must be first segment in url path" )
15
+ object OAuth2Endpoints {
16
+ const val OAUTH2_WELL_KNOWN = " /.well-known/oauth-authorization-server"
17
+ const val OIDC_WELL_KNOWN = " /.well-known/openid-configuration"
18
+ const val AUTHORIZATION = " /authorize"
19
+ const val TOKEN = " /token"
20
+ const val END_SESSION = " /endsession"
21
+ const val JWKS = " /jwks"
22
+ const val DEBUGGER = " /debugger"
23
+ const val DEBUGGER_CALLBACK = " /debugger/callback"
27
24
28
- fun HttpUrl.Builder.removeAllEncodedQueryParams (vararg params : String ) =
29
- apply { params.forEach { removeAllEncodedQueryParameters(it) } }
25
+ val all = listOf (
26
+ OAUTH2_WELL_KNOWN ,
27
+ OIDC_WELL_KNOWN ,
28
+ AUTHORIZATION ,
29
+ TOKEN ,
30
+ END_SESSION ,
31
+ JWKS ,
32
+ DEBUGGER ,
33
+ DEBUGGER_CALLBACK
34
+ )
35
+ }
30
36
31
- fun HttpUrl.match (path : String ) =
32
- path.trimPath().let {
33
- this .pathSegments.containsAll(it.split(" /" ))
37
+ fun HttpUrl.isWellKnownUrl (): Boolean = this .endsWith(OAUTH2_WELL_KNOWN ) || this .endsWith(OIDC_WELL_KNOWN )
38
+ fun HttpUrl.isAuthorizationEndpointUrl (): Boolean = this .endsWith(AUTHORIZATION )
39
+ fun HttpUrl.isTokenEndpointUrl (): Boolean = this .endsWith(TOKEN )
40
+ fun HttpUrl.isEndSessionEndpointUrl (): Boolean = this .endsWith(END_SESSION )
41
+ fun HttpUrl.isJwksUrl (): Boolean = this .endsWith(JWKS )
42
+ fun HttpUrl.isDebuggerUrl (): Boolean = this .endsWith(DEBUGGER )
43
+ fun HttpUrl.isDebuggerCallbackUrl (): Boolean = this .endsWith(DEBUGGER_CALLBACK )
44
+
45
+ fun HttpUrl.toOAuth2AuthorizationServerMetadataUrl () = issuer(OAUTH2_WELL_KNOWN )
46
+ fun HttpUrl.toWellKnownUrl (): HttpUrl = issuer(OIDC_WELL_KNOWN )
47
+ fun HttpUrl.toAuthorizationEndpointUrl (): HttpUrl = issuer(AUTHORIZATION )
48
+ fun HttpUrl.toEndSessionEndpointUrl (): HttpUrl = issuer(END_SESSION )
49
+ fun HttpUrl.toTokenEndpointUrl (): HttpUrl = issuer(TOKEN )
50
+ fun HttpUrl.toJwksUrl (): HttpUrl = issuer(JWKS )
51
+ fun HttpUrl.toIssuerUrl (): HttpUrl = issuer()
52
+ fun HttpUrl.toDebuggerUrl (): HttpUrl = issuer(DEBUGGER )
53
+ fun HttpUrl.toDebuggerCallbackUrl (): HttpUrl = issuer(DEBUGGER_CALLBACK )
54
+
55
+ fun HttpUrl.issuerId (): String {
56
+ val path = this .pathSegments.joinToString(" /" ).trimPath()
57
+ OAuth2Endpoints .all.forEach {
58
+ if (path.endsWith(it)) {
59
+ return path.substringBefore(it)
60
+ }
34
61
}
62
+ return path
63
+ }
64
+
65
+ fun HttpUrl.Builder.removeAllEncodedQueryParams (vararg params : String ) =
66
+ apply { params.forEach { removeAllEncodedQueryParameters(it) } }
35
67
36
68
fun HttpUrl.endsWith (path : String ): Boolean = this .pathSegments.joinToString(" /" ).endsWith(path.trimPath())
37
69
38
70
private fun String.trimPath () = removePrefix(" /" ).removeSuffix(" /" )
39
71
40
- private fun HttpUrl.withoutQuery (): HttpUrl = this .newBuilder().query(null ).build()
72
+ private fun HttpUrl.issuer (path : String = ""): HttpUrl =
73
+ baseUrl().let {
74
+ it.resolve(joinPaths(issuerId(), path))
75
+ ? : throw OAuth2Exception (OAuth2Error .INVALID_REQUEST , " cannot resolve path $path " )
76
+ }
77
+
78
+ private fun joinPaths (vararg path : String ) =
79
+ path.filter { it.isNotEmpty() }.joinToString(" /" ) { it.trimPath() }
41
80
42
- private fun HttpUrl.resolvePath ( path : String ): HttpUrl {
43
- return HttpUrl .Builder ()
81
+ private fun HttpUrl.baseUrl ( ): HttpUrl =
82
+ HttpUrl .Builder ()
44
83
.scheme(this .scheme)
45
84
.host(this .host)
46
85
.port(this .port)
47
86
.build()
48
- .resolve(path.removePrefix(" /" )) ? : throw OAuth2Exception (OAuth2Error .INVALID_REQUEST , " cannot resolve path $path " )
49
- }
0 commit comments