From 0ee14ff59311838af5d8d96d9ce763169979e9fd Mon Sep 17 00:00:00 2001 From: Daniel Teichmann Date: Thu, 24 Jun 2021 19:41:03 +0200 Subject: Update test_client.py to existing API-features --- test_client.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- tox.ini | 10 ++++---- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/test_client.py b/test_client.py index 850e8d3..deeb67b 100755 --- a/test_client.py +++ b/test_client.py @@ -3,7 +3,7 @@ # This file is part of Remote Support Desktop # https://gitlab.das-netzwerkteam.de/RemoteWebApp/rwa.support.sessionservice # Copyright 2020, 2021 Jonathan Weth -# Copyright 2020 Daniel Teichmann +# Copyright 2020, 2021 Daniel Teichmann # Copyright 2020 Mike Gabriel # SPDX-License-Identifier: GPL-2.0-or-later # @@ -25,11 +25,75 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import argparse +from typing import Union + import dbus -bus = dbus.SessionBus() -time = bus.get_object("org.ArcticaProject.RWASupportSessionService", "/RWASupportSessionService") +def str2bool(v: Union[str, bool, int]) -> bool: + """Return true or false if the given string can be interpreted as a boolean. + + If it fails, raise an exception. + """ + if isinstance(v, bool): + return v + if v.lower() in ("yes", "true", "t", "y", "1", 1): + return True + elif v.lower() in ("no", "false", "f", "n", "0", 0): + return False + else: + raise argparse.ArgumentTypeError("Boolean value expected.") + + +def main(): + parser = argparse.ArgumentParser(description="D-Bus Session Service API test client") + arguments = parser.add_mutually_exclusive_group() + arguments.add_argument( + "-s", + "--start", + const=True, + nargs="?", + default=True, + help="Starts a new support session by calling the D-Bus Session Service (default)", + ) + arguments.add_argument("-x", "--stop", help="Stops , an existing support session.") + arguments.add_argument( + "-r", "--refresh_status", help="Refreshes the status of , an existing support session." + ) + arguments.add_argument( + "-i", "--status", help="Gets the status of , an existing support session." + ) + args = parser.parse_args() + + start = args.start + stop_pid = args.stop + status_pid = args.status + refresh_pid = args.refresh_status + + bus = dbus.SessionBus() + req = bus.get_object("org.ArcticaProject.RWASupportSessionService", "/RWASupportSessionService") + + if stop_pid: + print(f"Sending D-Bus request 'stop': {stop_pid}") + response = req.stop(stop_pid) + print(f"Your response is: {response}") + elif status_pid: + print(f"Sending D-Bus request 'status': {status_pid}") + response = req.status(status_pid) + print(f"Your response is: {response}") + elif refresh_pid: + print(f"Sending D-Bus request 'refresh_status': {refresh_pid}") + response = req.refresh_status(refresh_pid) + print(f"Your response is: {response}") + elif start: + print("Sending D-Bus request 'start'") + response = req.start() + print(f"Your response is: {response}") + else: + print("No valid input!") + return + -curr = time.start() -print("Your VNC session is", curr) +if __name__ == "__main__": + main() diff --git a/tox.ini b/tox.ini index db4d9c2..7bf007e 100644 --- a/tox.ini +++ b/tox.ini @@ -15,9 +15,9 @@ commands = [testenv:lint] commands = - poetry run black --check --diff rwa/ - poetry run isort -c --diff --stdout rwa/ - poetry run flake8 {posargs} rwa/ + poetry run black --check --diff rwa/ test_client.py + poetry run isort -c --diff --stdout rwa/ test_client.py + poetry run flake8 {posargs} rwa/ test_client.py [testenv:security] commands = @@ -34,8 +34,8 @@ commands = poetry run make -C docs/ html {posargs} [testenv:reformat] commands = - poetry run isort rwa/ - poetry run black rwa/ + poetry run isort rwa/ test_client.py + poetry run black rwa/ test_client.py [flake8] max_line_length = 100 -- cgit v1.2.3 From 4b329132854bc4f07bdd70a837e4553c6d106591 Mon Sep 17 00:00:00 2001 From: Jonathan Weth Date: Mon, 28 Jun 2021 11:48:57 +0200 Subject: Rewrite test_client.py using click --- poetry.lock | 36 ++++++++++--------- pyproject.toml | 1 + test_client.py | 109 +++++++++++++++++++++++---------------------------------- 3 files changed, 65 insertions(+), 81 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4b90dfe..ff5ea5b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -166,17 +166,21 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "click" -version = "7.1.2" +version = "8.0.1" description = "Composable command line interface toolkit" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" version = "0.4.4" description = "Cross-platform colored terminal text." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -445,17 +449,17 @@ restructuredtext-lint = "*" [[package]] name = "flask" -version = "1.1.4" +version = "1.1.2" description = "A simple framework for building complex web applications." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] -click = ">=5.1,<8.0" -itsdangerous = ">=0.24,<2.0" -Jinja2 = ">=2.10.1,<3.0" -Werkzeug = ">=0.15,<2.0" +click = ">=5.1" +itsdangerous = ">=0.24" +Jinja2 = ">=2.10.1" +Werkzeug = ">=0.15" [package.extras] dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] @@ -516,7 +520,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" name = "importlib-metadata" version = "4.5.0" description = "Read metadata from Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -1196,7 +1200,7 @@ python-versions = "*" name = "typing-extensions" version = "3.10.0.0" description = "Backported and Experimental Type Hints for Python 3.5+" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -1240,7 +1244,7 @@ watchdog = ["watchdog"] name = "zipp" version = "3.4.1" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -1251,7 +1255,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "b9992b58f505b297a099abda504337cc6a7dae5f0291e63c9ae8da725fda63f3" +content-hash = "acbf56b1d53e7831a6325e327dbcdfc4fcaff60ab07eb5862d6bdb6807ef4132" [metadata.files] alabaster = [ @@ -1307,8 +1311,8 @@ chardet = [ {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, + {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, + {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -1447,8 +1451,8 @@ flake8-rst-docstrings = [ {file = "flake8_rst_docstrings-0.2.3-py3-none-any.whl", hash = "sha256:565bbb391d7e4d0042924102221e9857ad72929cdd305b26501736ec22c1451a"}, ] flask = [ - {file = "Flask-1.1.4-py2.py3-none-any.whl", hash = "sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22"}, - {file = "Flask-1.1.4.tar.gz", hash = "sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196"}, + {file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"}, + {file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"}, ] freezegun = [ {file = "freezegun-1.1.0-py2.py3-none-any.whl", hash = "sha256:2ae695f7eb96c62529f03a038461afe3c692db3465e215355e1bb4b0ab408712"}, diff --git a/pyproject.toml b/pyproject.toml index 2582378..88e529b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ psutil = "^5.7.2" flask = "^1.1.2" argparse = "^1.0.10" dynaconf = "^3.0.0" +click = "^8.0.1" [tool.poetry.dev-dependencies] aleksis-builddeps = "*" diff --git a/test_client.py b/test_client.py index deeb67b..9e2f15c 100755 --- a/test_client.py +++ b/test_client.py @@ -25,75 +25,54 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import argparse -from typing import Union +import click import dbus +bus = dbus.SessionBus() +req = bus.get_object("org.ArcticaProject.RWASupportSessionService", "/RWASupportSessionService") -def str2bool(v: Union[str, bool, int]) -> bool: - """Return true or false if the given string can be interpreted as a boolean. - - If it fails, raise an exception. - """ - if isinstance(v, bool): - return v - if v.lower() in ("yes", "true", "t", "y", "1", 1): - return True - elif v.lower() in ("no", "false", "f", "n", "0", 0): - return False - else: - raise argparse.ArgumentTypeError("Boolean value expected.") - - -def main(): - parser = argparse.ArgumentParser(description="D-Bus Session Service API test client") - arguments = parser.add_mutually_exclusive_group() - arguments.add_argument( - "-s", - "--start", - const=True, - nargs="?", - default=True, - help="Starts a new support session by calling the D-Bus Session Service (default)", - ) - arguments.add_argument("-x", "--stop", help="Stops , an existing support session.") - arguments.add_argument( - "-r", "--refresh_status", help="Refreshes the status of , an existing support session." - ) - arguments.add_argument( - "-i", "--status", help="Gets the status of , an existing support session." - ) - args = parser.parse_args() - - start = args.start - stop_pid = args.stop - status_pid = args.status - refresh_pid = args.refresh_status - - bus = dbus.SessionBus() - req = bus.get_object("org.ArcticaProject.RWASupportSessionService", "/RWASupportSessionService") - - if stop_pid: - print(f"Sending D-Bus request 'stop': {stop_pid}") - response = req.stop(stop_pid) - print(f"Your response is: {response}") - elif status_pid: - print(f"Sending D-Bus request 'status': {status_pid}") - response = req.status(status_pid) - print(f"Your response is: {response}") - elif refresh_pid: - print(f"Sending D-Bus request 'refresh_status': {refresh_pid}") - response = req.refresh_status(refresh_pid) - print(f"Your response is: {response}") - elif start: - print("Sending D-Bus request 'start'") - response = req.start() - print(f"Your response is: {response}") - else: - print("No valid input!") - return + +@click.group() +def cli(): + pass + + +@cli.command() +@click.argument("host") +def start(host: int): + """Start a session on the RWA.Support.WebApp host with index HOST.""" + click.echo(f"Sending D-Bus request 'start': {host}") + response = req.start() + click.echo(f"Your response is: {response}") + + +@cli.command() +@click.argument("pid") +def stop(pid: int): + """Stop the session with the pid PID.""" + click.echo(f"Sending D-Bus request 'stop' with PID {pid}") + response = req.stop(pid) + click.echo(f"Your response is: {response}") + + +@cli.command() +@click.argument("pid") +def status(pid: int): + """Get the status of the session with the pid PID.""" + click.echo(f"Sending D-Bus request 'status' with PID {pid}") + response = req.status(pid) + click.echo(f"Your response is: {response}") + + +@cli.command() +@click.argument("pid") +def refresh_status(pid: int): + """Refresh and get the status of the session with the pid PID.""" + click.echo(f"Sending D-Bus request 'refresh_status' with PID {pid}") + response = req.refresh_status(pid) + click.echo(f"Your response is: {response}") if __name__ == "__main__": - main() + cli() -- cgit v1.2.3 From cc4e3d56a1e8dd3338c1a0efb01e443ff5730521 Mon Sep 17 00:00:00 2001 From: Jonathan Weth Date: Mon, 28 Jun 2021 11:49:22 +0200 Subject: Stop VNC server on request failure --- rwa/support/sessionservice/session.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rwa/support/sessionservice/session.py b/rwa/support/sessionservice/session.py index e603568..cabef5f 100644 --- a/rwa/support/sessionservice/session.py +++ b/rwa/support/sessionservice/session.py @@ -145,6 +145,7 @@ class Session: }, ) except requests.exceptions.ConnectionError: + self.stop(triggered=True) raise ConnectionError() logging.info( @@ -153,6 +154,7 @@ class Session: ) if r.status_code != 200: + self.stop(triggered=True) raise ConnectionError() self.meta = r.json() -- cgit v1.2.3 From d81082efdea8b603914f04b6690d11c28fc8fcf7 Mon Sep 17 00:00:00 2001 From: Jonathan Weth Date: Mon, 28 Jun 2021 11:58:01 +0200 Subject: Use click in Session Service --- rwa/support/sessionservice/service.py | 49 ++++++++++++++--------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/rwa/support/sessionservice/service.py b/rwa/support/sessionservice/service.py index c50da26..3e9900d 100755 --- a/rwa/support/sessionservice/service.py +++ b/rwa/support/sessionservice/service.py @@ -25,7 +25,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import argparse import json import logging import signal @@ -33,6 +32,7 @@ import time from threading import Thread from typing import Union +import click import dbus import dbus.mainloop.glib import dbus.service @@ -284,7 +284,23 @@ def str2bool(v: Union[str, bool, int]) -> bool: raise argparse.ArgumentTypeError("Boolean value expected.") -def main(): +@click.command() +@click.option( + "-m", + "--mockup", + is_flag=True, + default=False, + help="Activates mock up mode. Acts like the real Session Service " + "but don't do changes or call RWA.Support.WebApp.", +) +@click.option( + "-o", + "--once", + is_flag=True, + default=False, + help="Runs as one-time-service. Stops after one session.", +) +def main(mockup, once): # Check for lock file if is_locked(): logging.error("The service is already running.") @@ -293,38 +309,13 @@ def main(): # Create lock file lock() - parser = argparse.ArgumentParser(description="D-Bus Session Service for RWA.Support") - parser.add_argument( - "-m", - "--mockup-mode", - type=str2bool, - nargs="?", - const=True, - default=False, - help="Activates mock up mode. Acts like the real session service " - "but don't do changes or call RWA.", - ) - parser.add_argument( - "-o", - "--one-time", - type=str2bool, - nargs="?", - const=True, - default=False, - help="Runs as one-time-service. Stops after one session.", - ) - - args = parser.parse_args() - mockup_mode = args.mockup_mode - one_time = args.one_time - - if mockup_mode: + if mockup: logging.warning("All API responses are faked and should NOT BE USED IN PRODUCTION!") dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) loop = GLib.MainLoop() - service_object = RWASupportSessionService(loop, mockup_mode, one_time) + service_object = RWASupportSessionService(loop, mockup, once) def signal_handler(sig, frame): logging.info("Service was terminated.") -- cgit v1.2.3