Add multi-user MAX authentication and tenant isolation

This commit is contained in:
Курнат Андрей
2026-07-14 07:35:04 +03:00
parent 582f99ed0e
commit 440de7325f
36 changed files with 904 additions and 118 deletions
+108
View File
@@ -0,0 +1,108 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import hashlib
import mimetypes
import os
import re
import shutil
import sqlite3
import uuid
from datetime import UTC, datetime
from pathlib import Path
def main() -> None:
parser = argparse.ArgumentParser(description="Publish a QMAX Android APK to the local Argus data store.")
parser.add_argument("source", type=Path)
parser.add_argument("version")
parser.add_argument("notes")
args = parser.parse_args()
source = args.source.resolve(strict=True)
data_root = Path(os.environ.get("ARGUS_DATA", "/srv/argus-data")).resolve(strict=True)
db_path = data_root / "argus.db"
packages_root = data_root / "Packages"
slug = "qmax"
channel = "stable"
platform = "android"
release_id = str(uuid.uuid4()).upper()
now = datetime.now(UTC).isoformat(timespec="microseconds")
safe_version = re.sub(r"[^a-zA-Z0-9._-]+", "-", args.version).strip("-._")
stored_name = f"{datetime.now(UTC):%Y%m%d%H%M%S}-{safe_version}-{release_id.replace('-', '')}.apk"
stored_relative_path = f"{slug}/{stored_name}"
target_path = packages_root / stored_relative_path
target_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(source, target_path)
size_bytes = target_path.stat().st_size
sha256 = hashlib.sha256(target_path.read_bytes()).hexdigest()
content_type = mimetypes.guess_type(source.name)[0] or "application/vnd.android.package-archive"
connection = sqlite3.connect(db_path)
try:
connection.execute("PRAGMA foreign_keys = ON")
connection.execute("BEGIN")
app_id = connection.execute('SELECT "Id" FROM "Apps" WHERE "Slug" = ?', (slug,)).fetchone()[0]
connection.execute(
'''
UPDATE "Apps"
SET "Name" = ?, "Summary" = ?, "Description" = ?, "RepositoryUrl" = ?,
"HomepageUrl" = ?, "IsListed" = 1, "UpdatedAt" = ?
WHERE "Id" = ?
''',
(
"QMAX",
"Multi-user Android client for MAX through a self-hosted PyMax bridge.",
"QMAX connects multiple Android users to isolated MAX accounts through one self-hosted server and per-user PyMax sessions.",
"https://git.kusoft.xyz/sevenhill/QMAX",
"https://qmax.kusoft.xyz",
now,
app_id,
),
)
duplicate = connection.execute(
'SELECT 1 FROM "Releases" WHERE "CatalogAppId" = ? AND "Version" = ? AND "Channel" = ? AND "Platform" = ?',
(app_id, args.version, channel, platform),
).fetchone()
if duplicate:
raise RuntimeError(f"QMAX {args.version} is already published")
connection.execute(
'''
INSERT INTO "Releases"
("Id", "CatalogAppId", "Version", "Channel", "Platform", "PackageKind",
"OriginalFileName", "StoredRelativePath", "ContentType", "PackageSizeBytes",
"Sha256", "Notes", "PublishedAt")
VALUES (?, ?, ?, ?, ?, 'apk', ?, ?, ?, ?, ?, ?, ?)
''',
(
release_id,
app_id,
args.version,
channel,
platform,
source.name,
stored_relative_path,
content_type,
size_bytes,
sha256,
args.notes,
now,
),
)
connection.commit()
except Exception:
connection.rollback()
target_path.unlink(missing_ok=True)
raise
finally:
connection.close()
print(f"PUBLISHED={args.version}")
print(f"SIZE={size_bytes}")
print(f"SHA256={sha256}")
if __name__ == "__main__":
main()