From c934bedd443fc3de94a17d68312ac4ed10a0ccfe Mon Sep 17 00:00:00 2001 From: Trysdyn Black Date: Sun, 16 Feb 2025 13:44:33 -0800 Subject: [PATCH 1/3] Comment config files a bit more --- example/ome_management_auth.conf | 2 ++ example/ome_webhook.conf | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/example/ome_management_auth.conf b/example/ome_management_auth.conf index 768e920..ba7ae4c 100644 --- a/example/ome_management_auth.conf +++ b/example/ome_management_auth.conf @@ -1,3 +1,5 @@ [Service] +# These are the api user and password configured in your OvenMediaEngine +# Server.xml Environment="OVENMONITOR_API_USER=apiuser" Environment="OVENMONITOR_API_PASSWORD=apipassword" diff --git a/example/ome_webhook.conf b/example/ome_webhook.conf index c87e1ef..3e2e516 100644 --- a/example/ome_webhook.conf +++ b/example/ome_webhook.conf @@ -1,7 +1,15 @@ [Service] +# These variables are for a Discord webhook, to do stream online/offline +# announcements. Environment="OVENMONITOR_WEBHOOK_URL=FULL WEBHOOK URL" Environment="OVENMONITOR_WEBHOOK_ONLINE=TEXT WHEN STREAM GOES ONLINE" Environment="OVENMONITOR_WEBHOOK_OFFLINE=TEXT WHEN STREAM GOES OFFLINE" Environment="OVENMONITOR_WEBHOOK_NAME=NAME TO ASSIGN TO WEBHOOK BOT" + +# These variables attempt to set the webhook bot above to use a specific avatar +# for each given announcement, based on the stream key that invokes the hook. +# AVATARPATH will be searched for an image named {app}/{stream}.png and use it. +# Otherwise it will use default.png. +# When going offline, offline.png will be used. Environment="OVENMONITOR_WEBHOOK_AVATARPATH=/srv/http/example.com/assets/webhook_avatars" Environment="OVENMONITOR_WEBHOOK_AVATARURL=https://example.com/assets/webhook_avatars" From 4c2c82cfc3f3d1e0d6263b9c0d93e442f28780e4 Mon Sep 17 00:00:00 2001 From: Trysdyn Black Date: Sun, 16 Feb 2025 17:06:35 -0800 Subject: [PATCH 2/3] Add access key gating to incoming streams For the moment this is a singleton. One access key will let you stream to any app or stream key. It's denoted in the form of appending a GET parameter to the URL like `?access_key=foobarbaz` This at least means someone who knows the stream URL (frex to view it) won't also be able to stream. --- admission.py | 19 ++++++++++++++++--- config.py | 2 ++ example/ome_access_control.conf | 6 ++++++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 example/ome_access_control.conf diff --git a/admission.py b/admission.py index 0658a85..002b85a 100644 --- a/admission.py +++ b/admission.py @@ -45,7 +45,7 @@ def webhook_offline() -> None: requests.post(config.WEBHOOK_URL, timeout=10, json=data, headers=config.WEBHOOK_HEADERS) -def check_authorized(host, app, stream, source) -> bool: +def check_authorized(host, app, stream, source, access_key) -> bool: # Are we globally disabled? if config.DISABLED: return False @@ -57,7 +57,10 @@ def check_authorized(host, app, stream, source) -> bool: if f"default:{app}:{stream}" in config.DISABLED_KEYS: return False # Finally check the provided vhost app/stream - return f"{host}:{app}:{stream}" not in config.DISABLED_KEYS + if f"{host}:{app}:{stream}" in config.DISABLED_KEYS: + return False + # Check for an access key requirement + return not (config.ACCESS_KEY and access_key != config.ACCESS_KEY) @cherrypy.tools.register("on_end_request") @@ -124,6 +127,16 @@ class Admission: _, _, host, app, path = input_json["request"]["url"].split("/")[:5] stream = path.split("?")[0] + # Tokenize out URL GET parameters + params = {} + if "?" in path: + for pair in path.split("?")[1].split("&"): + if "=" in pair: + k, v = pair.split("=", 1) + params[k] = v + else: + params[pair] = None + # Populate variables for our on_end_request tool into request object cherrypy.request.update_stream = ("default", app, stream) @@ -136,7 +149,7 @@ class Admission: ip = input_json["client"]["real_ip"] # Check if stream is authorized - if not check_authorized(host, app, stream, ip): + if not check_authorized(host, app, stream, ip, params.get("access_key")): cherrypy.log(f"Unauthorized stream key: {app}/{stream}") return {"allowed": False} diff --git a/config.py b/config.py index 0f423f3..084e677 100644 --- a/config.py +++ b/config.py @@ -7,6 +7,8 @@ from pathlib import Path API_USER = os.getenv("OVENMONITOR_API_USER", "") API_PASS = os.getenv("OVENMONITOR_API_PASSWORD", "") +ACCESS_KEY = os.getenv("OVENMONITOR_ACCESS_KEY", "") + WEBHOOK_URL = os.getenv("OVENMONITOR_WEBHOOK_URL", "") WEBHOOK_ONLINE = os.getenv("OVENMONITOR_WEBHOOK_ONLINE", "") WEBHOOK_OFFLINE = os.getenv("OVENMONITOR_WEBHOOK_OFFLINE", "") diff --git a/example/ome_access_control.conf b/example/ome_access_control.conf new file mode 100644 index 0000000..67b63f7 --- /dev/null +++ b/example/ome_access_control.conf @@ -0,0 +1,6 @@ +[Service] +# This is an access key you wish to require in all inbound streams. This must +# be provided as a GET parameter "access_key". For example: +# rtmp://example.org/app/stream?access_key=loginkeyhere +Environment="OVENMONITOR_ACCESS_KEY=loginkeyhere" + From 6bebb69ffa0723ab1d1e4ba95317108fbfa86eb0 Mon Sep 17 00:00:00 2001 From: Trysdyn Black Date: Sun, 16 Feb 2025 17:14:36 -0800 Subject: [PATCH 3/3] Fix throbber in single-player views Fixes #8 --- template/single.mako | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/single.mako b/template/single.mako index 73d9203..33cc46d 100644 --- a/template/single.mako +++ b/template/single.mako @@ -32,7 +32,7 @@ right: 0; top: 0; bottom: 0; - background: url(/assets/errorlogo.gif) no-repeat; + background: url(/assets/errorlogo.gif) 0px/96px no-repeat; z-index: -1; }