feat: add show-password CLI subcommand
Adds 'show-password' subcommand to the muxplex CLI that: - Prints 'Auth mode: PAM — no password file used' when MUXPLEX_AUTH is not 'password' and PAM is available - Prints 'Password: <pw>' when a password file exists - Prints guidance to auto-generate when no password file found Also imports load_password and pam_available at module level in cli.py to enable testable patching via muxplex.cli namespace. Tests added: - test_show_password_prints_password_from_file - test_show_password_no_file - test_show_password_pam_mode
This commit is contained in:
@@ -5,10 +5,25 @@ import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from muxplex.auth import load_password, pam_available
|
||||
|
||||
# Module-level path constants (overridable in tests via monkeypatch)
|
||||
_system_service_path = Path("/etc/systemd/system/muxplex.service")
|
||||
|
||||
|
||||
def show_password() -> None:
|
||||
"""Print the current muxplex password or indicate PAM mode."""
|
||||
auth_mode = os.environ.get("MUXPLEX_AUTH", "").lower()
|
||||
if auth_mode != "password" and pam_available():
|
||||
print("Auth mode: PAM — no password file used")
|
||||
return
|
||||
pw = load_password()
|
||||
if pw:
|
||||
print(f"Password: {pw}")
|
||||
else:
|
||||
print("No password file found. Start muxplex to auto-generate one.")
|
||||
|
||||
|
||||
def serve(
|
||||
host: str = "127.0.0.1",
|
||||
port: int = 8088,
|
||||
@@ -101,10 +116,14 @@ def main() -> None:
|
||||
"--system", action="store_true", help="System-wide (requires sudo)"
|
||||
)
|
||||
|
||||
sub.add_parser("show-password", help="Show the current muxplex password")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "install-service":
|
||||
install_service(system=args.system)
|
||||
elif args.command == "show-password":
|
||||
show_password()
|
||||
else:
|
||||
serve(
|
||||
host=args.host, port=args.port, auth=args.auth, session_ttl=args.session_ttl
|
||||
|
||||
@@ -160,6 +160,57 @@ def test_install_service_strips_wsl_mnt_paths_from_environment(tmp_path, monkeyp
|
||||
assert "/usr/bin" in env_line
|
||||
|
||||
|
||||
def test_show_password_prints_password_from_file(tmp_path, monkeypatch, capsys):
|
||||
"""show_password() prints the password when MUXPLEX_AUTH=password and file exists."""
|
||||
from muxplex.cli import show_password
|
||||
|
||||
# Set up fake home with password file
|
||||
fake_home = tmp_path / "home"
|
||||
pw_dir = fake_home / ".config" / "muxplex"
|
||||
pw_dir.mkdir(parents=True)
|
||||
pw_file = pw_dir / "password"
|
||||
pw_file.write_text("my-test-password\n")
|
||||
|
||||
monkeypatch.setattr(Path, "home", staticmethod(lambda: fake_home))
|
||||
monkeypatch.setenv("MUXPLEX_AUTH", "password")
|
||||
|
||||
show_password()
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert "my-test-password" in captured.out
|
||||
|
||||
|
||||
def test_show_password_no_file(tmp_path, monkeypatch, capsys):
|
||||
"""show_password() tells user no file found when in password mode with no file."""
|
||||
from muxplex.cli import show_password
|
||||
|
||||
# Set up fake home WITHOUT password file
|
||||
fake_home = tmp_path / "home"
|
||||
fake_home.mkdir(parents=True)
|
||||
|
||||
monkeypatch.setattr(Path, "home", staticmethod(lambda: fake_home))
|
||||
monkeypatch.setenv("MUXPLEX_AUTH", "password")
|
||||
|
||||
show_password()
|
||||
|
||||
captured = capsys.readouterr()
|
||||
output_lower = captured.out.lower()
|
||||
assert "no password" in output_lower or "not found" in output_lower
|
||||
|
||||
|
||||
def test_show_password_pam_mode(monkeypatch, capsys):
|
||||
"""show_password() reports PAM mode when pam_available() is True and not password mode."""
|
||||
from muxplex.cli import show_password
|
||||
|
||||
monkeypatch.delenv("MUXPLEX_AUTH", raising=False)
|
||||
|
||||
with patch("muxplex.cli.pam_available", return_value=True):
|
||||
show_password()
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert "pam" in captured.out.lower()
|
||||
|
||||
|
||||
def test_dunder_main_calls_main():
|
||||
"""python -m muxplex must call cli.main()."""
|
||||
import importlib.util
|
||||
|
||||
Reference in New Issue
Block a user