guanghu-ice-heart/zero-point/core-channel/revive-guard/repo-authorization-guard.py

66 lines
3 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""Fail-closed Forgejo pre-receive gate for Lake Lamp repo-push grants."""
import json
import os
import re
import sys
import time
GRANT_DIR = os.environ.get("REPO_AUTHORIZATION_DIR", "/var/lib/guanghu/repo-authorizations")
PUBLIC_AUTHZ_URL = os.environ.get("LAKE_LAMP_PUBLIC_URL", "https://guanghulab.com/authz").rstrip("/")
def normalize_repo(value):
value = value.strip().lower().removesuffix(".git")
match = re.search(r"(?:gitea-repositories|repositories)/([^/]+/[^/]+)$", value)
if match:
return match.group(1)
# Forgejo's hook environment may expose only the repository name.
# This instance is single-owner and the allowlist below remains authoritative.
if re.fullmatch(r"[a-z0-9._-]+", value):
return f"bingshuo/{value}"
return value
def check(repo, now=None):
now = time.time() if now is None else now
repo = normalize_repo(repo)
if not re.fullmatch(r"bingshuo/[a-z0-9._-]+", repo):
return False, "repository_not_allowlisted"
filename = os.path.join(GRANT_DIR, repo.replace("/", "__") + ".json")
try:
with open(filename, encoding="utf-8") as handle:
grant = json.load(handle)
except (OSError, ValueError):
return False, "repo_push_approval_required"
if grant.get("repo") != repo or grant.get("target") != "JD-FD-PRIMARY":
return False, "repo_push_grant_binding_mismatch"
if now > float(grant.get("expires_at", 0)):
return False, "repo_push_grant_expired"
return True, "ok"
def rejection_message(repo, reason, public_url=None):
repo = normalize_repo(repo)
public_url = (public_url or PUBLIC_AUTHZ_URL).rstrip("/")
return "\n".join([
f"小湖灯推送门已锁定: {reason}",
"[LL-REPO-PUSH-AUTH-REQUIRED] 这不是凭证错误;不要向冰朔索要邮箱、授权码、验证码或密码。",
"从 fifth-domain 仓库根目录执行下面一条命令(把 <CURRENT_PERSONA_ID> 换成本轮已登记人格编号):",
(
"node server-tools/lake-lamp-authz/authorize-repo-push.js "
f"--url {public_url} --persona <CURRENT_PERSONA_ID> --repo {repo}"
),
"命令会创建一张无执行权申请单并打印 REQUEST_URL。把该链接交给冰朔保持命令运行。",
"冰朔打开 REQUEST_URL 后,服务器才向预登记邮箱发送批准邮件;冰朔点击邮件批准链接后,",
"命令会自动领取受限会话、读取并确认导航图,并返回结构化操作回执。许可不是 Git 密码;只有回执显示安全推送接收器 ready 时才按其指令继续。",
"说明: AI 不发送邮件、不需要知道邮箱;公开空工单本身不含任何推送权限。",
])
if __name__ == "__main__":
repo = os.environ.get("FORGEJO_REPO") or os.environ.get("GIT_DIR") or os.getcwd()
ok, reason = check(repo)
if not ok:
print(rejection_message(repo, reason), file=sys.stderr)
sys.exit(1)