aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rwa/support/sessionservice/config.py4
-rwxr-xr-xrwa/support/sessionservice/service.py88
-rw-r--r--rwa/support/sessionservice/session.py3
3 files changed, 88 insertions, 7 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 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)
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/"