Explorar el Código

Http `post` session injection

ryoii hace 2 años
padre
commit
f47c76d1fc

+ 11 - 1
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/adapter/http/plugin/Authorization.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 Mamoe Technologies and contributors.
+ * Copyright 2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -12,6 +12,8 @@ package net.mamoe.mirai.api.http.adapter.http.plugin
 import io.ktor.server.application.*
 import io.ktor.server.request.*
 import io.ktor.util.*
+import net.mamoe.mirai.api.http.adapter.common.IllegalSessionException
+import net.mamoe.mirai.api.http.adapter.internal.dto.AuthedDTO
 import net.mamoe.mirai.api.http.context.MahContextHolder
 import net.mamoe.mirai.api.http.context.session.Session
 
@@ -30,6 +32,14 @@ val Authorization = createApplicationPlugin("Authorization") {
             }
         }
     }
+
+    on(ReceiveBodyTransformed) { call, body ->
+        if (body is AuthedDTO) {
+            body.session = call.session ?: MahContextHolder[body.sessionKey]
+                    ?: throw IllegalSessionException
+        }
+        body
+    }
 }
 
 val ApplicationCall.session: Session?

+ 13 - 0
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/adapter/http/plugin/hooks.kt

@@ -10,6 +10,7 @@
 package net.mamoe.mirai.api.http.adapter.http.plugin
 
 import io.ktor.server.application.*
+import io.ktor.server.request.*
 
 internal object Monitor : Hook<suspend (ApplicationCall) -> Unit> {
     override fun install(pipeline: ApplicationCallPipeline, handler: suspend (ApplicationCall) -> Unit) {
@@ -18,3 +19,15 @@ internal object Monitor : Hook<suspend (ApplicationCall) -> Unit> {
         }
     }
 }
+
+internal object ReceiveBodyTransformed : Hook<suspend (ApplicationCall, Any) -> Any> {
+    override fun install(
+        pipeline: ApplicationCallPipeline,
+        handler: suspend (call: ApplicationCall, state: Any) -> Any
+    ) {
+        pipeline.receivePipeline.intercept(ApplicationReceivePipeline.After) {
+            val body = handler(call, it)
+            proceedWith(body)
+        }
+    }
+}

+ 1 - 6
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/adapter/http/router/dsl.kt

@@ -95,12 +95,7 @@ internal inline fun Route.httpBind(path: String, crossinline body: Strategy<Bind
 internal inline fun <reified T : AuthedDTO> Route.httpAuthedPost(
     path: String,
     crossinline body: Strategy<T>
-) = routeWithHandle(path, HttpMethod.Post) {
-    val dto = context.receive<T>()
-
-    getAuthedSession(dto.sessionKey).also { dto.session = it }
-    this.body(dto)
-}
+) = routeWithHandle(path, HttpMethod.Post) { body(context.receive<T>()) }
 
 /**
  * Get,用于获取bot的属性