Coverage for mcpgateway / utils / hash_password.py: 100%
25 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 03:05 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 03:05 +0000
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3"""Location: ./mcpgateway/utils/hash_password.py
4Copyright 2026
5SPDX-License-Identifier: Apache-2.0
7Generate Argon2id password hashes for emergency admin recovery operations.
8"""
10# Standard
11import argparse
12import asyncio
13import getpass
14import sys
16# First-Party
17from mcpgateway.services.argon2_service import Argon2PasswordService
20async def _generate_hash(password: str) -> str:
21 """Generate an Argon2id hash for a plaintext password.
23 Args:
24 password: Plaintext password.
26 Returns:
27 str: Argon2id encoded hash.
28 """
29 service = Argon2PasswordService()
30 return await service.hash_password_async(password)
33def main() -> int:
34 """Run CLI entrypoint for generating password hashes.
36 Returns:
37 int: Process exit code (`0` success, non-zero on validation failure).
38 """
39 parser = argparse.ArgumentParser(description="Generate an Argon2id password hash for ContextForge users.")
40 parser.add_argument("--password", help="Password value. If omitted, a secure prompt is used.")
41 args = parser.parse_args()
43 password = args.password
44 if not password:
45 password = getpass.getpass("Password: ")
46 confirm = getpass.getpass("Confirm password: ")
47 if password != confirm:
48 print("Passwords do not match.", file=sys.stderr)
49 return 1
51 if not password:
52 print("Password cannot be empty.", file=sys.stderr)
53 return 1
55 password_hash = asyncio.run(_generate_hash(password))
56 print(password_hash)
57 return 0
60if __name__ == "__main__":
61 raise SystemExit(main())