42 lines
1.4 KiB
Python
Executable File
42 lines
1.4 KiB
Python
Executable File
#!/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")
|
|
|
|
|
|
def normalize_repo(value):
|
|
value = value.strip().lower().removesuffix(".git")
|
|
match = re.search(r"(?:gitea-repositories|repositories)/([^/]+/[^/]+)$", value)
|
|
return match.group(1) if match else 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"
|
|
|
|
|
|
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(f"小湖灯推送门已锁定: {reason}。请提交 repo-push 邮件工单。", file=sys.stderr)
|
|
sys.exit(1)
|