MediaDash/views/remote/__init__.py

98 lines
3.2 KiB
Python

import base64
import hashlib
import io
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.serialization import load_ssh_public_key
from flask import Blueprint, redirect, render_template, request, url_for, Markup, flash
from forms import AddSSHUser
from api import Client
from utils import admin_required
remote_page = Blueprint("remote", __name__, url_prefix="/remote")
def ssh_fingerprint(key):
fp = hashlib.md5(base64.b64decode(key)).hexdigest()
return ":".join(a + b for a, b in zip(fp[::2], fp[1::2]))
@remote_page.route("/stop")
@admin_required
def stop():
c = Client()
session_id = request.args.get("session")
c.jellyfin.stop_session(session_id)
return redirect(url_for("remote.index"))
@remote_page.route("/")
@admin_required
def index():
c = Client()
res = c.ssh.get("/data/.ssh/authorized_keys", io.BytesIO())
res.local.seek(0)
ssh_keys = []
for key in str(res.local.read(), "utf8").splitlines():
disabled = False
if key.startswith("#"):
key = key.lstrip("#").lstrip()
disabled = True
load_ssh_public_key(bytes(key, "utf8"))
key_type, key, name = key.split(None, 2)
ssh_keys.append(
{
"disabled": disabled,
"type": key_type,
"key": key,
"fingerprint": ssh_fingerprint(key),
"name": name,
}
)
key = request.args.get("key")
enabled = request.args.get("enabled")
if not (key is None or enabled is None):
key_file = []
for ssh_key in ssh_keys:
if ssh_key["key"] == key:
ssh_key["disabled"] = enabled == "False"
if ssh_key["disabled"]:
key_file.append("#{type} {key} {name}".format(**ssh_key))
else:
key_file.append("{type} {key} {name}".format(**ssh_key))
buf = io.BytesIO(bytes("\n".join(key_file), "utf8"))
c.ssh.put(buf, "/data/.ssh/authorized_keys", preserve_mode=False)
return redirect(url_for("remote"))
jellyfin = {
"users": c.jellyfin.get_users(),
"sessions": c.jellyfin.sessions(),
"info": c.jellyfin.system_info(),
}
return render_template(
"remote/index.html",
ssh=ssh_keys,
jellyfin=jellyfin)
@remote_page.route("/add", methods=["GET", "POST"])
@admin_required
def add():
form = AddSSHUser()
c = Client()
if form.validate_on_submit():
key = load_ssh_public_key(bytes(form.data["ssh_key"], "utf8"))
rawKeyData = key.public_bytes(
encoding=serialization.Encoding.OpenSSH,
format=serialization.PublicFormat.OpenSSH,
)
passwd = c.add_user(form.data["name"], str(rawKeyData, "utf8"))
flash(
Markup(
"".join(
[
f"<p>Name: <b>{form.data['name']}</b></p>",
f"<p>PW: <b>{passwd}</b></p>",
f"<p>FP: <b>{ssh_fingerprint(rawKeyData.split()[1])}</b></p>",
])))
return render_template("remote/add.html", form=form)