feat: add Nox-API upstream support
This commit is contained in:
@@ -37,6 +37,16 @@ MASK = "***"
|
||||
SECRET_KEYS = {"password", "token", "key", "secret"}
|
||||
|
||||
|
||||
AUTH_CONFIG_ALLOWED_KEYS = {
|
||||
"none": set(),
|
||||
"bearer": {"token"},
|
||||
"nox_token": {"token", "user_id", "new_api_user", "provider"},
|
||||
"api_key": {"key", "header"},
|
||||
"cookie": {"cookie_string", "new_api_user", "user_id", "provider"},
|
||||
"login_password": {"email", "password", "login_path", "username_field", "new_api_user", "user_id"},
|
||||
}
|
||||
|
||||
|
||||
def _group_id(group: dict) -> str:
|
||||
for key in ("id", "group_id", "groupId"):
|
||||
value = group.get(key)
|
||||
@@ -80,6 +90,13 @@ def _mask_auth_config(auth_type: str, cfg: dict) -> dict:
|
||||
return masked
|
||||
|
||||
|
||||
def _normalize_auth_config(auth_type: str, cfg: dict) -> dict:
|
||||
allowed = AUTH_CONFIG_ALLOWED_KEYS.get(auth_type)
|
||||
if allowed is None:
|
||||
return cfg
|
||||
return {k: v for k, v in cfg.items() if k in allowed}
|
||||
|
||||
|
||||
def _extract_plaintext_key(payload: dict[str, Any] | None) -> str:
|
||||
if not isinstance(payload, dict):
|
||||
return ""
|
||||
@@ -319,20 +336,39 @@ def _is_sub2api_upstream(upstream: Upstream) -> bool:
|
||||
return upstream.api_prefix.strip("/") == "api/v1"
|
||||
|
||||
|
||||
def _is_nox_api_upstream(upstream: Upstream) -> bool:
|
||||
auth_config = json.loads(upstream.auth_config_json or "{}")
|
||||
return (
|
||||
upstream.api_prefix.strip("/") == ""
|
||||
and upstream.groups_endpoint == "/api/user/self/groups"
|
||||
and (
|
||||
upstream.auth_type == "nox_token"
|
||||
or auth_config.get("login_path") == "/api/user/login"
|
||||
or bool(auth_config.get("user_id"))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _is_new_api_user_upstream(upstream: Upstream) -> bool:
|
||||
auth_config = json.loads(upstream.auth_config_json or "{}")
|
||||
return (
|
||||
upstream.api_prefix.strip("/") == ""
|
||||
and (
|
||||
upstream.groups_endpoint == "/api/user/self/groups"
|
||||
or auth_config.get("login_path") == "/api/user/login"
|
||||
or bool(auth_config.get("new_api_user"))
|
||||
bool(auth_config.get("new_api_user"))
|
||||
or (
|
||||
upstream.groups_endpoint == "/api/user/self/groups"
|
||||
and auth_config.get("login_path") != "/api/user/login"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _supports_key_generation(upstream: Upstream) -> bool:
|
||||
return _is_sub2api_upstream(upstream) or _is_new_api_user_upstream(upstream)
|
||||
return (
|
||||
_is_sub2api_upstream(upstream)
|
||||
or _is_new_api_user_upstream(upstream)
|
||||
or _is_nox_api_upstream(upstream)
|
||||
)
|
||||
|
||||
|
||||
def _ensure_group_key(
|
||||
@@ -486,7 +522,7 @@ def generate_keys_by_groups(
|
||||
if not u:
|
||||
raise HTTPException(404, "upstream not found")
|
||||
if not _supports_key_generation(u):
|
||||
raise HTTPException(400, "仅支持 Sub2API 或 New-API 普通账号上游生成 Key")
|
||||
raise HTTPException(400, "仅支持 Sub2API、New-API 普通账号或 Nox-API 上游生成 Key")
|
||||
|
||||
# 生成前先对账,清理远端已删除的旧 Key
|
||||
try:
|
||||
@@ -766,7 +802,7 @@ def create_upstream(
|
||||
base_url=body.base_url.rstrip("/"),
|
||||
api_prefix=body.api_prefix,
|
||||
auth_type=body.auth_type,
|
||||
auth_config_json=json.dumps(body.auth_config, ensure_ascii=False),
|
||||
auth_config_json=json.dumps(_normalize_auth_config(body.auth_type, body.auth_config), ensure_ascii=False),
|
||||
rate_endpoint=body.rate_endpoint,
|
||||
groups_endpoint=body.groups_endpoint,
|
||||
enabled=body.enabled,
|
||||
@@ -810,7 +846,8 @@ def update_upstream(
|
||||
for k, v in incoming.items():
|
||||
if v != MASK: # don't overwrite with mask placeholder
|
||||
existing[k] = v
|
||||
u.auth_config_json = json.dumps(existing, ensure_ascii=False)
|
||||
next_auth_type = data.get("auth_type", u.auth_type)
|
||||
u.auth_config_json = json.dumps(_normalize_auth_config(next_auth_type, existing), ensure_ascii=False)
|
||||
if "base_url" in data:
|
||||
data["base_url"] = data["base_url"].rstrip("/")
|
||||
for k, v in data.items():
|
||||
|
||||
Reference in New Issue
Block a user