mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 01:00:29 +08:00
htpasswd: split add and set commands
This commit is contained in:
parent
ccbe455ada
commit
30a82efea4
@ -44,7 +44,7 @@ from .. import init
|
||||
# =====
|
||||
def _get_htpasswd_path(config: Section) -> str:
|
||||
if config.kvmd.auth.internal.type != "htpasswd":
|
||||
raise SystemExit(f"Error: KVMD internal auth not using 'htpasswd'"
|
||||
raise SystemExit(f"Error: KVMD internal auth does not use 'htpasswd'"
|
||||
f" (now configured {config.kvmd.auth.internal.type!r})")
|
||||
return config.kvmd.auth.internal.file
|
||||
|
||||
@ -100,20 +100,40 @@ def _cmd_list(config: Section, _: argparse.Namespace) -> None:
|
||||
print(user)
|
||||
|
||||
|
||||
def _cmd_set(config: Section, options: argparse.Namespace) -> None:
|
||||
def _change_user(config: Section, options: argparse.Namespace, create: bool) -> None:
|
||||
with _get_htpasswd_for_write(config) as htpasswd:
|
||||
assert options.user == options.user.strip()
|
||||
assert options.user
|
||||
|
||||
has_user = (options.user in htpasswd.users())
|
||||
if create:
|
||||
if has_user:
|
||||
raise SystemExit(f"The user {options.user!r} is already exists")
|
||||
else:
|
||||
if not has_user:
|
||||
raise SystemExit(f"The user {options.user!r} is not exist")
|
||||
|
||||
if options.read_stdin:
|
||||
passwd = valid_passwd(input())
|
||||
else:
|
||||
passwd = valid_passwd(getpass.getpass("Password: ", stream=sys.stderr))
|
||||
if valid_passwd(getpass.getpass("Repeat: ", stream=sys.stderr)) != passwd:
|
||||
raise SystemExit("Sorry, passwords do not match")
|
||||
|
||||
htpasswd.set_password(options.user, passwd)
|
||||
|
||||
if has_user and not options.quiet:
|
||||
_print_invalidate_tip(True)
|
||||
|
||||
|
||||
def _cmd_add(config: Section, options: argparse.Namespace) -> None:
|
||||
_change_user(config, options, create=True)
|
||||
|
||||
|
||||
def _cmd_set(config: Section, options: argparse.Namespace) -> None:
|
||||
_change_user(config, options, create=False)
|
||||
|
||||
|
||||
def _cmd_delete(config: Section, options: argparse.Namespace) -> None:
|
||||
with _get_htpasswd_for_write(config) as htpasswd:
|
||||
has_user = (options.user in htpasswd.users())
|
||||
@ -141,7 +161,13 @@ def main(argv: (list[str] | None)=None) -> None:
|
||||
sub = subparsers.add_parser("list", help="List users")
|
||||
sub.set_defaults(cmd=_cmd_list)
|
||||
|
||||
sub = subparsers.add_parser("set", help="Create user or change password")
|
||||
sub = subparsers.add_parser("add", help="Add user")
|
||||
sub.add_argument("user", type=valid_user)
|
||||
sub.add_argument("-i", "--read-stdin", action="store_true", help="Read password from stdin")
|
||||
sub.add_argument("-q", "--quiet", action="store_true", help="Don't show invalidation note")
|
||||
sub.set_defaults(cmd=_cmd_add)
|
||||
|
||||
sub = subparsers.add_parser("set", help="Change user's password")
|
||||
sub.add_argument("user", type=valid_user)
|
||||
sub.add_argument("-i", "--read-stdin", action="store_true", help="Read password from stdin")
|
||||
sub.add_argument("-q", "--quiet", action="store_true", help="Don't show invalidation note")
|
||||
|
||||
@ -71,24 +71,32 @@ def test_ok__list(htpasswd: KvmdHtpasswdFile, capsys) -> None: # type: ignore
|
||||
|
||||
|
||||
# =====
|
||||
def test_ok__set_change_stdin(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
def test_ok__set_stdin(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
old_users = set(htpasswd.users())
|
||||
if old_users:
|
||||
assert htpasswd.check_password("admin", _make_passwd("admin"))
|
||||
|
||||
mocker.patch.object(builtins, "input", (lambda: " test "))
|
||||
|
||||
_run_htpasswd(["set", "admin", "--read-stdin"], htpasswd.path)
|
||||
|
||||
with pytest.raises(SystemExit, match="The user 'new' is not exist"):
|
||||
_run_htpasswd(["set", "new", "--read-stdin"], htpasswd.path)
|
||||
|
||||
htpasswd.load(force=True)
|
||||
assert htpasswd.check_password("admin", " test ")
|
||||
assert old_users == set(htpasswd.users())
|
||||
|
||||
|
||||
def test_ok__set_add_stdin(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
def test_ok__add_stdin(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
old_users = set(htpasswd.users())
|
||||
if old_users:
|
||||
mocker.patch.object(builtins, "input", (lambda: " test "))
|
||||
_run_htpasswd(["set", "new", "--read-stdin"], htpasswd.path)
|
||||
|
||||
_run_htpasswd(["add", "new", "--read-stdin"], htpasswd.path)
|
||||
|
||||
with pytest.raises(SystemExit, match="The user 'new' is already exists"):
|
||||
_run_htpasswd(["add", "new", "--read-stdin"], htpasswd.path)
|
||||
|
||||
htpasswd.load(force=True)
|
||||
assert htpasswd.check_password("new", " test ")
|
||||
@ -96,20 +104,24 @@ def test_ok__set_add_stdin(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type:
|
||||
|
||||
|
||||
# =====
|
||||
def test_ok__set_change_getpass(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
def test_ok__set_getpass(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
old_users = set(htpasswd.users())
|
||||
if old_users:
|
||||
assert htpasswd.check_password("admin", _make_passwd("admin"))
|
||||
|
||||
mocker.patch.object(getpass, "getpass", (lambda *_, **__: " test "))
|
||||
|
||||
_run_htpasswd(["set", "admin"], htpasswd.path)
|
||||
|
||||
with pytest.raises(SystemExit, match="The user 'new' is not exist"):
|
||||
_run_htpasswd(["set", "new"], htpasswd.path)
|
||||
|
||||
htpasswd.load(force=True)
|
||||
assert htpasswd.check_password("admin", " test ")
|
||||
assert old_users == set(htpasswd.users())
|
||||
|
||||
|
||||
def test_fail__set_change_getpass(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
def test_fail__set_getpass(htpasswd: KvmdHtpasswdFile, mocker) -> None: # type: ignore
|
||||
old_users = set(htpasswd.users())
|
||||
if old_users:
|
||||
assert htpasswd.check_password("admin", _make_passwd("admin"))
|
||||
@ -152,7 +164,7 @@ def test_ok__del(htpasswd: KvmdHtpasswdFile) -> None:
|
||||
|
||||
# =====
|
||||
def test_fail__not_htpasswd() -> None:
|
||||
with pytest.raises(SystemExit, match="Error: KVMD internal auth not using 'htpasswd'"):
|
||||
with pytest.raises(SystemExit, match="Error: KVMD internal auth does not use 'htpasswd'"):
|
||||
_run_htpasswd(["list"], "", int_type="http")
|
||||
|
||||
|
||||
@ -166,4 +178,4 @@ def test_fail__invalid_passwd(mocker, tmpdir) -> None: # type: ignore
|
||||
open(path, "w").close() # pylint: disable=consider-using-with
|
||||
mocker.patch.object(builtins, "input", (lambda: "\n"))
|
||||
with pytest.raises(SystemExit, match="The argument is not a valid passwd characters"):
|
||||
_run_htpasswd(["set", "admin", "--read-stdin"], path)
|
||||
_run_htpasswd(["add", "admin", "--read-stdin"], path)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user