refactor: rename auth.py to gitea_auth.py and ignore env files
This commit is contained in:
@@ -1,93 +0,0 @@
|
||||
"""Shared authentication and API helper for Gitea scripts.
|
||||
|
||||
Pulls credentials from the macOS keychain via `git credential fill`
|
||||
so no tokens appear on the command line.
|
||||
"""
|
||||
import json
|
||||
import base64
|
||||
import subprocess
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
# Known Gitea instances — shared by all scripts.
|
||||
REMOTES = {
|
||||
"dadeschools": {
|
||||
"host": "gitea.dadeschools.net",
|
||||
"org": "Contractor",
|
||||
"repo": "Timesheet",
|
||||
},
|
||||
"prgs": {
|
||||
"host": "gitea.prgs.cc",
|
||||
"org": "Scaled-Tech-Consulting",
|
||||
"repo": "Timesheet",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_credentials(host):
|
||||
"""Return (user, password) for *host* via ``git credential fill``."""
|
||||
p = subprocess.Popen(
|
||||
["git", "credential", "fill"],
|
||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True,
|
||||
)
|
||||
out, _ = p.communicate(f"protocol=https\nhost={host}\n\n")
|
||||
user = password = ""
|
||||
for line in out.splitlines():
|
||||
if line.startswith("username="):
|
||||
user = line.split("=", 1)[1]
|
||||
elif line.startswith("password="):
|
||||
password = line.split("=", 1)[1]
|
||||
return user, password
|
||||
|
||||
|
||||
def get_auth_header(host):
|
||||
"""Return an ``Authorization: Basic …`` header value for *host*."""
|
||||
user, password = get_credentials(host)
|
||||
if not user or not password:
|
||||
return None
|
||||
token = base64.b64encode(f"{user}:{password}".encode()).decode()
|
||||
return f"Basic {token}"
|
||||
|
||||
|
||||
def resolve_remote(args):
|
||||
"""Given parsed argparse args with --remote/--host/--org/--repo,
|
||||
return (host, org, repo) with overrides applied."""
|
||||
profile = REMOTES[args.remote]
|
||||
host = args.host or profile["host"]
|
||||
org = args.org or profile["org"]
|
||||
repo = args.repo or profile["repo"]
|
||||
return host, org, repo
|
||||
|
||||
|
||||
def add_remote_args(parser):
|
||||
"""Add the standard --remote/--host/--org/--repo arguments to a parser."""
|
||||
parser.add_argument(
|
||||
"--remote", choices=sorted(REMOTES), default="dadeschools",
|
||||
help="Known Gitea instance (default: dadeschools).",
|
||||
)
|
||||
parser.add_argument("--host", help="Override the Gitea host.")
|
||||
parser.add_argument("--org", help="Override the owner/org.")
|
||||
parser.add_argument("--repo", help="Override the repository.")
|
||||
|
||||
|
||||
def api_request(method, url, auth_header, payload=None):
|
||||
"""Make an authenticated JSON request to the Gitea API.
|
||||
|
||||
Returns parsed JSON on success, raises on HTTP errors.
|
||||
"""
|
||||
data = json.dumps(payload).encode("utf-8") if payload is not None else None
|
||||
req = urllib.request.Request(url, data=data, method=method)
|
||||
req.add_header("Authorization", auth_header)
|
||||
req.add_header("Content-Type", "application/json")
|
||||
try:
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
body = resp.read().decode("utf-8")
|
||||
return json.loads(body) if body else None
|
||||
except urllib.error.HTTPError as e:
|
||||
error_body = e.read().decode("utf-8", errors="replace")
|
||||
raise RuntimeError(f"HTTP {e.code}: {error_body}") from e
|
||||
|
||||
|
||||
def repo_api_url(host, org, repo):
|
||||
"""Return the base API URL for a repo: https://host/api/v1/repos/org/repo"""
|
||||
return f"https://{host}/api/v1/repos/{org}/{repo}"
|
||||
Reference in New Issue
Block a user