1
1
#!/usr/bin/python3 -bbI
2
# -*- coding: utf-8; lexical-binding: t -*-
4
# Mandos Control - Control or query the Mandos server
6
# Copyright © 2008-2020 Teddy Hogeborn
7
# Copyright © 2008-2020 Björn Påhlsson
2
# -*- after-save-hook: (lambda () (let ((command (if (fboundp 'file-local-name) (file-local-name (buffer-file-name)) (or (file-remote-p (buffer-file-name) 'localname) (buffer-file-name))))) (if (= (progn (if (get-buffer "*Test*") (kill-buffer "*Test*")) (process-file-shell-command (format "%s --check" (shell-quote-argument command)) nil "*Test*")) 0) (let ((w (get-buffer-window "*Test*"))) (if w (delete-window w))) (progn (with-current-buffer "*Test*" (compilation-mode)) (display-buffer "*Test*" '(display-buffer-in-side-window)))))); coding: utf-8 -*-
4
# Mandos Monitor - Control and monitor the Mandos server
6
# Copyright © 2008-2019 Teddy Hogeborn
7
# Copyright © 2008-2019 Björn Påhlsson
9
9
# This file is part of Mandos.
395
395
"""Parse an interval string as documented by Mandos before 1.6.1,
396
396
and return a datetime.timedelta
398
>>> parse_pre_1_6_1_interval("7d") == datetime.timedelta(days=7)
400
>>> parse_pre_1_6_1_interval("60s") == datetime.timedelta(0, 60)
402
>>> parse_pre_1_6_1_interval("60m") == datetime.timedelta(hours=1)
404
>>> parse_pre_1_6_1_interval("24h") == datetime.timedelta(days=1)
406
>>> parse_pre_1_6_1_interval("1w") == datetime.timedelta(days=7)
408
>>> parse_pre_1_6_1_interval("5m 30s") == datetime.timedelta(0, 330)
410
>>> parse_pre_1_6_1_interval("") == datetime.timedelta(0)
398
>>> parse_pre_1_6_1_interval('7d') == datetime.timedelta(days=7)
400
>>> parse_pre_1_6_1_interval('60s') == datetime.timedelta(0, 60)
402
>>> parse_pre_1_6_1_interval('60m') == datetime.timedelta(hours=1)
404
>>> parse_pre_1_6_1_interval('24h') == datetime.timedelta(days=1)
406
>>> parse_pre_1_6_1_interval('1w') == datetime.timedelta(days=7)
408
>>> parse_pre_1_6_1_interval('5m 30s') == datetime.timedelta(0, 330)
410
>>> parse_pre_1_6_1_interval('') == datetime.timedelta(0)
412
412
>>> # Ignore unknown characters, allow any order and repetitions
413
>>> parse_pre_1_6_1_interval("2dxy7zz11y3m5m") == datetime.timedelta(2, 480, 18000)
413
>>> parse_pre_1_6_1_interval('2dxy7zz11y3m5m') == datetime.timedelta(2, 480, 18000)
876
874
{key: properties[key]
877
875
for key in self.all_keywords}
878
876
for properties in clients.values()}
879
print(json.dumps(data, indent=4, separators=(",", ": ")))
877
print(json.dumps(data, indent=4, separators=(',', ': ')))
882
880
class PrintTable(Output):
2439
2437
busname = "se.recompile.Mandos"
2440
2438
client_interface = "se.recompile.Mandos.Client"
2441
2439
command.Approve().run(self.bus.clients, self.bus)
2442
self.assertTrue(self.bus.clients)
2443
2440
for clientpath in self.bus.clients:
2444
2441
self.assertIn(("Approve", busname, clientpath,
2445
2442
client_interface, (True,)), self.bus.calls)
2448
2445
busname = "se.recompile.Mandos"
2449
2446
client_interface = "se.recompile.Mandos.Client"
2450
2447
command.Deny().run(self.bus.clients, self.bus)
2451
self.assertTrue(self.bus.clients)
2452
2448
for clientpath in self.bus.clients:
2453
2449
self.assertIn(("Approve", busname, clientpath,
2454
2450
client_interface, (False,)),
2455
2451
self.bus.calls)
2457
2453
def test_Remove(self):
2458
busname = "se.recompile.Mandos"
2460
server_interface = "se.recompile.Mandos"
2461
orig_clients = self.bus.clients.copy()
2462
2454
command.Remove().run(self.bus.clients, self.bus)
2463
self.assertFalse(self.bus.clients)
2464
for clientpath in orig_clients:
2465
self.assertIn(("RemoveClient", busname,
2466
server_path, server_interface,
2455
for clientpath in self.bus.clients:
2456
self.assertIn(("RemoveClient", dbus_busname,
2457
dbus_server_path, dbus_server_interface,
2467
2458
(clientpath,)), self.bus.calls)
2469
2460
expected_json = {
2672
2663
cmd_args = [() for x in range(len(self.values_to_get))]
2673
2664
values_to_get = self.values_to_get
2674
self.assertTrue(values_to_get)
2675
2665
for value_to_get, cmd_arg in zip(values_to_get, cmd_args):
2676
2666
for clientpath in self.bus.clients:
2677
2667
self.bus.clients[clientpath][self.propname] = (
2679
2669
self.command(*cmd_arg).run(self.bus.clients, self.bus)
2680
self.assertTrue(self.bus.clients)
2681
2670
for clientpath in self.bus.clients:
2682
2671
value = (self.bus.clients[clientpath]
2683
2672
[self.propname])
2742
2731
class TestSetSecretCmd(TestPropertySetterCmd):
2743
2732
command = command.SetSecret
2744
2733
propname = "Secret"
2745
def __init__(self, *args, **kwargs):
2746
self.values_to_set = [io.BytesIO(b""),
2747
io.BytesIO(b"secret\0xyzzy\nbar")]
2748
self.values_to_get = [f.getvalue() for f in
2750
super(TestSetSecretCmd, self).__init__(*args, **kwargs)
2734
values_to_set = [io.BytesIO(b""),
2735
io.BytesIO(b"secret\0xyzzy\nbar")]
2736
values_to_get = [f.getvalue() for f in values_to_set]
2753
2739
class TestSetTimeoutCmd(TestPropertySetterCmd):
2809
def parse_test_args():
2810
# type: () -> argparse.Namespace
2795
def should_only_run_tests():
2811
2796
parser = argparse.ArgumentParser(add_help=False)
2812
parser.add_argument("--check", action="store_true")
2813
parser.add_argument("--prefix", )
2797
parser.add_argument("--check", action='store_true')
2814
2798
args, unknown_args = parser.parse_known_args()
2816
# Remove test options from sys.argv
2799
run_tests = args.check
2801
# Remove --check argument from sys.argv
2817
2802
sys.argv[1:] = unknown_args
2820
2805
# Add all tests from doctest strings
2821
2806
def load_tests(loader, tests, none):
2826
2811
if __name__ == "__main__":
2827
options = parse_test_args()
2830
extra_test_prefix = options.prefix
2831
if extra_test_prefix is not None:
2832
if not (unittest.main(argv=[""], exit=False)
2833
.result.wasSuccessful()):
2835
class ExtraTestLoader(unittest.TestLoader):
2836
testMethodPrefix = extra_test_prefix
2837
# Call using ./scriptname --check [--verbose]
2838
unittest.main(argv=[""], testLoader=ExtraTestLoader())
2840
unittest.main(argv=[""])
2813
if should_only_run_tests():
2814
# Call using ./tdd-python-script --check [--verbose]
2844
2819
logging.shutdown()
2848
# (lambda (&optional extra)
2849
# (if (not (funcall run-tests-in-test-buffer default-directory
2851
# (funcall show-test-buffer-in-test-window)
2852
# (funcall remove-test-window)
2853
# (if extra (message "Extra tests run successfully!"))))
2854
# run-tests-in-test-buffer:
2855
# (lambda (dir &optional extra)
2856
# (with-current-buffer (get-buffer-create "*Test*")
2857
# (setq buffer-read-only nil
2858
# default-directory dir)
2860
# (compilation-mode))
2861
# (let ((inhibit-read-only t))
2862
# (= (process-file-shell-command
2863
# (funcall get-command-line extra)
2864
# nil "*Test*") 0)))
2866
# (lambda (&optional extra)
2867
# (let ((quoted-script
2868
# (shell-quote-argument (funcall get-script-name))))
2870
# (concat "%s --check" (if extra " --prefix=atest" ""))
2874
# (if (fboundp 'file-local-name)
2875
# (file-local-name (buffer-file-name))
2876
# (or (file-remote-p (buffer-file-name) 'localname)
2877
# (buffer-file-name))))
2878
# remove-test-window:
2880
# (let ((test-window (get-buffer-window "*Test*")))
2881
# (if test-window (delete-window test-window))))
2882
# show-test-buffer-in-test-window:
2884
# (when (not (get-buffer-window-list "*Test*"))
2885
# (setq next-error-last-buffer (get-buffer "*Test*"))
2886
# (let* ((side (if (>= (window-width) 146) 'right 'bottom))
2887
# (display-buffer-overriding-action
2888
# `((display-buffer-in-side-window) (side . ,side)
2889
# (window-height . fit-window-to-buffer)
2890
# (window-width . fit-window-to-buffer))))
2891
# (display-buffer "*Test*"))))
2894
# (let* ((run-extra-tests (lambda () (interactive)
2895
# (funcall run-tests t)))
2896
# (inner-keymap `(keymap (116 . ,run-extra-tests))) ; t
2897
# (outer-keymap `(keymap (3 . ,inner-keymap)))) ; C-c
2898
# (setq minor-mode-overriding-map-alist
2899
# (cons `(run-tests . ,outer-keymap)
2900
# minor-mode-overriding-map-alist)))
2901
# (add-hook 'after-save-hook run-tests 90 t))