summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/browser.py35
-rw-r--r--backend/helpers.py49
-rw-r--r--backend/main.py49
3 files changed, 94 insertions, 39 deletions
diff --git a/backend/browser.py b/backend/browser.py
index c58a97e5..190f8bd5 100644
--- a/backend/browser.py
+++ b/backend/browser.py
@@ -1,20 +1,22 @@
-from injector import get_tab
+# Full imports
+import json
+
+# Partial imports
+from aiohttp import ClientSession, web
+from asyncio import get_event_loop
+from concurrent.futures import ProcessPoolExecutor
+from hashlib import sha256
+from io import BytesIO
from logging import getLogger
from os import path, rename, listdir
from shutil import rmtree
-from aiohttp import ClientSession, web
-from io import BytesIO
-from zipfile import ZipFile
-from concurrent.futures import ProcessPoolExecutor
-from asyncio import get_event_loop
+from subprocess import call
from time import time
-from hashlib import sha256
-from subprocess import Popen
-from injector import inject_to_tab
-
-import json
+from zipfile import ZipFile
-import helpers
+# Local modules
+from helpers import get_ssl_context, get_user, get_user_group
+from injector import get_tab, inject_to_tab
class PluginInstallContext:
def __init__(self, artifact, name, version, hash) -> None:
@@ -41,8 +43,11 @@ class PluginBrowser:
return False
zip_file = ZipFile(zip)
zip_file.extractall(self.plugin_path)
- Popen(["chown", "-R", "deck:deck", self.plugin_path])
- Popen(["chmod", "-R", "555", self.plugin_path])
+ code_chown = call(["chown", "-R", get_user()+":"+get_user_group(), self.plugin_path])
+ code_chmod = call(["chmod", "-R", "555", self.plugin_path])
+ if code_chown != 0 or code_chmod != 0:
+ logger.error(f"chown/chmod exited with a non-zero exit code (chown: {code_chown}, chmod: {code_chmod})")
+ return False
return True
def find_plugin_folder(self, name):
@@ -83,7 +88,7 @@ class PluginBrowser:
self.log.info(f"Installing {name} (Version: {version})")
async with ClientSession() as client:
self.log.debug(f"Fetching {artifact}")
- res = await client.get(artifact, ssl=helpers.get_ssl_context())
+ res = await client.get(artifact, ssl=get_ssl_context())
if res.status == 200:
self.log.debug("Got 200. Reading...")
data = await res.read()
diff --git a/backend/helpers.py b/backend/helpers.py
index e8c2ce5b..68ac7cb3 100644
--- a/backend/helpers.py
+++ b/backend/helpers.py
@@ -1,11 +1,15 @@
-from aiohttp.web import middleware, Response
-import ssl
import certifi
+import ssl
import uuid
-ssl_ctx = ssl.create_default_context(cafile=certifi.where())
+from subprocess import check_output
+from time import sleep
+# global vars
csrf_token = str(uuid.uuid4())
+ssl_ctx = ssl.create_default_context(cafile=certifi.where())
+user = None
+group = None
def get_ssl_context():
return ssl_ctx
@@ -17,4 +21,41 @@ def get_csrf_token():
async def csrf_middleware(request, handler):
if str(request.method) == "OPTIONS" or request.headers.get('Authentication') == csrf_token or str(request.rel_url) == "/auth/token" or str(request.rel_url).startswith("/plugins/load_main/") or str(request.rel_url).startswith("/static/") or str(request.rel_url).startswith("/legacy/") or str(request.rel_url).startswith("/steam_resource/"):
return await handler(request)
- return Response(text='Forbidden', status='403') \ No newline at end of file
+ return Response(text='Forbidden', status='403')
+
+# Get the user by checking for the first logged in user. As this is run
+# by systemd at startup the process is likely to start before the user
+# logs in, so we will wait here until they are available. Note that
+# other methods such as getenv wont work as there was no $SUDO_USER to
+# start the systemd service.
+def set_user():
+ global user
+ cmd = "who | awk '{print $1}' | sort | head -1"
+ while user == None:
+ name = check_output(cmd, shell=True).decode().strip()
+ if name not in [None, '']:
+ user = name
+ sleep(0.1)
+
+# Get the global user. get_user must be called first.
+def get_user() -> str:
+ global user
+ if user == None:
+ raise ValueError("helpers.get_user method called before user variable was set. Run helpers.set_user first.")
+ return user
+
+# Set the global user group. get_user must be called first
+def set_user_group() -> str:
+ global group
+ global user
+ if user == None:
+ raise ValueError("helpers.set_user_dir method called before user variable was set. Run helpers.set_user first.")
+ if group == None:
+ group = check_output(["id", "-g", "-n", user]).decode().strip()
+
+# Get the group of the global user. set_user_group must be called first.
+def get_user_group() -> str:
+ global group
+ if group == None:
+ raise ValueError("helpers.get_user_group method called before group variable was set. Run helpers.set_user_group first.")
+ return group
diff --git a/backend/main.py b/backend/main.py
index 02cc0d56..4129f5db 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -1,10 +1,35 @@
-from logging import DEBUG, INFO, basicConfig, getLogger
-from os import getenv
+# Full imports
+import aiohttp_cors
+# Partial imports
from aiohttp import ClientSession
+from aiohttp.web import Application, run_app, static, get, Response
+from aiohttp_jinja2 import setup as jinja_setup
+from asyncio import get_event_loop, sleep
+from json import dumps, loads
+from logging import DEBUG, INFO, basicConfig, getLogger
+from os import getenv, path
+from subprocess import call
+
+# local modules
+from browser import PluginBrowser
+from helpers import csrf_middleware, get_csrf_token, get_user, get_user_group, set_user, set_user_group
+from injector import inject_to_tab, tab_has_global_var
+from loader import Loader
+from updater import Updater
+from utilities import Utilities
+# Ensure USER and GROUP vars are set first.
+# TODO: This isn't the best way to do this but supports the current
+# implementation. All the config load and environment setting eventually be
+# moved into init or a config/loader method.
+set_user()
+set_user_group()
+USER = get_user()
+GROUP = get_user_group()
+HOME_PATH = "/home/"+USER
CONFIG = {
- "plugin_path": getenv("PLUGIN_PATH", "/home/deck/homebrew/plugins"),
+ "plugin_path": getenv("PLUGIN_PATH", HOME_PATH+"/homebrew/plugins"),
"chown_plugin_path": getenv("CHOWN_PLUGIN_PATH", "1") == "1",
"server_host": getenv("SERVER_HOST", "127.0.0.1"),
"server_port": int(getenv("SERVER_PORT", "1337")),
@@ -14,26 +39,10 @@ CONFIG = {
basicConfig(level=CONFIG["log_level"], format="[%(module)s][%(levelname)s]: %(message)s")
-from asyncio import get_event_loop, sleep
-from json import dumps, loads
-from os import path
-from subprocess import call
-
-import aiohttp_cors
-from aiohttp.web import Application, run_app, static, get, Response
-from aiohttp_jinja2 import setup as jinja_setup
-
-from browser import PluginBrowser
-from injector import inject_to_tab, tab_has_global_var
-from loader import Loader
-from helpers import csrf_middleware, get_csrf_token
-from utilities import Utilities
-from updater import Updater
-
logger = getLogger("Main")
async def chown_plugin_dir(_):
- code_chown = call(["chown", "-R", "deck:deck", CONFIG["plugin_path"]])
+ code_chown = call(["chown", "-R", USER+":"+GROUP, CONFIG["plugin_path"]])
code_chmod = call(["chmod", "-R", "555", CONFIG["plugin_path"]])
if code_chown != 0 or code_chmod != 0:
logger.error(f"chown/chmod exited with a non-zero exit code (chown: {code_chown}, chmod: {code_chmod})")