105 lines
4.9 KiB
Kotlin
105 lines
4.9 KiB
Kotlin
package com.securityc4po.api
|
|
|
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
|
import com.github.dockerjava.api.model.ExposedPort
|
|
import com.github.dockerjava.api.model.PortBinding
|
|
import com.github.dockerjava.api.model.Ports
|
|
import com.nimbusds.jwt.JWTParser
|
|
import org.junit.jupiter.api.TestInstance
|
|
import org.springframework.beans.factory.annotation.Value
|
|
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock
|
|
import org.springframework.http.HttpEntity
|
|
import org.springframework.http.HttpHeaders
|
|
import org.springframework.http.MediaType
|
|
import org.springframework.test.context.TestPropertySource
|
|
import org.springframework.util.LinkedMultiValueMap
|
|
import org.springframework.web.client.RestTemplate
|
|
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper
|
|
import org.testcontainers.containers.GenericContainer
|
|
import org.testcontainers.images.builder.ImageFromDockerfile
|
|
import org.testcontainers.utility.DockerImageName
|
|
import org.testcontainers.utility.MountableFile
|
|
import java.nio.file.Paths
|
|
|
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
@AutoConfigureWireMock(port = 0)
|
|
@TestPropertySource(properties = [
|
|
"spring.data.mongodb.port=10002",
|
|
"spring.data.mongodb.authentication-database=admin",
|
|
"spring.data.mongodb.password=test",
|
|
"spring.data.mongodb.username=testuser",
|
|
"MONGO_DB_MAX_CONNECTION_IDLE_TIME=PT25M",
|
|
"DATA_REFRESH_THRESHOLD_DURATION=PT30M",
|
|
"CLEANUP_BATCH_SIZE_FOR_SELECTING_EXPIRED_USERS=100"
|
|
])
|
|
abstract class BaseContainerizedTest {
|
|
@Value("\${keycloakhost}")
|
|
var keycloakhost: String? = null
|
|
|
|
companion object {
|
|
val mongoDbContainer = KGenericContainer(ImageFromDockerfile("c4poapibasecontainerizedtest").withDockerfileFromBuilder {
|
|
it.from("mongo")
|
|
it.env("MONGO_INITDB_ROOT_USERNAME", "root")
|
|
it.env("MONGO_INITDB_ROOT_PASSWORD", "cjwkbencowepoc324pon2mop3mp4")
|
|
it.env("MONGO_INITDB_DATABASE", "admin")
|
|
it.add("insert-mongodb-user.js", "/docker-entrypoint-initdb.d")
|
|
}.withFileFromPath("insert-mongodb-user.js", Paths.get(MountableFile.forClasspathResource("insert-mongodb-user.js", 700).resolvedPath))
|
|
).apply {
|
|
withCreateContainerCmdModifier {
|
|
it.hostConfig?.withPortBindings(PortBinding(Ports.Binding.bindPort(10002), ExposedPort(27017)))
|
|
}
|
|
start()
|
|
}
|
|
|
|
val keycloakContainer = KGenericContainerFromImage(DockerImageName.parse("jboss/keycloak:6.0.1")).apply {
|
|
withEnv("KEYCLOAK_USER", "admin")
|
|
withEnv("KEYCLOAK_PASSWORD", "admin")
|
|
withEnv("KEYCLOAK_IMPORT", "/tmp/realm.json")
|
|
withEnv("DB_VENDOR", "h2")
|
|
withCreateContainerCmdModifier {
|
|
it.hostConfig?.withPortBindings(PortBinding(Ports.Binding.bindPort(8888), ExposedPort(8080)))
|
|
}
|
|
withCopyFileToContainer(MountableFile.forClasspathResource("outdated_realm-export.json", 700), "/tmp/realm.json")
|
|
withCopyFileToContainer(MountableFile.forClasspathResource("create-keycloak-user.sh", 700),
|
|
"/opt/jboss/create-keycloak-user.sh")
|
|
start()
|
|
println("== Inserting users must wait until Keycloak is started completely ==")
|
|
execInContainer("sh", "/opt/jboss/create-keycloak-user.sh")
|
|
}
|
|
}
|
|
|
|
var token = "n/a"
|
|
var tokenAdmin = "n/a"
|
|
var tokenUser = "n/a"
|
|
var keycloakHost: String? = null
|
|
|
|
fun getAccessToken(username: String, password: String, clientId: String, realm: String): String {
|
|
keycloakHost = "http://" + keycloakhost + ":" + keycloakContainer.getMappedPort(8080)
|
|
val restTemplate = RestTemplate()
|
|
val headers = HttpHeaders()
|
|
headers.contentType = MediaType.APPLICATION_FORM_URLENCODED
|
|
|
|
val map = LinkedMultiValueMap<Any, Any>()
|
|
map.add("grant_type", "password")
|
|
map.add("client_id", clientId)
|
|
map.add("username", username)
|
|
map.add("password", password)
|
|
map.add("client_secret", "secret")
|
|
val responseString = restTemplate.postForObject("$keycloakHost/auth/realms/$realm/protocol/openid-connect/token",
|
|
HttpEntity<Any>(map, headers), String::class.java)
|
|
val token = ObjectMapper().readValue(responseString, KeyCloakToken::class.java)
|
|
return token.access_token!!
|
|
}
|
|
|
|
fun getSubClaim(token: String): String {
|
|
val jwt = JWTParser.parse(token)
|
|
val scopes = ObjectMapper().readValue(jwt.jwtClaimsSet.toJSONObject().toJSONString(), HashMap::class.java)
|
|
return scopes["sub"] as String
|
|
}
|
|
|
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
class KeyCloakToken(val access_token: String? = null)
|
|
|
|
class KGenericContainerFromImage(imageName: DockerImageName) : GenericContainer<KGenericContainerFromImage>(imageName)
|
|
class KGenericContainer(dockerFile: ImageFromDockerfile) : GenericContainer<KGenericContainer>(dockerFile)
|
|
} |