mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-24 00:55:07 +08:00
add auth check and config docs
This commit is contained in:
parent
02ca49f6d0
commit
26c697f5e4
@ -23,10 +23,12 @@ module.exports = {
|
||||
|
||||
themeConfig: {
|
||||
repo: "nonebot/nonebot",
|
||||
docsDir: "docs",
|
||||
docsBranch: "dev2",
|
||||
editLinks: true,
|
||||
editLinkText: "在 GitHub 上编辑此页",
|
||||
docsDir: "docs",
|
||||
lastUpdated: "上次更新",
|
||||
smoothScroll: true,
|
||||
nav: [{ text: "API", link: "/api/" }],
|
||||
sidebar: {
|
||||
"/api/": [
|
||||
|
@ -1,5 +1,11 @@
|
||||
# NoneBot.config 模块
|
||||
|
||||
## 配置
|
||||
|
||||
NoneBot 使用 [pydantic](https://pydantic-docs.helpmanual.io/) 以及 [python-dotenv](https://saurabh-kumar.com/python-dotenv/) 来读取配置。
|
||||
|
||||
配置项需符合特殊格式或 json 序列化格式。详情见 [pydantic Field Type](https://pydantic-docs.helpmanual.io/usage/types/) 文档
|
||||
|
||||
|
||||
## _class_ `Env`
|
||||
|
||||
@ -29,7 +35,8 @@
|
||||
|
||||
NoneBot 主要配置。大小写不敏感。
|
||||
|
||||
除了 NoneBot 的配置项外,还可以自行添加配置项到 `.env.{environment}` 文件中。这些配置将会一起带入 `Config` 类中。
|
||||
除了 NoneBot 的配置项外,还可以自行添加配置项到 `.env.{environment}` 文件中。
|
||||
这些配置将会在 json 反序列化后一起带入 `Config` 类中。
|
||||
|
||||
|
||||
### `driver`
|
||||
@ -90,3 +97,143 @@ NoneBot 的 HTTP 和 WebSocket 服务端监听的端口。
|
||||
POST /cqhttp/ HTTP/1.1
|
||||
Authorization: Bearer kSLuTF2GC2Q4q4ugm3
|
||||
```
|
||||
|
||||
|
||||
### `debug`
|
||||
|
||||
|
||||
* 类型: `bool`
|
||||
|
||||
|
||||
* 默认值: `False`
|
||||
|
||||
|
||||
* 说明:
|
||||
是否以调试模式运行 NoneBot。
|
||||
|
||||
|
||||
### `api_root`
|
||||
|
||||
|
||||
* 类型: `Dict[str, str]`
|
||||
|
||||
|
||||
* 默认值: `{}`
|
||||
|
||||
|
||||
* 说明:
|
||||
以机器人 ID 为键,上报地址为值的字典,环境变量或文件中应使用 json 序列化。
|
||||
|
||||
|
||||
* 示例:
|
||||
|
||||
```plain
|
||||
API_ROOT={"123456": "http://127.0.0.1:5700"}
|
||||
```
|
||||
|
||||
|
||||
### `api_timeout`
|
||||
|
||||
|
||||
* 类型: `Optional[float]`
|
||||
|
||||
|
||||
* 默认值: `60.`
|
||||
|
||||
|
||||
* 说明:
|
||||
API 请求超时时间,单位: 秒。
|
||||
|
||||
|
||||
### `access_token`
|
||||
|
||||
|
||||
* 类型: `Optional[str]`
|
||||
|
||||
|
||||
* 默认值: `None`
|
||||
|
||||
|
||||
* 说明:
|
||||
API 请求所需密钥,会在调用 API 时在请求头中携带。
|
||||
|
||||
|
||||
### `superusers`
|
||||
|
||||
|
||||
* 类型: `Set[int]`
|
||||
|
||||
|
||||
* 默认值: `set()`
|
||||
|
||||
|
||||
* 说明:
|
||||
机器人超级用户。
|
||||
|
||||
|
||||
* 示例:
|
||||
|
||||
```plain
|
||||
SUPER_USERS=[12345789]
|
||||
```
|
||||
|
||||
|
||||
### `nickname`
|
||||
|
||||
|
||||
* 类型: `Union[str, Set[str]]`
|
||||
|
||||
|
||||
* 默认值: `""`
|
||||
|
||||
|
||||
* 说明:
|
||||
机器人昵称。
|
||||
|
||||
|
||||
### `command_start`
|
||||
|
||||
|
||||
* 类型: `Set[str]`
|
||||
|
||||
|
||||
* 默认值: `{"/"}`
|
||||
|
||||
|
||||
* 说明:
|
||||
命令的起始标记,用于判断一条消息是不是命令。
|
||||
|
||||
|
||||
### `command_sep`
|
||||
|
||||
|
||||
* 类型: `Set[str]`
|
||||
|
||||
|
||||
* 默认值: `{"."}`
|
||||
|
||||
|
||||
* 说明:
|
||||
命令的分隔标记,用于将文本形式的命令切分为元组(实际的命令名)。
|
||||
|
||||
|
||||
### `session_expire_timeout`
|
||||
|
||||
|
||||
* 类型: `timedelta`
|
||||
|
||||
|
||||
* 默认值: `timedelta(minutes=2)`
|
||||
|
||||
|
||||
* 说明:
|
||||
等待用户回复的超时时间。
|
||||
|
||||
|
||||
* 示例:
|
||||
|
||||
```plain
|
||||
SESSION_EXPIRE_TIMEOUT=120 # 单位: 秒
|
||||
SESSION_EXPIRE_TIMEOUT=[DD ][HH:MM]SS[.ffffff]
|
||||
SESSION_EXPIRE_TIMEOUT=P[DD]DT[HH]H[MM]M[SS]S # ISO 8601
|
||||
```
|
||||
|
@ -67,7 +67,7 @@ class ResultStore:
|
||||
future.set_result(result)
|
||||
|
||||
@classmethod
|
||||
async def fetch(cls, seq: int, timeout: float) -> Dict[str, Any]:
|
||||
async def fetch(cls, seq: int, timeout: Optional[float]) -> Dict[str, Any]:
|
||||
future = asyncio.get_event_loop().create_future()
|
||||
cls._futures[seq] = future
|
||||
try:
|
||||
@ -137,7 +137,7 @@ class Bot(BaseBot):
|
||||
api_root += "/"
|
||||
|
||||
headers = {}
|
||||
if self.config.access_token:
|
||||
if self.config.access_token is not None:
|
||||
headers["Authorization"] = "Bearer " + self.config.access_token
|
||||
|
||||
try:
|
||||
|
@ -1,5 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
配置
|
||||
====
|
||||
|
||||
NoneBot 使用 `pydantic`_ 以及 `python-dotenv`_ 来读取配置。
|
||||
|
||||
配置项需符合特殊格式或 json 序列化格式。详情见 `pydantic Field Type`_ 文档。
|
||||
|
||||
.. _pydantic:
|
||||
https://pydantic-docs.helpmanual.io/
|
||||
.. _python-dotenv:
|
||||
https://saurabh-kumar.com/python-dotenv/
|
||||
.. _pydantic Field Type:
|
||||
https://pydantic-docs.helpmanual.io/usage/types/
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
@ -100,7 +115,8 @@ class Config(BaseConfig):
|
||||
"""
|
||||
NoneBot 主要配置。大小写不敏感。
|
||||
|
||||
除了 NoneBot 的配置项外,还可以自行添加配置项到 ``.env.{environment}`` 文件中。这些配置将会一起带入 ``Config`` 类中。
|
||||
除了 NoneBot 的配置项外,还可以自行添加配置项到 ``.env.{environment}`` 文件中。
|
||||
这些配置将会在 json 反序列化后一起带入 ``Config`` 类中。
|
||||
"""
|
||||
# nonebot configs
|
||||
driver: str = "nonebot.drivers.fastapi"
|
||||
@ -147,15 +163,80 @@ class Config(BaseConfig):
|
||||
|
||||
# bot connection configs
|
||||
api_root: Dict[str, str] = {}
|
||||
"""
|
||||
- 类型: ``Dict[str, str]``
|
||||
- 默认值: ``{}``
|
||||
- 说明:
|
||||
以机器人 ID 为键,上报地址为值的字典,环境变量或文件中应使用 json 序列化。
|
||||
- 示例:
|
||||
|
||||
.. code-block:: plain
|
||||
|
||||
API_ROOT={"123456": "http://127.0.0.1:5700"}
|
||||
"""
|
||||
api_timeout: Optional[float] = 60.
|
||||
"""
|
||||
- 类型: ``Optional[float]``
|
||||
- 默认值: ``60.``
|
||||
- 说明:
|
||||
API 请求超时时间,单位: 秒。
|
||||
"""
|
||||
access_token: Optional[str] = None
|
||||
"""
|
||||
- 类型: ``Optional[str]``
|
||||
- 默认值: ``None``
|
||||
- 说明:
|
||||
API 请求所需密钥,会在调用 API 时在请求头中携带。
|
||||
"""
|
||||
|
||||
# bot runtime configs
|
||||
superusers: Set[int] = set()
|
||||
"""
|
||||
- 类型: ``Set[int]``
|
||||
- 默认值: ``set()``
|
||||
- 说明:
|
||||
机器人超级用户。
|
||||
- 示例:
|
||||
|
||||
.. code-block:: plain
|
||||
|
||||
SUPER_USERS=[12345789]
|
||||
"""
|
||||
nickname: Union[str, Set[str]] = ""
|
||||
"""
|
||||
- 类型: ``Union[str, Set[str]]``
|
||||
- 默认值: ``""``
|
||||
- 说明:
|
||||
机器人昵称。
|
||||
"""
|
||||
command_start: Set[str] = {"/"}
|
||||
"""
|
||||
- 类型: ``Set[str]``
|
||||
- 默认值: ``{"/"}``
|
||||
- 说明:
|
||||
命令的起始标记,用于判断一条消息是不是命令。
|
||||
"""
|
||||
command_sep: Set[str] = {"."}
|
||||
"""
|
||||
- 类型: ``Set[str]``
|
||||
- 默认值: ``{"."}``
|
||||
- 说明:
|
||||
命令的分隔标记,用于将文本形式的命令切分为元组(实际的命令名)。
|
||||
"""
|
||||
session_expire_timeout: timedelta = timedelta(minutes=2)
|
||||
"""
|
||||
- 类型: ``timedelta``
|
||||
- 默认值: ``timedelta(minutes=2)``
|
||||
- 说明:
|
||||
等待用户回复的超时时间。
|
||||
- 示例:
|
||||
|
||||
.. code-block:: plain
|
||||
|
||||
SESSION_EXPIRE_TIMEOUT=120 # 单位: 秒
|
||||
SESSION_EXPIRE_TIMEOUT=[DD ][HH:MM]SS[.ffffff]
|
||||
SESSION_EXPIRE_TIMEOUT=P[DD]DT[HH]H[MM]M[SS]S # ISO 8601
|
||||
"""
|
||||
|
||||
# custom configs
|
||||
# custom configs can be assigned during nonebot.init
|
||||
|
@ -5,10 +5,9 @@ import json
|
||||
import logging
|
||||
|
||||
import uvicorn
|
||||
from fastapi import FastAPI, status
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
from starlette.websockets import WebSocketDisconnect
|
||||
from fastapi import Body, Header, Response, WebSocket as FastAPIWebSocket
|
||||
from fastapi import FastAPI, status, HTTPException
|
||||
from fastapi import Body, Header, Response, Depends
|
||||
from starlette.websockets import WebSocketDisconnect, WebSocket as FastAPIWebSocket
|
||||
|
||||
from nonebot.log import logger
|
||||
from nonebot.config import Env, Config
|
||||
@ -18,6 +17,18 @@ from nonebot.drivers import BaseDriver, BaseWebSocket
|
||||
from nonebot.typing import Union, Optional, Callable, overrides
|
||||
|
||||
|
||||
def get_auth_bearer(access_token: Optional[str] = Header(
|
||||
None, alias="Authorization")):
|
||||
if not access_token:
|
||||
return None
|
||||
scheme, _, param = access_token.partition(" ")
|
||||
if scheme.lower() != "bearer":
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Not authenticated",
|
||||
headers={"WWW-Authenticate": "Bearer"})
|
||||
return param
|
||||
|
||||
|
||||
class Driver(BaseDriver):
|
||||
|
||||
def __init__(self, env: Env, config: Config):
|
||||
@ -106,14 +117,18 @@ class Driver(BaseDriver):
|
||||
**kwargs)
|
||||
|
||||
@overrides(BaseDriver)
|
||||
async def _handle_http(self,
|
||||
adapter: str,
|
||||
response: Response,
|
||||
data: dict = Body(...),
|
||||
x_self_id: str = Header(None),
|
||||
access_token: str = OAuth2PasswordBearer(
|
||||
"/", auto_error=False)):
|
||||
# TODO: Check authorization
|
||||
async def _handle_http(
|
||||
self,
|
||||
adapter: str,
|
||||
response: Response,
|
||||
data: dict = Body(...),
|
||||
x_self_id: str = Header(None),
|
||||
access_token: Optional[str] = Depends(get_auth_bearer)):
|
||||
secret = self.config.secret
|
||||
if secret is not None and secret != access_token:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Not authenticated",
|
||||
headers={"WWW-Authenticate": "Bearer"})
|
||||
|
||||
# Create Bot Object
|
||||
if adapter in self._adapters:
|
||||
@ -127,15 +142,19 @@ class Driver(BaseDriver):
|
||||
return {"status": 200, "message": "success"}
|
||||
|
||||
@overrides(BaseDriver)
|
||||
async def _handle_ws_reverse(self,
|
||||
adapter: str,
|
||||
websocket: FastAPIWebSocket,
|
||||
x_self_id: str = Header(None),
|
||||
access_token: str = OAuth2PasswordBearer(
|
||||
"/", auto_error=False)):
|
||||
websocket = WebSocket(websocket)
|
||||
async def _handle_ws_reverse(
|
||||
self,
|
||||
adapter: str,
|
||||
websocket: FastAPIWebSocket,
|
||||
x_self_id: str = Header(None),
|
||||
access_token: Optional[str] = Depends(get_auth_bearer)):
|
||||
secret = self.config.secret
|
||||
if secret is not None and secret != access_token:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Not authenticated",
|
||||
headers={"WWW-Authenticate": "Bearer"})
|
||||
|
||||
# TODO: Check authorization
|
||||
websocket = WebSocket(websocket)
|
||||
|
||||
# Create Bot Object
|
||||
if adapter == "coolq":
|
||||
|
Loading…
Reference in New Issue
Block a user