mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 01:00:29 +08:00
kvmd-htpasswd
This commit is contained in:
parent
d743b2780a
commit
8ae714ab3c
2
Makefile
2
Makefile
@ -12,7 +12,7 @@ TESTENV_CMD ?= /bin/bash -c " \
|
||||
&& ln -s $(TESTENV_VIDEO) /dev/kvmd-video \
|
||||
&& (losetup -d /dev/kvmd-msd || true) \
|
||||
&& losetup /dev/kvmd-msd /root/loop.img \
|
||||
&& python -m kvmd.apps.kvmd -c /etc/kvmd/kvmd.yaml \
|
||||
&& python -m kvmd.apps.kvmd \
|
||||
"
|
||||
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
admin:$apr1$INC0KeyU$YdLQ9qosXzNVlhxQPUf7A/
|
||||
admin:$apr1$.6mu9N8n$xOuGesr4JZZkdiZo/j318.
|
||||
|
||||
@ -23,8 +23,8 @@ from .yamlconf.loader import load_yaml_file
|
||||
|
||||
|
||||
# =====
|
||||
def init() -> Tuple[argparse.ArgumentParser, List[str], Section]:
|
||||
args_parser = argparse.ArgumentParser(add_help=False)
|
||||
def init(prog: str=sys.argv[0], add_help: bool=True) -> Tuple[argparse.ArgumentParser, List[str], Section]:
|
||||
args_parser = argparse.ArgumentParser(prog=prog, add_help=add_help)
|
||||
args_parser.add_argument("-c", "--config", dest="config_path", default="/etc/kvmd/kvmd.yaml", metavar="<file>")
|
||||
args_parser.add_argument("-o", "--set-options", dest="set_options", default=[], nargs="+")
|
||||
args_parser.add_argument("-m", "--dump-config", dest="dump_config", action="store_true")
|
||||
|
||||
@ -10,7 +10,7 @@ from ... import gpio
|
||||
|
||||
# =====
|
||||
def main() -> None:
|
||||
config = init()[2].kvmd
|
||||
config = init("kvmd-cleanup")[2].kvmd
|
||||
logger = get_logger(0)
|
||||
|
||||
logger.info("Cleaning up ...")
|
||||
|
||||
91
kvmd/apps/htpasswd/__init__.py
Normal file
91
kvmd/apps/htpasswd/__init__.py
Normal file
@ -0,0 +1,91 @@
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import getpass
|
||||
import tempfile
|
||||
import contextlib
|
||||
import argparse
|
||||
|
||||
from typing import Generator
|
||||
|
||||
import passlib.apache
|
||||
|
||||
from ...yamlconf import Section
|
||||
|
||||
from ...application import init
|
||||
|
||||
|
||||
# =====
|
||||
@contextlib.contextmanager
|
||||
def _get_htpasswd_for_write(config: Section) -> Generator[passlib.apache.HtpasswdFile, None, None]:
|
||||
path = config.kvmd.auth.htpasswd
|
||||
(tmp_fd, tmp_path) = tempfile.mkstemp(prefix=".", dir=os.path.dirname(path))
|
||||
try:
|
||||
try:
|
||||
with open(path, "rb") as htpasswd_file:
|
||||
os.write(tmp_fd, htpasswd_file.read())
|
||||
finally:
|
||||
os.close(tmp_fd)
|
||||
htpasswd = passlib.apache.HtpasswdFile(tmp_path)
|
||||
yield htpasswd
|
||||
htpasswd.save()
|
||||
os.rename(tmp_path, path)
|
||||
finally:
|
||||
if os.path.exists(tmp_path):
|
||||
os.remove(tmp_path)
|
||||
|
||||
|
||||
def _valid_user(user: str) -> str:
|
||||
stripped = user.strip()
|
||||
if re.match(r"^[a-z_][a-z0-9_-]*$", stripped):
|
||||
return stripped
|
||||
raise SystemExit("Invalid user %r" % (user))
|
||||
|
||||
|
||||
# ====
|
||||
def _cmd_list(config: Section, _: argparse.Namespace) -> None:
|
||||
for user in passlib.apache.HtpasswdFile(config.kvmd.auth.htpasswd).users():
|
||||
print(user)
|
||||
|
||||
|
||||
def _cmd_set(config: Section, options: argparse.Namespace) -> None:
|
||||
if options.read_stdin:
|
||||
passwd = input()
|
||||
else:
|
||||
passwd = getpass.getpass("Password: ", stream=sys.stderr)
|
||||
if getpass.getpass("Repeat: ", stream=sys.stderr) != passwd:
|
||||
raise SystemExit("Sorry, passwords do not match")
|
||||
with _get_htpasswd_for_write(config) as htpasswd:
|
||||
htpasswd.set_password(options.user, passwd)
|
||||
|
||||
|
||||
def _cmd_delete(config: Section, options: argparse.Namespace) -> None:
|
||||
with _get_htpasswd_for_write(config) as htpasswd:
|
||||
htpasswd.delete(options.user)
|
||||
|
||||
|
||||
# =====
|
||||
def main() -> None:
|
||||
(parent_parser, argv, config) = init(add_help=False)
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="kvmd-htpasswd",
|
||||
description="Manage KVMD users",
|
||||
parents=[parent_parser],
|
||||
)
|
||||
parser.set_defaults(cmd=(lambda *_: parser.print_help()))
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
cmd_list_parser = subparsers.add_parser("list", help="List users")
|
||||
cmd_list_parser.set_defaults(cmd=_cmd_list)
|
||||
|
||||
cmd_set_parser = subparsers.add_parser("set", help="Create user or change password")
|
||||
cmd_set_parser.add_argument("user", type=_valid_user)
|
||||
cmd_set_parser.add_argument("-i", "--read-stdin", action="store_true", help="Read password from stdin")
|
||||
cmd_set_parser.set_defaults(cmd=_cmd_set)
|
||||
|
||||
cmd_delete_parser = subparsers.add_parser("del", help="Delete user")
|
||||
cmd_delete_parser.add_argument("user", type=_valid_user)
|
||||
cmd_delete_parser.set_defaults(cmd=_cmd_delete)
|
||||
|
||||
options = parser.parse_args(argv[1:])
|
||||
options.cmd(config, options)
|
||||
2
kvmd/apps/htpasswd/__main__.py
Normal file
2
kvmd/apps/htpasswd/__main__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from . import main
|
||||
main()
|
||||
@ -17,7 +17,7 @@ from .server import Server
|
||||
|
||||
# =====
|
||||
def main() -> None:
|
||||
config = init()[2].kvmd
|
||||
config = init("kvmd")[2].kvmd
|
||||
with gpio.bcm():
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
|
||||
2
setup.py
2
setup.py
@ -21,6 +21,7 @@ def main() -> None:
|
||||
"kvmd.yamlconf",
|
||||
"kvmd.apps",
|
||||
"kvmd.apps.kvmd",
|
||||
"kvmd.apps.htpasswd",
|
||||
"kvmd.apps.cleanup",
|
||||
],
|
||||
|
||||
@ -31,6 +32,7 @@ def main() -> None:
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"kvmd = kvmd.apps.kvmd:main",
|
||||
"kvmd-htpasswd = kvmd.apps.htpasswd:main",
|
||||
"kvmd-cleanup = kvmd.apps.cleanup:main",
|
||||
],
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user