can submit an image

16
Timo Bryant 2024-01-10 15:06:39 +01:00
parent 92b53529f6
commit f645477ded
12 changed files with 109 additions and 18 deletions

View File

@ -0,0 +1,3 @@
dependencies {
implementation(project(":libraries:httpClient"))
}

View File

@ -0,0 +1,48 @@
package de.itkl.xsCli
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.subcommands
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.convert
import com.github.ajalt.clikt.parameters.options.required
import com.github.ajalt.clikt.parameters.types.int
import de.itkl.httpClient.clients.XsClient
import de.itkl.httpClient.httpClientModule
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.core.context.startKoin
import java.io.File
import java.nio.file.Paths
class Cli : CliktCommand() {
override fun run() {}
inner class StressAnalyse : CliktCommand(name = "stress-analyse") {
val inputDirectory: File by option(help="Input directory path").convert { File(it) }.required()
val tasks: Int by option(help="Number of tasks").int().required()
override fun run() {
// TODO: Use inputDirectory and tasks here
}
}
init {
subcommands(StressAnalyse())
}
}
class XsCli : KoinComponent {
private val xsClient: XsClient by inject()
suspend fun run() {
xsClient.analyse(Paths.get("assets/xs-reg/00001.jpg"))
}
}
suspend fun main(args: Array<String>) {
startKoin {
modules(httpClientModule)
}
XsCli().run()
// Cli().main(args)
}

View File

@ -0,0 +1,15 @@
import korlibs.korge.gradle.korge
plugins {
id("com.soywiz.korge") version "5.3.0"
}
dependencies {
jvmMainImplementation("ch.qos.logback:logback-classic:1.4.14")
jvmMainImplementation(project(":libraries:docthor-core"))
}
korge {
targetJvm()
serializationJson()
}

View File

@ -3,7 +3,7 @@ project(":libraries").subprojects {
}
project(":apps").subprojects {
if(name != "documentViewerKorge") {
if(name != "documentViewerKorge" && name != "xsViewer") {
apply(plugin = "docthor.kotlin-application-conventions")
}

View File

@ -1,10 +0,0 @@
package de.itkl.httpClient
import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable
@Serializable
data class BearerToken(
val tokenString: String,
val validUntil: Instant
)

View File

@ -12,9 +12,10 @@ private val Log = KotlinLogging.logger { }
val smartCloudAuthPlugin = createClientPlugin("SmartCloudAuth") {
val smartCloudAuthStrategy = SmartCloudAuthStrategy()
on(Send) { request ->
val token = smartCloudAuthStrategy.login(client, request) ?: error("login failed")
request.headers {
set(HttpHeaders.Authorization, "Bearer ${token.toBearer()}")
smartCloudAuthStrategy.login(client, request)?.let { token ->
request.headers {
set(HttpHeaders.Authorization, token.toBearer())
}
}
proceed(request)
}

View File

@ -0,0 +1,12 @@
package de.itkl.httpClient
import java.security.cert.X509Certificate
import javax.net.ssl.X509TrustManager
class TrustAllX509TrustManager : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate?> = arrayOfNulls(0)
override fun checkClientTrusted(certs: Array<X509Certificate?>?, authType: String?) {}
override fun checkServerTrusted(certs: Array<X509Certificate?>?, authType: String?) {}
}

View File

@ -1,12 +1,14 @@
package de.itkl.httpClient.auth
import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable
sealed class AuthenticationToken {
abstract val expires: Expires
abstract fun toBearer(): String
}
@Serializable
data class BearerToken(val token: String, val validUntil: Instant) : AuthenticationToken() {
override val expires: Expires
get() = Expires.ExpiresAt(validUntil)

View File

@ -4,5 +4,5 @@ import kotlinx.serialization.Serializable
sealed class Credentials {
@Serializable
data class LoginAndPassword(val login: String, val password: String) : Credentials()
data class LoginAndPassword(val username: String, val password: String) : Credentials()
}

View File

@ -8,6 +8,7 @@ import io.ktor.client.statement.*
import io.ktor.client.utils.EmptyContent.contentType
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.util.*
import io.ktor.util.cio.*
import io.ktor.utils.io.*
import io.ktor.utils.io.streams.*
@ -44,10 +45,12 @@ class XsClient : KoinComponent {
}
)
}
)
) {
this.attributes.put(AttributeKey("username"), "xs.dev.klara")
}
val responseText = response.bodyAsText()
Log.info { "Form submitted successfully: ${response.status}: $responseText" }
Log.info { "Form submitted: ${response.status}: $responseText" }
}
}

View File

@ -1,9 +1,13 @@
package de.itkl.httpClient
import io.ktor.client.*
import io.ktor.client.engine.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import kotlin.time.Duration.Companion.minutes
fun createHttpClient(): HttpClient {
return HttpClient(CIO) {
@ -11,5 +15,15 @@ fun createHttpClient(): HttpClient {
json()
}
install(smartCloudAuthPlugin)
install(HttpTimeout) {
requestTimeoutMillis = 1.minutes.inWholeMilliseconds
}
engine {
proxy = ProxyBuilder.http(Url("http://localhost:9999"))
https {
trustManager = TrustAllX509TrustManager()
}
}
}
}

View File

@ -17,7 +17,10 @@ class SmartCloudAuthStrategy : AuthStrategy, KoinComponent {
private val credentialsProvider: CredentialsProvider by inject()
override suspend fun login(httpClient: HttpClient, request: HttpRequestBuilder): AuthenticationToken? {
Log.debug { "Attempting login..." }
val user = request.attributes.getOrNull(AttributeKey<String>("username")) ?: error("No username is specified for this request: $request")
val user = request.attributes.getOrNull(AttributeKey<String>("username")) ?: run {
Log.info { "No username is specified for this request" }
return null
}
val credentials: Credentials = credentialsProvider.lookupByUsername(user) ?: error("No credentials found for user: $user")
val loginAndPassword: Credentials.LoginAndPassword = credentials as? Credentials.LoginAndPassword ?: error("Only username and password is supported by smartcloud auth login")