aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rwa/support/sessionservice/config.py4
-rwxr-xr-xrwa/support/sessionservice/service.py102
-rw-r--r--rwa/support/sessionservice/session.py3
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/"