chore: 不要になった依存と実装を削除

This commit is contained in:
2023-10-19 11:35:57 +09:00
parent c7d3b2d868
commit db65bb4b2e
11 changed files with 1 additions and 763 deletions
@@ -1,20 +1,16 @@
package dev.usbharu.hideout.config
import dev.usbharu.hideout.plugins.KtorKeyMap
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.service.core.Transaction
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.cache.*
import io.ktor.client.plugins.logging.*
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import tech.barbero.http.message.signing.KeyMap
@Configuration
class HttpClientConfig {
@Bean
fun httpClient(keyMap: KeyMap): HttpClient = HttpClient(CIO).config {
fun httpClient(): HttpClient = HttpClient(CIO).config {
install(Logging) {
logger = Logger.DEFAULT
level = LogLevel.INFO
@@ -24,16 +20,4 @@ class HttpClientConfig {
expectSuccess = true
}
@Bean
fun keyMap(
userQueryService: UserQueryService,
transaction: Transaction,
applicationConfig: ApplicationConfig
): KtorKeyMap {
return KtorKeyMap(
userQueryService,
transaction,
applicationConfig
)
}
}
@@ -1,183 +0,0 @@
package dev.usbharu.hideout.plugins
import dev.usbharu.hideout.config.ApplicationConfig
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.service.core.Transaction
import dev.usbharu.hideout.service.user.UserAuthServiceImpl
import io.ktor.client.plugins.api.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.coroutines.runBlocking
import tech.barbero.http.message.signing.HttpMessage
import tech.barbero.http.message.signing.HttpMessageSigner
import tech.barbero.http.message.signing.HttpRequest
import tech.barbero.http.message.signing.KeyMap
import java.net.URI
import java.security.KeyFactory
import java.security.PrivateKey
import java.security.PublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import java.text.SimpleDateFormat
import java.util.*
import javax.crypto.SecretKey
class HttpSignaturePluginConfig {
lateinit var keyMap: KeyMap
}
val httpSignaturePlugin: ClientPlugin<HttpSignaturePluginConfig> = createClientPlugin(
"HttpSign",
::HttpSignaturePluginConfig
) {
val keyMap = pluginConfig.keyMap
val format = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US)
format.timeZone = TimeZone.getTimeZone("GMT")
onRequest { request, body ->
request.header("Date", format.format(Date()))
request.header("Host", request.url.host)
if (request.bodyType?.type == String::class) {
body as String
// UserAuthService.sha256.reset()
val digest =
Base64.getEncoder().encodeToString(UserAuthServiceImpl.sha256.digest(body.toByteArray(Charsets.UTF_8)))
request.headers.append("Digest", "sha-256=$digest")
}
if (request.headers.contains("Signature")) {
val all = request.headers.getAll("Signature").orEmpty()
val parameters = mutableListOf<String>()
for (s in all) {
s.split(",").forEach { parameters.add(it) }
}
val keyId = parameters.find { it.startsWith("keyId") }
.orEmpty()
.split("=")[1]
.replace("\"", "")
val algorithm =
parameters.find { it.startsWith("algorithm") }
.orEmpty()
.split("=")[1]
.replace("\"", "")
val headers = parameters.find { it.startsWith("headers") }
.orEmpty()
.split("=")[1]
.replace("\"", "")
.split(" ")
.toMutableList()
val algorithmType = when (algorithm) {
"rsa-sha256" -> {
HttpMessageSigner.Algorithm.RSA_SHA256
}
else -> {
TODO()
}
}
headers.map {
when (it) {
"(request-target)" -> {
HttpMessageSigner.REQUEST_TARGET
}
"digest" -> {
"Digest"
}
"date" -> {
"Date"
}
"host" -> {
"Host"
}
else -> {
it
}
}
}
val builder = HttpMessageSigner.builder().algorithm(algorithmType).keyId(keyId).keyMap(keyMap)
var tmp = builder
headers.forEach {
tmp = tmp.addHeaderToSign(it)
}
val signer = tmp.build()
request.headers.remove("Signature")
(signer ?: return@onRequest).sign(object : HttpMessage, HttpRequest {
override fun headerValues(name: String?): MutableList<String> =
name?.let { request.headers.getAll(it) }?.toMutableList() ?: mutableListOf()
override fun addHeader(name: String?, value: String?) {
val split = value?.split("=").orEmpty()
name?.let { request.header(it, split[0] + "=\"" + split[1].trim('"') + "\"") }
}
override fun method(): String = request.method.value
override fun uri(): URI = request.url.build().toURI()
})
val signatureHeader = request.headers.getAll("Signature").orEmpty()
request.headers.remove("Signature")
signatureHeader.joinToString(",") { it.replace("; ", ",").replace(";", ",") }
.let { request.header("Signature", it) }
}
}
}
class KtorKeyMap(
private val userQueryService: UserQueryService,
private val transaction: Transaction,
private val applicationConfig: ApplicationConfig
) : KeyMap {
override fun getPublicKey(keyId: String?): PublicKey = runBlocking {
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
.substringAfterLast("/")
val publicBytes = Base64.getDecoder().decode(
transaction.transaction {
userQueryService.findByNameAndDomain(
username,
applicationConfig.url.host
).run {
publicKey
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replace("\n", "")
}
}
)
val x509EncodedKeySpec = X509EncodedKeySpec(publicBytes)
return@runBlocking KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec)
}
override fun getPrivateKey(keyId: String?): PrivateKey = runBlocking {
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
.substringAfterLast("/")
val publicBytes = Base64.getDecoder().decode(
transaction.transaction {
userQueryService.findByNameAndDomain(
username,
applicationConfig.url.host
).privateKey?.run {
replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\n", "")
}
}
)
val x509EncodedKeySpec = PKCS8EncodedKeySpec(publicBytes)
return@runBlocking KeyFactory.getInstance("RSA").generatePrivate(x509EncodedKeySpec)
}
@Suppress("NotImplementedDeclaration")
override fun getSecretKey(keyId: String?): SecretKey = TODO("Not yet implemented")
}
@@ -1,38 +0,0 @@
package dev.usbharu.hideout.service.auth
import dev.usbharu.hideout.config.ApplicationConfig
import dev.usbharu.hideout.plugins.KtorKeyMap
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.service.core.Transaction
import io.ktor.http.*
import org.springframework.stereotype.Service
import tech.barbero.http.message.signing.SignatureHeaderVerifier
@Service
interface HttpSignatureVerifyService {
fun verify(headers: Headers): Boolean
}
@Service
class HttpSignatureVerifyServiceImpl(
private val userQueryService: UserQueryService,
private val transaction: Transaction,
private val applicationConfig: ApplicationConfig
) : HttpSignatureVerifyService {
override fun verify(headers: Headers): Boolean {
val build =
SignatureHeaderVerifier.builder().keyMap(KtorKeyMap(userQueryService, transaction, applicationConfig))
.build()
return true
// build.verify(object : HttpMessage {
// override fun headerValues(name: String?): MutableList<String> {
// return name?.let { headers.getAll(it) }?.toMutableList() ?: mutableListOf()
// }
//
// override fun addHeader(name: String?, value: String?) {
// TODO()
// }
//
// })
}
}
@@ -1,17 +0,0 @@
package dev.usbharu.hideout.service.signature
import io.ktor.http.*
interface HttpSignatureSigner {
@Suppress("LongParameterList")
suspend fun sign(
url: String,
method: HttpMethod,
headers: Headers,
requestBody: String,
keyPair: Key,
signHeaders: List<String>
): SignedRequest
suspend fun signRaw(signString: String, keyPair: Key, signHeaders: List<String>): Sign
}
@@ -1,84 +0,0 @@
package dev.usbharu.hideout.service.signature
import dev.usbharu.hideout.util.Base64Util
import io.ktor.http.*
import io.ktor.util.*
import org.springframework.stereotype.Component
import java.net.URL
import java.security.Signature
@Component
class HttpSignatureSignerImpl : HttpSignatureSigner {
override suspend fun sign(
url: String,
method: HttpMethod,
headers: Headers,
requestBody: String,
keyPair: Key,
signHeaders: List<String>
): SignedRequest {
val sign = signRaw(
signString = buildSignString(
url = URL(url),
method = method,
headers = headers,
signHeaders = signHeaders
),
keyPair = keyPair,
signHeaders = signHeaders
)
val signedHeaders = headers {
appendAll(headers)
set("Signature", sign.signatureHeader)
}
return SignedRequest(
url = url,
method = method,
headers = signedHeaders,
requestBody = requestBody,
sign = sign
)
}
override suspend fun signRaw(signString: String, keyPair: Key, signHeaders: List<String>): Sign {
val signer = Signature.getInstance("SHA256withRSA")
signer.initSign(keyPair.privateKey)
signer.update(signString.toByteArray())
val sign = signer.sign()
val signature = Base64Util.encode(sign)
return Sign(
signature,
"""keyId="${keyPair.keyId}",algorithm="rsa-sha256",headers="${
signHeaders.joinToString(
" "
)
}",signature="$signature""""
)
}
private fun buildSignString(
url: URL,
method: HttpMethod,
headers: Headers,
signHeaders: List<String>
): String {
headers.toMap().map { it.key.lowercase() to it.value }.toMap()
val result = signHeaders.joinToString("\n") {
if (it.startsWith("(")) {
specialHeader(it, url, method)
} else {
generalHeader(it, headers.get(it)!!)
}
}
return result
}
private fun specialHeader(fieldName: String, url: URL, method: HttpMethod): String {
if (fieldName != "(request-target)") {
throw IllegalArgumentException(fieldName + "is unsupported type")
}
return "(request-target): ${method.value.lowercase()} ${url.path}"
}
private fun generalHeader(fieldName: String, value: String): String = "$fieldName: $value"
}
@@ -1,10 +0,0 @@
package dev.usbharu.hideout.service.signature
import java.security.PrivateKey
import java.security.PublicKey
data class Key(
val keyId: String,
val privateKey: PrivateKey,
val publicKey: PublicKey
)
@@ -1,6 +0,0 @@
package dev.usbharu.hideout.service.signature
data class Sign(
val signature: String,
val signatureHeader: String
)
@@ -1,23 +0,0 @@
package dev.usbharu.hideout.service.signature
import io.ktor.client.request.*
import io.ktor.http.*
data class SignedRequest(
val url: String,
val method: HttpMethod,
val headers: Headers,
val requestBody: String,
val sign: Sign
) {
fun toRequestBuilder(): HttpRequestBuilder {
val httpRequestBuilder = HttpRequestBuilder()
httpRequestBuilder.url(this.url)
httpRequestBuilder.method = this.method
httpRequestBuilder.headers {
this.appendAll(headers)
}
httpRequestBuilder.setBody(requestBody)
return httpRequestBuilder
}
}