feat: ActivityPub関係のルーティングを整備

This commit is contained in:
usbharu 2023-04-05 21:47:29 +09:00
parent 2e7cecdd13
commit f02ca9e5b0
10 changed files with 83 additions and 22 deletions

View File

@ -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)
}

View File

@ -1,4 +1,4 @@
package dev.usbharu.hideout.exception.ap
package dev.usbharu.hideout.exception
class JsonParseException : IllegalArgumentException {
constructor() : super()

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}
}

View File

@ -1,7 +1,7 @@
package dev.usbharu.hideout.service.activitypub
interface ActivityPubService {
fun parseActivity(json:String): List<ActivityType>
fun parseActivity(json:String): ActivityType
fun processActivity(json:String, type: ActivityType)
}

View File

@ -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<ActivityType> {
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) {

View File

@ -0,0 +1,7 @@
package dev.usbharu.hideout.service.signature
import io.ktor.http.*
interface HttpSignatureVerifyService {
fun verify(headers:Headers):Boolean
}

View File

@ -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<String> {
return name?.let { headers.getAll(it) }?.toMutableList() ?: mutableListOf()
}
override fun addHeader(name: String?, value: String?) {
TODO()
}
})
}
}