Skip to content

Commit

Permalink
bump(deps): kotlinter 3.16.0 to 4.0.0 (#562)
Browse files Browse the repository at this point in the history
  • Loading branch information
ybelMekk authored Oct 11, 2023
1 parent c4d37a5 commit 19bbd72
Show file tree
Hide file tree
Showing 78 changed files with 2,579 additions and 2,089 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ plugins {
kotlin("jvm") version "1.9.10"
id("se.patrikerdes.use-latest-versions") version "0.2.18"
id("com.github.ben-manes.versions") version "0.49.0"
id("org.jmailen.kotlinter") version "3.16.0"
id("org.jmailen.kotlinter") version "4.0.0"
id("com.google.cloud.tools.jib") version "3.4.0"
id("com.github.johnrengelman.shadow") version "8.1.1"
id("net.researchgate.release") version "3.0.2"
Expand Down
87 changes: 54 additions & 33 deletions src/main/kotlin/no/nav/security/mock/oauth2/MockOAuth2Server.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ open class MockOAuth2Server(

private val httpServer = config.httpServer
private val defaultRequestHandler: OAuth2HttpRequestHandler = OAuth2HttpRequestHandler(config)
private val router: RequestHandler = routes(
*additionalRoutes,
defaultRequestHandler.authorizationServer,
)
private val router: RequestHandler =
routes(
*additionalRoutes,
defaultRequestHandler.authorizationServer,
)

/**
* Starts the [MockOAuth2Server] on the localhost interface.
Expand All @@ -63,11 +64,12 @@ open class MockOAuth2Server(
* @exception OAuth2Exception Runtime error if unable to start server.
*/
@JvmOverloads
fun start(port: Int = 0) = try {
start(InetAddress.getByName("localhost"), port)
} catch (ex: IOException) {
throw OAuth2Exception("unable to start server: ${ex.message}", ex)
}
fun start(port: Int = 0) =
try {
start(InetAddress.getByName("localhost"), port)
} catch (ex: IOException) {
throw OAuth2Exception("unable to start server: ${ex.message}", ex)
}

/**
* Starts the [MockOAuth2Server] on the given [inetAddress] IP address at the given [port].
Expand All @@ -77,7 +79,10 @@ open class MockOAuth2Server(
*
* @exception OAuth2Exception Runtime error if unable to start server.
*/
fun start(inetAddress: InetAddress, port: Int) {
fun start(
inetAddress: InetAddress,
port: Int,
) {
log.debug("attempt to start server on port=$port")
httpServer.start(inetAddress, port, router)
}
Expand All @@ -104,7 +109,9 @@ open class MockOAuth2Server(
fun url(path: String): HttpUrl = httpServer.url(path)

@Deprecated("Use MockWebServer method/function instead", ReplaceWith("MockWebServer.enqueue()"))
fun enqueueResponse(@Suppress("UNUSED_PARAMETER") response: MockResponse) {
fun enqueueResponse(
@Suppress("UNUSED_PARAMETER") response: MockResponse,
) {
throw UnsupportedOperationException("cannot enqueue MockResponse, please use the MockWebServer directly with QueueDispatcher")
}

Expand All @@ -125,7 +132,10 @@ open class MockOAuth2Server(
* @param unit A [TimeUnit] determining how to interpret the [timeout] parameter
*/
@JvmOverloads
fun takeRequest(timeout: Long = 2, unit: TimeUnit = TimeUnit.SECONDS): RecordedRequest =
fun takeRequest(
timeout: Long = 2,
unit: TimeUnit = TimeUnit.SECONDS,
): RecordedRequest =
(httpServer as? MockWebServerWrapper)?.mockWebServer?.let {
it.takeRequest(timeout, unit) ?: throw RuntimeException("no request found in queue within timeout $timeout $unit")
} ?: throw UnsupportedOperationException("can only takeRequest when httpServer is of type MockWebServer")
Expand Down Expand Up @@ -225,14 +235,19 @@ open class MockOAuth2Server(
* @param clientId The identifier for the client or Relying Party that requests the token.
* @param tokenCallback A callback that implements the [OAuth2TokenCallback] interface for token customization.
*/
fun issueToken(issuerId: String, clientId: String, tokenCallback: OAuth2TokenCallback): SignedJWT {
fun issueToken(
issuerId: String,
clientId: String,
tokenCallback: OAuth2TokenCallback,
): SignedJWT {
val uri = tokenEndpointUrl(issuerId)
val issuerUrl = issuerUrl(issuerId)
val tokenRequest = TokenRequest(
uri.toUri(),
ClientSecretBasic(ClientID(clientId), Secret("secret")),
AuthorizationCodeGrant(AuthorizationCode("123"), URI.create("http://localhost")),
)
val tokenRequest =
TokenRequest(
uri.toUri(),
ClientSecretBasic(ClientID(clientId), Secret("secret")),
AuthorizationCodeGrant(AuthorizationCode("123"), URI.create("http://localhost")),
)
return config.tokenProvider.accessToken(tokenRequest, issuerUrl, tokenCallback, null)
}

Expand All @@ -248,29 +263,35 @@ open class MockOAuth2Server(
audience: String? = "default",
claims: Map<String, Any> = emptyMap(),
expiry: Long = 3600,
): SignedJWT = issueToken(
issuerId,
"default",
DefaultOAuth2TokenCallback(
): SignedJWT =
issueToken(
issuerId,
subject,
JOSEObjectType.JWT.type,
audience?.let { listOf(it) },
claims,
expiry,
),
)
"default",
DefaultOAuth2TokenCallback(
issuerId,
subject,
JOSEObjectType.JWT.type,
audience?.let { listOf(it) },
claims,
expiry,
),
)

/**
* Issues a signed JWT for a given [issuerUrl] containing the input set of [claims].
* The JWT's signature can be verified with the server's keys found at the [jwksUrl] endpoint.
*/
@JvmOverloads
fun anyToken(issuerUrl: HttpUrl, claims: Map<String, Any>, expiry: Duration = Duration.ofHours(1)): SignedJWT {
fun anyToken(
issuerUrl: HttpUrl,
claims: Map<String, Any>,
expiry: Duration = Duration.ofHours(1),
): SignedJWT {
val jwtClaimsSet = claims.toJwtClaimsSet()
val mockGrant: AuthorizationGrant = object : AuthorizationGrant(GrantType("MockGrant")) {
override fun toParameters(): MutableMap<String, MutableList<String>> = mutableMapOf()
}
val mockGrant: AuthorizationGrant =
object : AuthorizationGrant(GrantType("MockGrant")) {
override fun toParameters(): MutableMap<String, MutableList<String>> = mutableMapOf()
}
return this.config.tokenProvider.exchangeAccessToken(
TokenRequest(URI.create("http://mockgrant"), ClientID("mockclientid"), mockGrant),
issuerUrl,
Expand Down
152 changes: 80 additions & 72 deletions src/main/kotlin/no/nav/security/mock/oauth2/OAuth2Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,90 +20,98 @@ import no.nav.security.mock.oauth2.token.OAuth2TokenProvider
import no.nav.security.mock.oauth2.token.RequestMappingTokenCallback
import java.io.File

data class OAuth2Config @JvmOverloads constructor(
val interactiveLogin: Boolean = false,
val loginPagePath: String? = null,
val staticAssetsPath: String? = null,
@JsonDeserialize(using = OAuth2TokenProviderDeserializer::class)
val tokenProvider: OAuth2TokenProvider = OAuth2TokenProvider(),
@JsonDeserialize(contentAs = RequestMappingTokenCallback::class)
val tokenCallbacks: Set<OAuth2TokenCallback> = emptySet(),
@JsonDeserialize(using = OAuth2HttpServerDeserializer::class)
val httpServer: OAuth2HttpServer = MockWebServerWrapper(),
) {

class OAuth2TokenProviderDeserializer : JsonDeserializer<OAuth2TokenProvider>() {
data class OAuth2Config
@JvmOverloads
constructor(
val interactiveLogin: Boolean = false,
val loginPagePath: String? = null,
val staticAssetsPath: String? = null,
@JsonDeserialize(using = OAuth2TokenProviderDeserializer::class)
val tokenProvider: OAuth2TokenProvider = OAuth2TokenProvider(),
@JsonDeserialize(contentAs = RequestMappingTokenCallback::class)
val tokenCallbacks: Set<OAuth2TokenCallback> = emptySet(),
@JsonDeserialize(using = OAuth2HttpServerDeserializer::class)
val httpServer: OAuth2HttpServer = MockWebServerWrapper(),
) {
class OAuth2TokenProviderDeserializer : JsonDeserializer<OAuth2TokenProvider>() {
data class ProviderConfig(
val keyProvider: KeyProviderConfig?,
)

data class ProviderConfig(
val keyProvider: KeyProviderConfig?,
)
data class KeyProviderConfig(
val initialKeys: String?,
val algorithm: String,
)

data class KeyProviderConfig(
val initialKeys: String?,
val algorithm: String,
)
override fun deserialize(
p: JsonParser,
ctxt: DeserializationContext?,
): OAuth2TokenProvider {
val node: JsonNode = p.readValueAsTree()
val config: ProviderConfig =
if (!node.isObject) {
return OAuth2TokenProvider()
} else {
p.codec.treeToValue(node, ProviderConfig::class.java)
}
val jwks =
config.keyProvider?.initialKeys?.let {
listOf(JWK.parse(it))
} ?: emptyList()

override fun deserialize(p: JsonParser, ctxt: DeserializationContext?): OAuth2TokenProvider {
val node: JsonNode = p.readValueAsTree()
val config: ProviderConfig = if (!node.isObject) {
return OAuth2TokenProvider()
} else {
p.codec.treeToValue(node, ProviderConfig::class.java)
return OAuth2TokenProvider(
KeyProvider(
jwks,
config.keyProvider?.algorithm ?: JWSAlgorithm.RS256.name,
),
)
}
val jwks = config.keyProvider?.initialKeys?.let {
listOf(JWK.parse(it))
} ?: emptyList()

return OAuth2TokenProvider(
KeyProvider(
jwks,
config.keyProvider?.algorithm ?: JWSAlgorithm.RS256.name,
),
)
}
}

class OAuth2HttpServerDeserializer : JsonDeserializer<OAuth2HttpServer>() {
enum class ServerType {
MockWebServerWrapper,
NettyWrapper,
}

data class ServerConfig(
val type: ServerType,
val ssl: SslConfig? = null,
)
class OAuth2HttpServerDeserializer : JsonDeserializer<OAuth2HttpServer>() {
enum class ServerType {
MockWebServerWrapper,
NettyWrapper,
}

data class SslConfig(
val keyPassword: String = "",
val keystoreFile: File? = null,
val keystoreType: SslKeystore.KeyStoreType = SslKeystore.KeyStoreType.PKCS12,
val keystorePassword: String = "",
) {
fun ssl() = Ssl(sslKeyStore())
data class ServerConfig(
val type: ServerType,
val ssl: SslConfig? = null,
)

private fun sslKeyStore() =
if (keystoreFile == null) SslKeystore() else SslKeystore(keyPassword, keystoreFile, keystoreType, keystorePassword)
}
data class SslConfig(
val keyPassword: String = "",
val keystoreFile: File? = null,
val keystoreType: SslKeystore.KeyStoreType = SslKeystore.KeyStoreType.PKCS12,
val keystorePassword: String = "",
) {
fun ssl() = Ssl(sslKeyStore())

override fun deserialize(p: JsonParser, ctxt: DeserializationContext): OAuth2HttpServer {
val node: JsonNode = p.readValueAsTree()
val serverConfig: ServerConfig = if (node.isObject) {
p.codec.treeToValue(node, ServerConfig::class.java)
} else {
ServerConfig(ServerType.valueOf(node.textValue()))
private fun sslKeyStore() = if (keystoreFile == null) SslKeystore() else SslKeystore(keyPassword, keystoreFile, keystoreType, keystorePassword)
}
val ssl: Ssl? = serverConfig.ssl?.ssl()
return when (serverConfig.type) {
ServerType.NettyWrapper -> NettyWrapper(ssl)
ServerType.MockWebServerWrapper -> MockWebServerWrapper(ssl)

override fun deserialize(
p: JsonParser,
ctxt: DeserializationContext,
): OAuth2HttpServer {
val node: JsonNode = p.readValueAsTree()
val serverConfig: ServerConfig =
if (node.isObject) {
p.codec.treeToValue(node, ServerConfig::class.java)
} else {
ServerConfig(ServerType.valueOf(node.textValue()))
}
val ssl: Ssl? = serverConfig.ssl?.ssl()
return when (serverConfig.type) {
ServerType.NettyWrapper -> NettyWrapper(ssl)
ServerType.MockWebServerWrapper -> MockWebServerWrapper(ssl)
}
}
}
}

companion object {
fun fromJson(json: String): OAuth2Config {
return jacksonObjectMapper().readValue(json)
companion object {
fun fromJson(json: String): OAuth2Config {
return jacksonObjectMapper().readValue(json)
}
}
}
}
21 changes: 12 additions & 9 deletions src/main/kotlin/no/nav/security/mock/oauth2/OAuth2Exception.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ class OAuth2Exception(val errorObject: ErrorObject?, msg: String, throwable: Thr
constructor(errorObject: ErrorObject?, msg: String) : this(errorObject, msg, null)
}

fun missingParameter(name: String): Nothing = "missing required parameter $name".let {
throw OAuth2Exception(OAuth2Error.INVALID_REQUEST.setDescription(it), it)
}
fun missingParameter(name: String): Nothing =
"missing required parameter $name".let {
throw OAuth2Exception(OAuth2Error.INVALID_REQUEST.setDescription(it), it)
}

fun invalidGrant(grantType: GrantType): Nothing = "grant_type $grantType not supported.".let {
throw OAuth2Exception(OAuth2Error.INVALID_GRANT, it)
}
fun invalidGrant(grantType: GrantType): Nothing =
"grant_type $grantType not supported.".let {
throw OAuth2Exception(OAuth2Error.INVALID_GRANT, it)
}

fun invalidRequest(message: String): Nothing = message.let {
throw OAuth2Exception(OAuth2Error.INVALID_REQUEST, message)
}
fun invalidRequest(message: String): Nothing =
message.let {
throw OAuth2Exception(OAuth2Error.INVALID_REQUEST, message)
}

fun notFound(message: String): Nothing = throw OAuth2Exception(ErrorObject("not_found", "Resource not found", HTTPResponse.SC_NOT_FOUND), message)
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@ object StandaloneConfig {
const val SERVER_PORT = "SERVER_PORT"
const val PORT = "PORT" // Supports running Docker image on Heroku.

fun hostname(): InetAddress = SERVER_HOSTNAME.fromEnv()
?.let { InetAddress.getByName(it) } ?: InetSocketAddress(0).address
fun hostname(): InetAddress =
SERVER_HOSTNAME.fromEnv()
?.let { InetAddress.getByName(it) } ?: InetSocketAddress(0).address

fun port(): Int = (SERVER_PORT.fromEnv()?.toInt() ?: PORT.fromEnv()?.toInt()) ?: 8080

fun oauth2Config(): OAuth2Config = with(jsonFromEnv()) {
if (this != null) {
OAuth2Config.fromJson(this)
} else {
OAuth2Config(
interactiveLogin = true,
httpServer = NettyWrapper(),
)
fun oauth2Config(): OAuth2Config =
with(jsonFromEnv()) {
if (this != null) {
OAuth2Config.fromJson(this)
} else {
OAuth2Config(
interactiveLogin = true,
httpServer = NettyWrapper(),
)
}
}
}

private fun jsonFromEnv() = JSON_CONFIG.fromEnv() ?: JSON_CONFIG_PATH.fromEnv("config.json").readFile()

Expand All @@ -56,4 +58,5 @@ fun main() {
}

fun String.fromEnv(default: String): String = System.getenv(this) ?: default

fun String.fromEnv(): String? = System.getenv(this)
Loading

0 comments on commit 19bbd72

Please sign in to comment.