mirror of https://github.com/usbharu/Hideout.git
feat: ActivityPub関係のルーティングを整備
This commit is contained in:
parent
2e7cecdd13
commit
f02ca9e5b0
|
@ -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)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.usbharu.hideout.exception.ap
|
package dev.usbharu.hideout.exception
|
||||||
|
|
||||||
class JsonParseException : IllegalArgumentException {
|
class JsonParseException : IllegalArgumentException {
|
||||||
constructor() : super()
|
constructor() : super()
|
|
@ -1,15 +1,19 @@
|
||||||
package dev.usbharu.hideout.plugins
|
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.routing.*
|
||||||
import io.ktor.server.response.*
|
|
||||||
import io.ktor.server.plugins.autohead.*
|
import io.ktor.server.plugins.autohead.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
|
|
||||||
fun Application.configureRouting() {
|
fun Application.configureRouting(httpSignatureVerifyService: HttpSignatureVerifyService,activityPubService: ActivityPubService) {
|
||||||
install(AutoHeadResponse)
|
install(AutoHeadResponse)
|
||||||
routing {
|
routing {
|
||||||
get("/") {
|
inbox(httpSignatureVerifyService,activityPubService)
|
||||||
call.respondText("Hello World!")
|
outbox()
|
||||||
}
|
usersAP(activityPubService)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,35 @@
|
||||||
package dev.usbharu.hideout.routing.activitypub
|
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.application.*
|
||||||
|
import io.ktor.server.request.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
fun Routing.inbox(){
|
fun Routing.inbox(httpSignatureVerifyService: HttpSignatureVerifyService,activityPubService: dev.usbharu.hideout.service.activitypub.ActivityPubService){
|
||||||
|
|
||||||
route("/inbox") {
|
route("/inbox") {
|
||||||
get {
|
get {
|
||||||
|
call.respond(HttpStatusCode.MethodNotAllowed)
|
||||||
}
|
}
|
||||||
post {
|
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"){
|
route("/users/{name}/inbox"){
|
||||||
get {
|
get {
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
|
call.respond(HttpStatusCode.MethodNotAllowed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
package dev.usbharu.hideout.routing.activitypub
|
package dev.usbharu.hideout.routing.activitypub
|
||||||
|
|
||||||
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
fun Routing.outbox() {
|
fun Routing.outbox() {
|
||||||
|
|
||||||
route("/outbox") {
|
route("/outbox") {
|
||||||
get {
|
get {
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
route("/users/{name}/outbox"){
|
route("/users/{name}/outbox"){
|
||||||
get {
|
get {
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
package dev.usbharu.hideout.routing.activitypub
|
package dev.usbharu.hideout.routing.activitypub
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.service.activitypub.ActivityPubService
|
||||||
import dev.usbharu.hideout.util.HttpUtil.Activity
|
import dev.usbharu.hideout.util.HttpUtil.Activity
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.request.*
|
import io.ktor.server.request.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
fun Routing.users(){
|
fun Routing.usersAP(activityPubService: ActivityPubService){
|
||||||
route("/users/{name}"){
|
route("/users/{name}"){
|
||||||
createChild(ContentTypeRouteSelector(ContentType.Application.Activity)).handle {
|
createChild(ContentTypeRouteSelector(ContentType.Application.Activity)).handle {
|
||||||
|
val json = call.receiveText()
|
||||||
|
val activityTypes = activityPubService.parseActivity(json)
|
||||||
|
activityPubService.processActivity(json,activityTypes)
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package dev.usbharu.hideout.service.activitypub
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
interface ActivityPubService {
|
interface ActivityPubService {
|
||||||
fun parseActivity(json:String): List<ActivityType>
|
fun parseActivity(json:String): ActivityType
|
||||||
|
|
||||||
fun processActivity(json:String, type: ActivityType)
|
fun processActivity(json:String, type: ActivityType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@ package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode
|
import com.fasterxml.jackson.databind.JsonNode
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.Config
|
||||||
import dev.usbharu.hideout.exception.ap.JsonParseException
|
import dev.usbharu.hideout.exception.JsonParseException
|
||||||
|
|
||||||
class ActivityPubServiceImpl : ActivityPubService {
|
class ActivityPubServiceImpl : ActivityPubService {
|
||||||
override fun parseActivity(json: String): List<ActivityType> {
|
override fun parseActivity(json: String): ActivityType {
|
||||||
val readTree = Config.configData.objectMapper.readTree(json)
|
val readTree = Config.configData.objectMapper.readTree(json)
|
||||||
if (readTree.isObject.not()) {
|
if (readTree.isObject.not()) {
|
||||||
throw JsonParseException("Json is not object.")
|
throw JsonParseException("Json is not object.")
|
||||||
|
@ -13,10 +13,10 @@ class ActivityPubServiceImpl : ActivityPubService {
|
||||||
val type = readTree["type"]
|
val type = readTree["type"]
|
||||||
if (type.isArray) {
|
if (type.isArray) {
|
||||||
return type.mapNotNull { jsonNode: JsonNode ->
|
return type.mapNotNull { jsonNode: JsonNode ->
|
||||||
ActivityType.values().filter { it.name.equals(jsonNode.toPrettyString(), true) }
|
ActivityType.values().firstOrNull { it.name.equals(jsonNode.asText(), true) }
|
||||||
}.flatten()
|
}.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) {
|
override fun processActivity(json: String, type: ActivityType) {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.usbharu.hideout.service.signature
|
||||||
|
|
||||||
|
import io.ktor.http.*
|
||||||
|
|
||||||
|
interface HttpSignatureVerifyService {
|
||||||
|
fun verify(headers:Headers):Boolean
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue