diff options
Diffstat (limited to 'rwa')
-rw-r--r-- | rwa/support/sessionservice/config.py | 4 | ||||
-rwxr-xr-x | rwa/support/sessionservice/service.py | 102 | ||||
-rw-r--r-- | rwa/support/sessionservice/session.py | 3 |
3 files changed, 95 insertions, 14 deletions
diff --git a/rwa/support/sessionservice/config.py b/rwa/support/sessionservice/config.py index de5518d..7863751 100644 --- a/rwa/support/sessionservice/config.py +++ b/rwa/support/sessionservice/config.py @@ -28,3 +28,7 @@ import usersettings user_settings = usersettings.Settings("org.ArcticaProject.RWASupportSessionService") user_settings.add_setting("web_app_hosts", list, ["http://127.0.0.1:8000"]) user_settings.load_settings() + +SUPPORTED_API_VERSIONS = [1] +API_PATH = "/app/rwasupport/api/" +ALLOW_ONLY_ONE_SESSION = True diff --git a/rwa/support/sessionservice/service.py b/rwa/support/sessionservice/service.py index 23fd660..9f0ad0a 100755 --- a/rwa/support/sessionservice/service.py +++ b/rwa/support/sessionservice/service.py @@ -29,23 +29,22 @@ import json 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 import validators 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 .log import logging 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. @@ -113,6 +112,55 @@ class RWASupportSessionService(dbus.service.Object): logging.debug('Return to D-Bus caller: "%s"', self._get_web_app_hosts()) 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" ) @@ -122,23 +170,42 @@ 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`` + * ``invalid_url`` """ host = str(host) logging.info('D-Bus method call: %s("%s")', "add_web_app_host", host) - if self._is_url(host): - user_settings.save_settings() - user_settings.web_app_hosts.append(host) - logging.debug('Added "%s" to "web_app_hosts" in user_settings', host) - else: + if not self._is_url(host): logging.warning("Given URL is not valid!") logging.debug('Did not add "%s" to "web_app_hosts" in user_settings', host) + return json.dumps({"status": "error", "type": "invalid_url"}) + + res = self._do_api_handshake(host) + if res["status"] == "error": + return json.dumps(res) + + user_settings.save_settings() + user_settings.web_app_hosts.append(host) + logging.debug('Added "%s" to "web_app_hosts" in user_settings', host) + return self._get_web_app_hosts() @dbus.service.method( @@ -192,9 +259,13 @@ class RWASupportSessionService(dbus.service.Object): {"status": "error", "type": "<type>"} - **Possible choices for error types:** ``multiple``, - ``connection``, - ``host_not_found`` + **Possible choices for error types:** + + * ``multiple`` + * ``connection`` + * ``host_not_found`` + * ``permission_denied`` + * ``unsupported_server`` """ logging.info("D-Bus method call: %s(%d)", "start", host_idx) @@ -217,6 +288,11 @@ class RWASupportSessionService(dbus.service.Object): logging.debug("The response to the D-Bus caller: '%s'", response) return response + # 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) diff --git a/rwa/support/sessionservice/session.py b/rwa/support/sessionservice/session.py index 0126800..aa97086 100644 --- a/rwa/support/sessionservice/session.py +++ b/rwa/support/sessionservice/session.py @@ -35,6 +35,7 @@ import port_for import psutil import requests +from .config import API_PATH from .lock import TEMP_DIR_PATH from .log import logging from .vnc import run_vnc, save_password @@ -59,7 +60,7 @@ class Session: def __init__(self, host: str, trigger_port: int, mockup_session: bool = False): self.host = host - self.BASE_URL = self.host + "/app/rwasupport/api/" + self.BASE_URL = self.host + API_PATH self.REGISTER_URL = self.BASE_URL + "register/" self.STOP_URL = self.BASE_URL + "stop/" self.STATUS_URL = self.BASE_URL + "status/" |