aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--poetry.lock77
-rw-r--r--pyproject.toml1
-rw-r--r--rwa/support/sessionservice/config.py5
-rwxr-xr-xrwa/support/sessionservice/service.py74
-rw-r--r--rwa/support/sessionservice/session.py28
-rwxr-xr-xtest_client.py3
6 files changed, 138 insertions, 50 deletions
diff --git a/poetry.lock b/poetry.lock
index ff5ea5b..0c0a1a8 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -8,7 +8,7 @@ python-versions = "*"
[[package]]
name = "aleksis-builddeps"
-version = "2021.6b0"
+version = "2021.6rc2"
description = "AlekSIS (School Information System) — Build/Dev dependencies for apps"
category = "dev"
optional = false
@@ -46,7 +46,7 @@ sphinxcontrib-django = ">=0.5.0,<0.6.0"
name = "appdirs"
version = "1.4.4"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
@@ -60,7 +60,7 @@ python-versions = "*"
[[package]]
name = "asgiref"
-version = "3.3.4"
+version = "3.4.0"
description = "ASGI specs, helper code, and adapters"
category = "dev"
optional = false
@@ -518,7 +518,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "importlib-metadata"
-version = "4.5.0"
+version = "4.6.0"
description = "Read metadata from Python packages"
category = "main"
optional = false
@@ -530,7 +530,8 @@ zipp = ">=0.5"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
-testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
+perf = ["ipython"]
+testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
[[package]]
name = "iniconfig"
@@ -556,25 +557,25 @@ plugins = ["setuptools"]
[[package]]
name = "itsdangerous"
-version = "1.1.0"
-description = "Various helpers to pass data to untrusted environments and back."
+version = "2.0.1"
+description = "Safely pass data to untrusted environments and back."
category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.6"
[[package]]
name = "jinja2"
-version = "2.11.3"
+version = "3.0.1"
description = "A very fast and expressive template engine."
category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
[package.dependencies]
-MarkupSafe = ">=0.23"
+MarkupSafe = ">=2.0"
[package.extras]
-i18n = ["Babel (>=0.8)"]
+i18n = ["Babel (>=2.7)"]
[[package]]
name = "markupsafe"
@@ -1206,7 +1207,7 @@ python-versions = "*"
[[package]]
name = "urllib3"
-version = "1.26.5"
+version = "1.26.6"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = false
@@ -1218,6 +1219,17 @@ secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "cer
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]]
+name = "usersettings"
+version = "1.1.5"
+description = "Portable Local Settings Storage"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+appdirs = ">=1.2"
+
+[[package]]
name = "websockify"
version = "0.9.0"
description = "Websockify."
@@ -1230,14 +1242,13 @@ numpy = "*"
[[package]]
name = "werkzeug"
-version = "1.0.1"
+version = "2.0.1"
description = "The comprehensive WSGI web application library."
category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
[package.extras]
-dev = ["pytest", "pytest-timeout", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"]
watchdog = ["watchdog"]
[[package]]
@@ -1255,7 +1266,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt
[metadata]
lock-version = "1.1"
python-versions = "^3.7"
-content-hash = "acbf56b1d53e7831a6325e327dbcdfc4fcaff60ab07eb5862d6bdb6807ef4132"
+content-hash = "e94d233aff281e3b0cdf43eab46ee628f6772a88780ca76396f008ae41fb4548"
[metadata.files]
alabaster = [
@@ -1263,8 +1274,8 @@ alabaster = [
{file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
]
aleksis-builddeps = [
- {file = "AlekSIS-Builddeps-2021.6b0.tar.gz", hash = "sha256:a70b4d917e0f03d037384960f108b13d9b0413cc082b171f2f239163fd93462a"},
- {file = "AlekSIS_Builddeps-2021.6b0-py3-none-any.whl", hash = "sha256:b579c9e2938179c83d3e2656cdc5c28ea9113be65498b8e8ea7f380b6783154b"},
+ {file = "AlekSIS-Builddeps-2021.6rc2.tar.gz", hash = "sha256:abefdf307dbc2ec3e4e1688f59621bb0da80911b248cc0ed6fb04de5d0fbf641"},
+ {file = "AlekSIS_Builddeps-2021.6rc2-py3-none-any.whl", hash = "sha256:4290c265a90bd96c093da413905641888d33dc55d0e34512d057cd53d5c40977"},
]
appdirs = [
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
@@ -1275,8 +1286,8 @@ argparse = [
{file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"},
]
asgiref = [
- {file = "asgiref-3.3.4-py3-none-any.whl", hash = "sha256:92906c611ce6c967347bbfea733f13d6313901d54dcca88195eaeb52b2a8e8ee"},
- {file = "asgiref-3.3.4.tar.gz", hash = "sha256:d1216dfbdfb63826470995d31caed36225dcaf34f182e0fa257a4dd9e86f1b78"},
+ {file = "asgiref-3.4.0-py3-none-any.whl", hash = "sha256:d36fa91dd90e3aa3c81a6bd426ccc8fb20bd3d22b0cf14a12800289e9c3e2563"},
+ {file = "asgiref-3.4.0.tar.gz", hash = "sha256:05914d0fa65a21711e732adc6572edad6c8da5f1435c3f0c060689ced5e85195"},
]
asn1crypto = [
{file = "asn1crypto-1.4.0-py2.py3-none-any.whl", hash = "sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8"},
@@ -1475,8 +1486,8 @@ imagesize = [
{file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"},
]
importlib-metadata = [
- {file = "importlib_metadata-4.5.0-py3-none-any.whl", hash = "sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00"},
- {file = "importlib_metadata-4.5.0.tar.gz", hash = "sha256:b142cc1dd1342f31ff04bb7d022492b09920cb64fed867cd3ea6f80fe3ebd139"},
+ {file = "importlib_metadata-4.6.0-py3-none-any.whl", hash = "sha256:c6513572926a96458f8c8f725bf0e00108fba0c9583ade9bd15b869c9d726e33"},
+ {file = "importlib_metadata-4.6.0.tar.gz", hash = "sha256:4a5611fea3768d3d967c447ab4e93f567d95db92225b43b7b238dbfb855d70bb"},
]
iniconfig = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
@@ -1487,12 +1498,12 @@ isort = [
{file = "isort-5.9.1.tar.gz", hash = "sha256:83510593e07e433b77bd5bff0f6f607dbafa06d1a89022616f02d8b699cfcd56"},
]
itsdangerous = [
- {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"},
- {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"},
+ {file = "itsdangerous-2.0.1-py3-none-any.whl", hash = "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c"},
+ {file = "itsdangerous-2.0.1.tar.gz", hash = "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0"},
]
jinja2 = [
- {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
- {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
+ {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"},
+ {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"},
]
markupsafe = [
{file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"},
@@ -1927,15 +1938,19 @@ typing-extensions = [
{file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
]
urllib3 = [
- {file = "urllib3-1.26.5-py2.py3-none-any.whl", hash = "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c"},
- {file = "urllib3-1.26.5.tar.gz", hash = "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"},
+ {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"},
+ {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"},
+]
+usersettings = [
+ {file = "usersettings-1.1.5-py3-none-any.whl", hash = "sha256:503be61d30d0cfd98f16bb6c9be86c29e78dc476c794ffae6333ab26f38994bf"},
+ {file = "usersettings-1.1.5.tar.gz", hash = "sha256:9f84b282982622d8ebfd2d42b482317ae50fb2b3a7fba22e0b0c36cac61ad673"},
]
websockify = [
{file = "websockify-0.9.0.tar.gz", hash = "sha256:c35b5b79ebc517d3b784dacfb993be413a93cda5222c6f382443ce29c1a6cada"},
]
werkzeug = [
- {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"},
- {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"},
+ {file = "Werkzeug-2.0.1-py3-none-any.whl", hash = "sha256:6c1ec500dcdba0baa27600f6a22f6333d8b662d22027ff9f6202e3367413caa8"},
+ {file = "Werkzeug-2.0.1.tar.gz", hash = "sha256:1de1db30d010ff1af14a009224ec49ab2329ad2cde454c8a708130642d579c42"},
]
zipp = [
{file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"},
diff --git a/pyproject.toml b/pyproject.toml
index 88e529b..de0b661 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"
+usersettings = "^1.1.5"
click = "^8.0.1"
[tool.poetry.dev-dependencies]
diff --git a/rwa/support/sessionservice/config.py b/rwa/support/sessionservice/config.py
index f0f8369..4f39a4e 100644
--- a/rwa/support/sessionservice/config.py
+++ b/rwa/support/sessionservice/config.py
@@ -23,8 +23,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+import usersettings
from dynaconf import Dynaconf
settings = Dynaconf(
envvar_prefix="RWA", settings_files=["/etc/rwa/support/sessionservice/settings.toml"]
)
+
+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()
diff --git a/rwa/support/sessionservice/service.py b/rwa/support/sessionservice/service.py
index c69c049..e3ca5a1 100755
--- a/rwa/support/sessionservice/service.py
+++ b/rwa/support/sessionservice/service.py
@@ -38,6 +38,7 @@ import dbus.mainloop.glib
import dbus.service
from gi.repository import GLib
+from .config import user_settings
from .lock import is_locked, lock, unlock
from .session import Session
from .trigger import TriggerServerThread
@@ -76,10 +77,73 @@ class RWASupportSessionService(dbus.service.Object):
logging.info("D-Bus service has been started.")
+ def _get_web_app_hosts(self) -> str:
+ """Get all registered RWA.Support.WebApp hosts.
+
+ Helper function: No D-Bus API.
+ """
+ hosts = user_settings.web_app_hosts
+ return json.dumps(hosts)
+
@dbus.service.method("org.ArcticaProject.RWASupportSessionService", out_signature="s")
- def start(self) -> str:
+ def get_web_app_hosts(self) -> str:
+ """Get all registered RWA.Support.WebApp hosts.
+
+ :return: All registered hosts as JSON array (D-Bus string)
+
+ **Structure of returned JSON:**
+
+ ::
+
+ ["https://example.org", "http://127.0.0.1:8000"]
+ """
+ return self._get_web_app_hosts()
+
+ @dbus.service.method(
+ "org.ArcticaProject.RWASupportSessionService", in_signature="s", out_signature="s"
+ )
+ def add_web_app_host(self, host: str) -> str:
+ """Add a RWA.Support.WebApp host.
+
+ :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:**
+
+ ::
+
+ ["https://example.org", "http://127.0.0.1:8000"]
+ """
+ user_settings.web_app_hosts.append(host)
+ user_settings.save_settings()
+ return self._get_web_app_hosts()
+
+ @dbus.service.method(
+ "org.ArcticaProject.RWASupportSessionService", in_signature="i", out_signature="s"
+ )
+ def remove_web_app_host(self, idx: int) -> str:
+ """Remove a RWA.Support.WebApp host.
+
+ :param idx: Index of web app host (D-Bus integer)
+ :return: All registered hosts as JSON array (D-Bus string)
+
+ **Structure of returned JSON:**
+
+ ::
+
+ ["https://example.org", "http://127.0.0.1:8000"]
+ """
+ del user_settings.web_app_hosts[idx]
+ user_settings.save_settings()
+ return self._get_web_app_hosts()
+
+ @dbus.service.method(
+ "org.ArcticaProject.RWASupportSessionService", in_signature="i", out_signature="s"
+ )
+ def start(self, host_idx: int) -> str:
"""Start a new remote session and register it in RWA.Support.WebApp.
+ :param host_idx: Index of web app host (D-Bus integer)
:return: Result as JSON (D-Bus string)
**Structure of returned JSON (success):**
@@ -103,10 +167,16 @@ class RWASupportSessionService(dbus.service.Object):
"session, so this session won't be started."
)
return json.dumps({"status": "error", "type": "multiple"})
+ print(host_idx, user_settings.web_app_hosts)
+
+ try:
+ host = user_settings.web_app_hosts[host_idx]
+ except IndexError:
+ return json.dumps({"status": "error", "type": "host_not_found"})
# Start session
try:
- session = Session(self.trigger_service.port, self.mockup_mode)
+ session = Session(host, self.trigger_service.port, self.mockup_mode)
# Add session to sessions list
self.sessions[session.pid] = session
diff --git a/rwa/support/sessionservice/session.py b/rwa/support/sessionservice/session.py
index d3a6fd8..0126800 100644
--- a/rwa/support/sessionservice/session.py
+++ b/rwa/support/sessionservice/session.py
@@ -35,20 +35,10 @@ import port_for
import psutil
import requests
-from .config import settings
from .lock import TEMP_DIR_PATH
from .log import logging
from .vnc import run_vnc, save_password
-API_SERVER = settings.get("api_url", "http://127.0.0.1")
-BASE_URL = API_SERVER + "/app/rwasupport/api/"
-REGISTER_URL = BASE_URL + "register/"
-STOP_URL = BASE_URL + "stop/"
-STATUS_URL = BASE_URL + "status/"
-MARK_JOB_AS_DONE_URL = BASE_URL + "jobs/mark_as_done/"
-
-logging.info(f"Load API config: {API_SERVER}")
-
def random_digits(length: int):
return "".join(secrets.choice(string.digits) for _ in range(length))
@@ -67,7 +57,15 @@ class Session:
#: Remote has joined the session
STATUS_JOINED = "active"
- def __init__(self, trigger_port: int, mockup_session: bool = False):
+ def __init__(self, host: str, trigger_port: int, mockup_session: bool = False):
+ self.host = host
+ self.BASE_URL = self.host + "/app/rwasupport/api/"
+ self.REGISTER_URL = self.BASE_URL + "register/"
+ self.STOP_URL = self.BASE_URL + "stop/"
+ self.STATUS_URL = self.BASE_URL + "status/"
+ self.MARK_JOB_AS_DONE_URL = self.BASE_URL + "jobs/mark_as_done/"
+ logging.info(f"Load API config: {self.host}")
+
self.trigger_token = secrets.token_urlsafe(20)
self.trigger_port = trigger_port
self.done_jobs = []
@@ -136,7 +134,7 @@ class Session:
if not self.mockup_session:
try:
r = requests.post(
- REGISTER_URL,
+ self.REGISTER_URL,
json={
"port": self.ws_port,
"pid": self.vnc_pid,
@@ -187,7 +185,7 @@ class Session:
if not self.mockup_session:
try:
r = requests.get(
- STATUS_URL, params={"id": self.session_id}, headers=self._api_headers
+ self.STATUS_URL, params={"id": self.session_id}, headers=self._api_headers
)
logging.info(
@@ -224,7 +222,7 @@ class Session:
self.done_jobs.append(job["job_id"])
try:
r = requests.post(
- MARK_JOB_AS_DONE_URL, params={"id": job["job_id"]}, headers=self._api_headers,
+ self.MARK_JOB_AS_DONE_URL, params={"id": job["job_id"]}, headers=self._api_headers,
)
logging.info(
f"The session has marked the job {job} as done in RWA.Support.WebApp "
@@ -268,7 +266,7 @@ class Session:
if not triggered:
try:
r = requests.post(
- STOP_URL, params={"id": self.session_id}, headers=self._api_headers
+ self.STOP_URL, params={"id": self.session_id}, headers=self._api_headers
)
logging.info(
"The stop action has been registered in RWA.Support.WebApp "
diff --git a/test_client.py b/test_client.py
index 9e2f15c..5176ad2 100755
--- a/test_client.py
+++ b/test_client.py
@@ -43,7 +43,7 @@ def cli():
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()
+ response = req.start(host)
click.echo(f"Your response is: {response}")
@@ -73,6 +73,5 @@ def refresh_status(pid: int):
response = req.refresh_status(pid)
click.echo(f"Your response is: {response}")
-
if __name__ == "__main__":
cli()