#!/usr/bin/env python3 """Generate API key and admin credentials for HexaWetter.""" from __future__ import annotations import argparse import secrets import bcrypt def hash_password(plain_password: str) -> str: return bcrypt.hashpw(plain_password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8") def docker_compose_escape(value: str) -> str: """Escape $ for docker compose .env interpolation ($$ -> literal $).""" return value.replace("$", "$$") def main() -> None: parser = argparse.ArgumentParser(description="Generate HexaWetter security secrets") parser.add_argument("password", nargs="?", help="Admin password (min. 8 characters)") parser.add_argument("--api-key-only", action="store_true", help="Only generate API_KEY") args = parser.parse_args() api_key = secrets.token_urlsafe(32) print("Add these lines to your .env file:\n") print(f"API_KEY={api_key}") print("REQUIRE_API_KEY=true") if args.api_key_only: return if not args.password: raise SystemExit("Admin password required unless --api-key-only is set") if len(args.password) < 8: raise SystemExit("Password must be at least 8 characters") password_hash = hash_password(args.password) jwt_secret = secrets.token_urlsafe(48) print() print("ADMIN_USERNAME=admin") print(f"ADMIN_PASSWORD_HASH={docker_compose_escape(password_hash)}") print(f"ADMIN_JWT_SECRET={jwt_secret}") print("\n# Hinweis: bcrypt-Hashes enthalten $. Fuer docker compose muss jedes $ als $$ escaped sein.") if __name__ == "__main__": main()