diff options
Diffstat (limited to 'rwa/support/sessionservice/service.py')
-rwxr-xr-x | rwa/support/sessionservice/service.py | 88 |
1 files changed, 82 insertions, 6 deletions
diff --git a/rwa/support/sessionservice/service.py b/rwa/support/sessionservice/service.py index 52bf627..3305223 100755 --- a/rwa/support/sessionservice/service.py +++ b/rwa/support/sessionservice/service.py @@ -30,21 +30,20 @@ import logging import signal import time from threading import Thread -from typing import Union +from typing import Dict, Union import click import dbus import dbus.mainloop.glib import dbus.service +import requests from gi.repository import GLib -from .config import user_settings +from .config import ALLOW_ONLY_ONE_SESSION, API_PATH, SUPPORTED_API_VERSIONS, user_settings from .lock import is_locked, lock, unlock from .session import Session from .trigger import TriggerServerThread -ALLOW_ONLY_ONE_SESSION = True - class RWASupportSessionService(dbus.service.Object): """D-Bus Session Service for RWA.Support. @@ -99,6 +98,55 @@ class RWASupportSessionService(dbus.service.Object): """ return self._get_web_app_hosts() + def _do_api_handshake(self, host: str) -> Dict[str, str]: + """Contact a RWA.Support.WebApp host and find out API version. + + :param host: The full hostname. + :return: Status information as dictionary. + + **Structure of returned JSON (success):** + + :: + + {"status": "success", "type": "valid_host"} + + **Structure of returned JSON (error):** + + :: + + {"status": "error", "type": "<type>"} + + **Possible choices for error types:** + + * ``connection`` + * ``permission_denied`` + * ``unsupported_server`` + """ + url = host + API_PATH + "handshake/" + logging.info(f"API handshake with {url} ...") + try: + r = requests.post(url) + + except requests.exceptions.ConnectionError: + logging.warning(" resulted in a connection error.") + return {"status": "error", "type": "connection"} + + if not r.ok: + logging.warning(" resulted in a connection error.") + return {"status": "error", "type": "connection"} + + if not r.json()["allowed"]: + logging.warning(" was not permitted.") + return {"status": "error", "type": "permission_denied"} + + if r.json().get("api_version") not in SUPPORTED_API_VERSIONS: + logging.warning(" resulted in a incompatible API version.") + return {"status": "error", "type": "unsupported_server"} + + logging.info(" was successful.") + + return {"status": "success", "type": "valid_host"} + @dbus.service.method( "org.ArcticaProject.RWASupportSessionService", in_signature="s", out_signature="s" ) @@ -108,12 +156,29 @@ class RWASupportSessionService(dbus.service.Object): :param host: Exact hostname of the RWA.Support.WebApp host (D-Bus string) :return: All registered hosts as JSON array (D-Bus string) - **Structure of returned JSON:** + **Structure of returned JSON (success):** :: ["https://example.org", "http://127.0.0.1:8000"] + + **Structure of returned JSON (error):** + + :: + + {"status": "error", "type": "<type>"} + + **Possible choices for error types:** + + * ``connection`` + * ``permission_denied`` + * ``unsupported_server`` """ + # Check host by doing a handshake + res = self._do_api_handshake(host) + if res["status"] == "error": + return json.dumps(res) + user_settings.web_app_hosts.append(host) user_settings.save_settings() return self._get_web_app_hosts() @@ -158,7 +223,13 @@ class RWASupportSessionService(dbus.service.Object): {"status": "error", "type": "<type>"} - **Possible choices for error types:** ``multiple``, ``connection`` + **Possible choices for error types:** + + * ``multiple`` + * ``connection`` + * ``host_not_found`` + * ``permission_denied`` + * ``unsupported_server`` """ if ALLOW_ONLY_ONE_SESSION and len(self.sessions.values()) > 0: logging.warning( @@ -174,6 +245,11 @@ class RWASupportSessionService(dbus.service.Object): except IndexError: return json.dumps({"status": "error", "type": "host_not_found"}) + # Check host by doing a handshake + res = self._do_api_handshake(host) + if res["status"] == "error": + return json.dumps(res) + # Start session try: session = Session(host, self.trigger_service.port, self.mockup_mode) |