From 217f8cde076c0602d9245b308b5534d35cb6b759 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 5 Apr 2023 21:47:29 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20ActivityPub=E9=96=A2=E4=BF=82=E3=81=AE?= =?UTF-8?q?=E3=83=AB=E3=83=BC=E3=83=86=E3=82=A3=E3=83=B3=E3=82=B0=E3=82=92?= =?UTF-8?q?=E6=95=B4=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/HttpSignatureVerifyException.kt | 8 +++++++ .../exception/{ap => }/JsonParseException.kt | 2 +- .../dev/usbharu/hideout/plugins/Routing.kt | 14 +++++++---- .../routing/activitypub/InboxRouting.kt | 21 +++++++++++++---- .../routing/activitypub/OutboxRouting.kt | 10 ++++---- .../routing/activitypub/UserRouting.kt | 8 ++++++- .../service/activitypub/ActivityPubService.kt | 2 +- .../activitypub/ActivityPubServiceImpl.kt | 10 ++++---- .../signature/HttpSignatureVerifyService.kt | 7 ++++++ .../HttpSignatureVerifyServiceImpl.kt | 23 +++++++++++++++++++ 10 files changed, 83 insertions(+), 22 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/exception/HttpSignatureVerifyException.kt rename src/main/kotlin/dev/usbharu/hideout/exception/{ap => }/JsonParseException.kt (85%) create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/exception/HttpSignatureVerifyException.kt b/src/main/kotlin/dev/usbharu/hideout/exception/HttpSignatureVerifyException.kt new file mode 100644 index 00000000..d123025f --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/exception/HttpSignatureVerifyException.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.exception + +class HttpSignatureVerifyException : IllegalArgumentException { + constructor() : super() + constructor(s: String?) : super(s) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/exception/ap/JsonParseException.kt b/src/main/kotlin/dev/usbharu/hideout/exception/JsonParseException.kt similarity index 85% rename from src/main/kotlin/dev/usbharu/hideout/exception/ap/JsonParseException.kt rename to src/main/kotlin/dev/usbharu/hideout/exception/JsonParseException.kt index 61208029..d5749f75 100644 --- a/src/main/kotlin/dev/usbharu/hideout/exception/ap/JsonParseException.kt +++ b/src/main/kotlin/dev/usbharu/hideout/exception/JsonParseException.kt @@ -1,4 +1,4 @@ -package dev.usbharu.hideout.exception.ap +package dev.usbharu.hideout.exception class JsonParseException : IllegalArgumentException { constructor() : super() diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt index 44f097ad..3710262d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt @@ -1,15 +1,19 @@ package dev.usbharu.hideout.plugins +import dev.usbharu.hideout.routing.activitypub.inbox +import dev.usbharu.hideout.routing.activitypub.outbox +import dev.usbharu.hideout.routing.activitypub.usersAP +import dev.usbharu.hideout.service.activitypub.ActivityPubService +import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService import io.ktor.server.routing.* -import io.ktor.server.response.* import io.ktor.server.plugins.autohead.* import io.ktor.server.application.* -fun Application.configureRouting() { +fun Application.configureRouting(httpSignatureVerifyService: HttpSignatureVerifyService,activityPubService: ActivityPubService) { install(AutoHeadResponse) routing { - get("/") { - call.respondText("Hello World!") - } + inbox(httpSignatureVerifyService,activityPubService) + outbox() + usersAP(activityPubService) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt index d82ea289..fc08e892 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt @@ -1,24 +1,35 @@ package dev.usbharu.hideout.routing.activitypub +import dev.usbharu.hideout.exception.HttpSignatureVerifyException +import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService +import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.request.* +import io.ktor.server.response.* import io.ktor.server.routing.* -fun Routing.inbox(){ +fun Routing.inbox(httpSignatureVerifyService: HttpSignatureVerifyService,activityPubService: dev.usbharu.hideout.service.activitypub.ActivityPubService){ route("/inbox") { get { - + call.respond(HttpStatusCode.MethodNotAllowed) } post { - + if (httpSignatureVerifyService.verify(call.request.headers).not()) { + throw HttpSignatureVerifyException() + } + val json = call.receiveText() + val activityTypes = activityPubService.parseActivity(json) + activityPubService.processActivity(json,activityTypes) + call.respond(HttpStatusCode.NotImplemented) } } route("/users/{name}/inbox"){ get { - + call.respond(HttpStatusCode.NotImplemented) } post { - + call.respond(HttpStatusCode.MethodNotAllowed) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt index cc8b133d..7bfced91 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt @@ -1,24 +1,26 @@ package dev.usbharu.hideout.routing.activitypub +import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.response.* import io.ktor.server.routing.* fun Routing.outbox() { route("/outbox") { get { - + call.respond(HttpStatusCode.NotImplemented) } post { - + call.respond(HttpStatusCode.NotImplemented) } } route("/users/{name}/outbox"){ get { - + call.respond(HttpStatusCode.NotImplemented) } post { - + call.respond(HttpStatusCode.NotImplemented) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index a071c5f7..9c73fbbc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -1,14 +1,20 @@ package dev.usbharu.hideout.routing.activitypub +import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.util.HttpUtil.Activity import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.request.* +import io.ktor.server.response.* import io.ktor.server.routing.* -fun Routing.users(){ +fun Routing.usersAP(activityPubService: ActivityPubService){ route("/users/{name}"){ createChild(ContentTypeRouteSelector(ContentType.Application.Activity)).handle { + val json = call.receiveText() + val activityTypes = activityPubService.parseActivity(json) + activityPubService.processActivity(json,activityTypes) + call.respond(HttpStatusCode.NotImplemented) } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubService.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubService.kt index 55d3eec4..070046a3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubService.kt @@ -1,7 +1,7 @@ package dev.usbharu.hideout.service.activitypub interface ActivityPubService { - fun parseActivity(json:String): List + fun parseActivity(json:String): ActivityType fun processActivity(json:String, type: ActivityType) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt index 6e407bb3..9e238c7f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt @@ -2,10 +2,10 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.databind.JsonNode import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.exception.ap.JsonParseException +import dev.usbharu.hideout.exception.JsonParseException class ActivityPubServiceImpl : ActivityPubService { - override fun parseActivity(json: String): List { + override fun parseActivity(json: String): ActivityType { val readTree = Config.configData.objectMapper.readTree(json) if (readTree.isObject.not()) { throw JsonParseException("Json is not object.") @@ -13,10 +13,10 @@ class ActivityPubServiceImpl : ActivityPubService { val type = readTree["type"] if (type.isArray) { return type.mapNotNull { jsonNode: JsonNode -> - ActivityType.values().filter { it.name.equals(jsonNode.toPrettyString(), true) } - }.flatten() + ActivityType.values().firstOrNull { it.name.equals(jsonNode.asText(), true) } + }.first() } - return ActivityType.values().filter { it.name.equals(type.toPrettyString(), true) } + return ActivityType.values().first { it.name.equals(type.asText(), true) } } override fun processActivity(json: String, type: ActivityType) { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyService.kt b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyService.kt new file mode 100644 index 00000000..34706206 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyService.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.service.signature + +import io.ktor.http.* + +interface HttpSignatureVerifyService { + fun verify(headers:Headers):Boolean +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt new file mode 100644 index 00000000..5f18f09e --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt @@ -0,0 +1,23 @@ +package dev.usbharu.hideout.service.signature + +import dev.usbharu.hideout.plugins.KtorKeyMap +import dev.usbharu.hideout.service.IUserAuthService +import io.ktor.http.* +import tech.barbero.http.message.signing.HttpMessage +import tech.barbero.http.message.signing.SignatureHeaderVerifier + +class HttpSignatureVerifyServiceImpl(private val userAuthService: IUserAuthService) : HttpSignatureVerifyService { + override fun verify(headers: Headers): Boolean { + val build = SignatureHeaderVerifier.builder().keyMap(KtorKeyMap(userAuthService)).build() + return build.verify(object : HttpMessage { + override fun headerValues(name: String?): MutableList { + return name?.let { headers.getAll(it) }?.toMutableList() ?: mutableListOf() + } + + override fun addHeader(name: String?, value: String?) { + TODO() + } + + }) + } +}