🐛 fix cqhttp secret checking #289

This commit is contained in:
yanyongyu 2021-03-20 14:49:58 +08:00
parent 22033e1cfb
commit 2166595e50
11 changed files with 61 additions and 54 deletions

View File

@ -93,7 +93,7 @@ Adapter 类型
* `headers: dict`: 请求头
* `body: Optional[dict]`: 请求数据WebSocket 连接该部分为空
* `body: Optional[bytes]`: 请求数据WebSocket 连接该部分为 None

View File

@ -150,7 +150,7 @@ sidebarDepth: 0
### _async_ `send(event, message, at_sender=False, **kwargs)`
### _async_ `send(event, message, at_sender=False, webhook=None, secret=None, **kwargs)`
* **说明**
@ -171,6 +171,12 @@ sidebarDepth: 0
* `at_sender: bool`: 是否 @ 事件主体
* `webhook: Optional[str]`: 该条消息将调用的 webhook 地址。不传则将使用 sessionWebhook若其也不存在该条消息不发送使用自定义 webhook 时注意你设置的安全方式如加关键词IP地址加签等等。
* `secret: Optional[str]`: 如果你使用自定义的 webhook 地址,推荐使用加签方式对消息进行验证,将 机器人安全设置页面加签一栏下面显示的SEC开头的字符串 传入这个参数即可。
* `**kwargs`: 覆盖默认参数

View File

@ -7,7 +7,7 @@ sidebarDepth: 0
## 事件响应器
该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行 对话 。
该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行对话 。
## `matchers`
@ -202,7 +202,7 @@ sidebarDepth: 0
* **类型**
`Optional[T_ArgsParser]`
`Optional[T_TypeUpdater]`
@ -217,7 +217,7 @@ sidebarDepth: 0
* **类型**
`Optional[T_ArgsParser]`
`Optional[T_PermissionUpdater]`
@ -237,7 +237,7 @@ sidebarDepth: 0
* **类型**
`List[T_Handler]`
`List[Handler]`

View File

@ -121,7 +121,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -162,7 +162,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -206,7 +206,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -247,7 +247,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -288,7 +288,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -335,7 +335,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -382,7 +382,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -429,7 +429,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -481,7 +481,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -538,7 +538,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -590,7 +590,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -767,7 +767,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -808,7 +808,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -852,7 +852,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -893,7 +893,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -934,7 +934,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -981,7 +981,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1028,7 +1028,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1075,7 +1075,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1127,7 +1127,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1184,7 +1184,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1236,7 +1236,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表
* `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次)

View File

@ -72,7 +72,7 @@ class Bot(abc.ABC):
@classmethod
@abc.abstractmethod
async def check_permission(cls, driver: "Driver", connection_type: str,
headers: dict, body: Optional[dict]) -> str:
headers: dict, body: Optional[bytes]) -> str:
"""
:说明:
@ -83,7 +83,7 @@ class Bot(abc.ABC):
* ``driver: Driver``: Driver 对象
* ``connection_type: str``: 连接类型
* ``headers: dict``: 请求头
* ``body: Optional[dict]``: 请求数据WebSocket 连接该部分为
* ``body: Optional[bytes]``: 请求数据WebSocket 连接该部分为 None
:返回:

View File

@ -16,7 +16,7 @@ from typing import List, Optional, Callable
import uvicorn
from pydantic import BaseSettings
from fastapi.responses import Response
from fastapi import Body, status, Request, FastAPI, HTTPException
from fastapi import status, Request, FastAPI, HTTPException
from starlette.websockets import WebSocketDisconnect, WebSocket as FastAPIWebSocket
from nonebot.log import logger
@ -177,11 +177,11 @@ class Driver(BaseDriver):
**kwargs)
@overrides(BaseDriver)
async def _handle_http(self,
adapter: str,
request: Request,
data: dict = Body(...)):
if not isinstance(data, dict):
async def _handle_http(self, adapter: str, request: Request):
data = await request.body()
data_dict = json.loads(data.decode())
if not isinstance(data_dict, dict):
logger.warning("Data received is invalid")
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
@ -208,7 +208,7 @@ class Driver(BaseDriver):
bot = BotClass("http", x_self_id)
asyncio.create_task(bot.handle_message(data))
asyncio.create_task(bot.handle_message(data_dict))
return Response("", 204)
@overrides(BaseDriver)

View File

@ -244,7 +244,7 @@ class Bot(BaseBot):
@classmethod
@overrides(BaseBot)
async def check_permission(cls, driver: "Driver", connection_type: str,
headers: dict, body: Optional[dict]) -> str:
headers: dict, body: Optional[bytes]) -> str:
"""
:说明:
@ -271,14 +271,13 @@ class Bot(BaseBot):
if not x_signature:
log("WARNING", "Missing Signature Header")
raise RequestDenied(401, "Missing Signature")
sig = hmac.new(secret.encode("utf-8"),
json.dumps(body).encode(), "sha1").hexdigest()
sig = hmac.new(secret.encode("utf-8"), body, "sha1").hexdigest()
if x_signature != "sha1=" + sig:
log("WARNING", "Signature Header is invalid")
raise RequestDenied(403, "Signature is invalid")
access_token = cqhttp_config.access_token
if access_token and access_token != token:
if access_token and access_token != token and connection_type == "websocket":
log(
"WARNING", "Authorization Header is invalid"
if token else "Missing Authorization Header")

View File

@ -1,5 +1,4 @@
import hmac
import base64
import json
import urllib.parse
from datetime import datetime
@ -51,7 +50,7 @@ class Bot(BaseBot):
@classmethod
@overrides(BaseBot)
async def check_permission(cls, driver: "Driver", connection_type: str,
headers: dict, body: Optional[dict]) -> str:
headers: dict, body: Optional[bytes]) -> str:
"""
:说明:
@ -81,7 +80,7 @@ class Bot(BaseBot):
raise RequestDenied(403, "Signature is invalid")
else:
log("WARNING", "Ding signature check ignored!")
return body["chatbotUserId"]
return json.loads(body.decode())["chatbotUserId"]
@overrides(BaseBot)
async def handle_message(self, message: dict):

View File

@ -1,7 +1,9 @@
import hmac
from nonebot.utils import logger_wrapper
import hashlib
import base64
import hashlib
from nonebot.utils import logger_wrapper
log = logger_wrapper("DING")

View File

@ -178,7 +178,7 @@ class Bot(BaseBot):
@classmethod
@overrides(BaseBot)
async def check_permission(cls, driver: "Driver", connection_type: str,
headers: dict, body: Optional[dict]) -> str:
headers: dict, body: Optional[bytes]) -> str:
if connection_type == 'ws':
raise RequestDenied(
status_code=501,
@ -224,7 +224,7 @@ class Bot(BaseBot):
\:\:\: danger
由于Mirai的HTTP API特殊性, 该API暂时无法实现
\:\:\:
\:\:\: tip
你可以使用 ``MiraiBot.api`` 中提供的调用方法来代替
\:\:\:
@ -447,7 +447,7 @@ class Bot(BaseBot):
:说明:
使用此方法获取bot接收到的最老消息和最老各类事件
(不会从MiraiApiHttp消息记录中删除)
(不会从MiraiApiHttp消息记录中删除)
:参数:
@ -462,7 +462,7 @@ class Bot(BaseBot):
使用此方法获取bot接收到的最新消息和最新各类事件
(不会从MiraiApiHttp消息记录中删除)
:参数:
* ``count: int``: 获取消息和事件的数量
@ -599,7 +599,7 @@ class Bot(BaseBot):
"""
:说明:
使用此方法使Bot退出群聊
使用此方法使Bot退出群聊
:参数:

View File

@ -116,7 +116,8 @@ class WebsocketBot(Bot):
@classmethod
@overrides(Bot)
async def check_permission(cls, driver: "Driver", connection_type: str,
headers: dict, body: Optional[dict]) -> NoReturn:
headers: dict,
body: Optional[bytes]) -> NoReturn:
raise RequestDenied(
status_code=501,
reason=f'Connection {connection_type} not implented')
@ -127,7 +128,7 @@ class WebsocketBot(Bot):
"""
:说明:
注册该Adapter
注册该Adapter
:参数: