mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-06-20 11:27:56 +00:00
add auth check and config docs
This commit is contained in:
parent
02ca49f6d0
commit
26c697f5e4
@ -23,10 +23,12 @@ module.exports = {
|
|||||||
|
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
repo: "nonebot/nonebot",
|
repo: "nonebot/nonebot",
|
||||||
|
docsDir: "docs",
|
||||||
|
docsBranch: "dev2",
|
||||||
editLinks: true,
|
editLinks: true,
|
||||||
editLinkText: "在 GitHub 上编辑此页",
|
editLinkText: "在 GitHub 上编辑此页",
|
||||||
docsDir: "docs",
|
|
||||||
lastUpdated: "上次更新",
|
lastUpdated: "上次更新",
|
||||||
|
smoothScroll: true,
|
||||||
nav: [{ text: "API", link: "/api/" }],
|
nav: [{ text: "API", link: "/api/" }],
|
||||||
sidebar: {
|
sidebar: {
|
||||||
"/api/": [
|
"/api/": [
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
# NoneBot.config 模块
|
# 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`
|
## _class_ `Env`
|
||||||
|
|
||||||
@ -29,7 +35,8 @@
|
|||||||
|
|
||||||
NoneBot 主要配置。大小写不敏感。
|
NoneBot 主要配置。大小写不敏感。
|
||||||
|
|
||||||
除了 NoneBot 的配置项外,还可以自行添加配置项到 `.env.{environment}` 文件中。这些配置将会一起带入 `Config` 类中。
|
除了 NoneBot 的配置项外,还可以自行添加配置项到 `.env.{environment}` 文件中。
|
||||||
|
这些配置将会在 json 反序列化后一起带入 `Config` 类中。
|
||||||
|
|
||||||
|
|
||||||
### `driver`
|
### `driver`
|
||||||
@ -90,3 +97,143 @@ NoneBot 的 HTTP 和 WebSocket 服务端监听的端口。
|
|||||||
POST /cqhttp/ HTTP/1.1
|
POST /cqhttp/ HTTP/1.1
|
||||||
Authorization: Bearer kSLuTF2GC2Q4q4ugm3
|
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)
|
future.set_result(result)
|
||||||
|
|
||||||
@classmethod
|
@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()
|
future = asyncio.get_event_loop().create_future()
|
||||||
cls._futures[seq] = future
|
cls._futures[seq] = future
|
||||||
try:
|
try:
|
||||||
@ -137,7 +137,7 @@ class Bot(BaseBot):
|
|||||||
api_root += "/"
|
api_root += "/"
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
if self.config.access_token:
|
if self.config.access_token is not None:
|
||||||
headers["Authorization"] = "Bearer " + self.config.access_token
|
headers["Authorization"] = "Bearer " + self.config.access_token
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -100,7 +115,8 @@ class Config(BaseConfig):
|
|||||||
"""
|
"""
|
||||||
NoneBot 主要配置。大小写不敏感。
|
NoneBot 主要配置。大小写不敏感。
|
||||||
|
|
||||||
除了 NoneBot 的配置项外,还可以自行添加配置项到 ``.env.{environment}`` 文件中。这些配置将会一起带入 ``Config`` 类中。
|
除了 NoneBot 的配置项外,还可以自行添加配置项到 ``.env.{environment}`` 文件中。
|
||||||
|
这些配置将会在 json 反序列化后一起带入 ``Config`` 类中。
|
||||||
"""
|
"""
|
||||||
# nonebot configs
|
# nonebot configs
|
||||||
driver: str = "nonebot.drivers.fastapi"
|
driver: str = "nonebot.drivers.fastapi"
|
||||||
@ -147,15 +163,80 @@ class Config(BaseConfig):
|
|||||||
|
|
||||||
# bot connection configs
|
# bot connection configs
|
||||||
api_root: Dict[str, str] = {}
|
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.
|
api_timeout: Optional[float] = 60.
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[float]``
|
||||||
|
- 默认值: ``60.``
|
||||||
|
- 说明:
|
||||||
|
API 请求超时时间,单位: 秒。
|
||||||
|
"""
|
||||||
access_token: Optional[str] = None
|
access_token: Optional[str] = None
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[str]``
|
||||||
|
- 默认值: ``None``
|
||||||
|
- 说明:
|
||||||
|
API 请求所需密钥,会在调用 API 时在请求头中携带。
|
||||||
|
"""
|
||||||
|
|
||||||
# bot runtime configs
|
# bot runtime configs
|
||||||
superusers: Set[int] = set()
|
superusers: Set[int] = set()
|
||||||
|
"""
|
||||||
|
- 类型: ``Set[int]``
|
||||||
|
- 默认值: ``set()``
|
||||||
|
- 说明:
|
||||||
|
机器人超级用户。
|
||||||
|
- 示例:
|
||||||
|
|
||||||
|
.. code-block:: plain
|
||||||
|
|
||||||
|
SUPER_USERS=[12345789]
|
||||||
|
"""
|
||||||
nickname: Union[str, Set[str]] = ""
|
nickname: Union[str, Set[str]] = ""
|
||||||
|
"""
|
||||||
|
- 类型: ``Union[str, Set[str]]``
|
||||||
|
- 默认值: ``""``
|
||||||
|
- 说明:
|
||||||
|
机器人昵称。
|
||||||
|
"""
|
||||||
command_start: Set[str] = {"/"}
|
command_start: Set[str] = {"/"}
|
||||||
|
"""
|
||||||
|
- 类型: ``Set[str]``
|
||||||
|
- 默认值: ``{"/"}``
|
||||||
|
- 说明:
|
||||||
|
命令的起始标记,用于判断一条消息是不是命令。
|
||||||
|
"""
|
||||||
command_sep: Set[str] = {"."}
|
command_sep: Set[str] = {"."}
|
||||||
|
"""
|
||||||
|
- 类型: ``Set[str]``
|
||||||
|
- 默认值: ``{"."}``
|
||||||
|
- 说明:
|
||||||
|
命令的分隔标记,用于将文本形式的命令切分为元组(实际的命令名)。
|
||||||
|
"""
|
||||||
session_expire_timeout: timedelta = timedelta(minutes=2)
|
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
|
||||||
# custom configs can be assigned during nonebot.init
|
# custom configs can be assigned during nonebot.init
|
||||||
|
@ -5,10 +5,9 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import FastAPI, status
|
from fastapi import FastAPI, status, HTTPException
|
||||||
from fastapi.security import OAuth2PasswordBearer
|
from fastapi import Body, Header, Response, Depends
|
||||||
from starlette.websockets import WebSocketDisconnect
|
from starlette.websockets import WebSocketDisconnect, WebSocket as FastAPIWebSocket
|
||||||
from fastapi import Body, Header, Response, WebSocket as FastAPIWebSocket
|
|
||||||
|
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from nonebot.config import Env, Config
|
from nonebot.config import Env, Config
|
||||||
@ -18,6 +17,18 @@ from nonebot.drivers import BaseDriver, BaseWebSocket
|
|||||||
from nonebot.typing import Union, Optional, Callable, overrides
|
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):
|
class Driver(BaseDriver):
|
||||||
|
|
||||||
def __init__(self, env: Env, config: Config):
|
def __init__(self, env: Env, config: Config):
|
||||||
@ -106,14 +117,18 @@ class Driver(BaseDriver):
|
|||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
async def _handle_http(self,
|
async def _handle_http(
|
||||||
adapter: str,
|
self,
|
||||||
response: Response,
|
adapter: str,
|
||||||
data: dict = Body(...),
|
response: Response,
|
||||||
x_self_id: str = Header(None),
|
data: dict = Body(...),
|
||||||
access_token: str = OAuth2PasswordBearer(
|
x_self_id: str = Header(None),
|
||||||
"/", auto_error=False)):
|
access_token: Optional[str] = Depends(get_auth_bearer)):
|
||||||
# TODO: Check authorization
|
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
|
# Create Bot Object
|
||||||
if adapter in self._adapters:
|
if adapter in self._adapters:
|
||||||
@ -127,15 +142,19 @@ class Driver(BaseDriver):
|
|||||||
return {"status": 200, "message": "success"}
|
return {"status": 200, "message": "success"}
|
||||||
|
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
async def _handle_ws_reverse(self,
|
async def _handle_ws_reverse(
|
||||||
adapter: str,
|
self,
|
||||||
websocket: FastAPIWebSocket,
|
adapter: str,
|
||||||
x_self_id: str = Header(None),
|
websocket: FastAPIWebSocket,
|
||||||
access_token: str = OAuth2PasswordBearer(
|
x_self_id: str = Header(None),
|
||||||
"/", auto_error=False)):
|
access_token: Optional[str] = Depends(get_auth_bearer)):
|
||||||
websocket = WebSocket(websocket)
|
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
|
# Create Bot Object
|
||||||
if adapter == "coolq":
|
if adapter == "coolq":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user