summaryrefslogtreecommitdiff
path: root/kvmd/apps
diff options
context:
space:
mode:
authorDevaev Maxim <[email protected]>2019-02-10 02:46:38 +0300
committerDevaev Maxim <[email protected]>2019-02-10 02:46:38 +0300
commit8ae714ab3caaa77de94bdafef02548a1b068f41f (patch)
tree3303b3ec50482f6eff33165c531922855f3a2697 /kvmd/apps
parentd743b2780ab686fb216ff68373fa94ebe69a455a (diff)
kvmd-htpasswd
Diffstat (limited to 'kvmd/apps')
-rw-r--r--kvmd/apps/cleanup/__init__.py2
-rw-r--r--kvmd/apps/htpasswd/__init__.py91
-rw-r--r--kvmd/apps/htpasswd/__main__.py2
-rw-r--r--kvmd/apps/kvmd/__init__.py2
4 files changed, 95 insertions, 2 deletions
diff --git a/kvmd/apps/cleanup/__init__.py b/kvmd/apps/cleanup/__init__.py
index 53f46259..281f60cb 100644
--- a/kvmd/apps/cleanup/__init__.py
+++ b/kvmd/apps/cleanup/__init__.py
@@ -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 ...")
diff --git a/kvmd/apps/htpasswd/__init__.py b/kvmd/apps/htpasswd/__init__.py
new file mode 100644
index 00000000..0eaf89f3
--- /dev/null
+++ b/kvmd/apps/htpasswd/__init__.py
@@ -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
+
+
+# =====
+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)
diff --git a/kvmd/apps/htpasswd/__main__.py b/kvmd/apps/htpasswd/__main__.py
new file mode 100644
index 00000000..031df43e
--- /dev/null
+++ b/kvmd/apps/htpasswd/__main__.py
@@ -0,0 +1,2 @@
+from . import main
+main()
diff --git a/kvmd/apps/kvmd/__init__.py b/kvmd/apps/kvmd/__init__.py
index 57844cc5..08dfe0dd 100644
--- a/kvmd/apps/kvmd/__init__.py
+++ b/kvmd/apps/kvmd/__init__.py
@@ -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()