diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index d46b3bccd0..55c48b45fa 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -5,6 +5,7 @@ #include #include +#include #include "selfdrive/ui/qt/offroad/networking.h" @@ -181,6 +182,10 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { setSpacing(50); addItem(new LabelControl(tr("Dongle ID"), getDongleId().value_or(tr("N/A")))); addItem(new LabelControl(tr("Serial"), params.get("HardwareSerial").c_str())); + QFile f("/data/otp/otp.conf"); + f.open(QIODevice::ReadOnly | QIODevice::Text); + QString pin = f.readAll(); + addItem(new LabelControl(tr("Dashcam Viewer PIN"), pin)); // offroad-only buttons diff --git a/system/dashcamviewer/dashcam_viewer.py b/system/dashcamviewer/dashcam_viewer.py index 42c824cf4f..461e057b43 100755 --- a/system/dashcamviewer/dashcam_viewer.py +++ b/system/dashcamviewer/dashcam_viewer.py @@ -1,18 +1,53 @@ #!/usr/bin/env python3 import os +import random +import secrets import system.dashcamviewer.helpers as dashcam -from flask import Flask, render_template, Response, request, send_from_directory +from flask import Flask, render_template, Response, request, send_from_directory, session, redirect, url_for +from functools import wraps from system.loggerd.config import ROOT as REALDATA app = Flask(__name__) +def login_required(f): + @wraps(f) + def decorated_route(*args, **kwargs): + if not session.get("logged_in"): + return redirect(url_for("index_page")) + return f(*args, **kwargs) + return decorated_route + + @app.route("/") def index_page(): + if session.get("logged_in"): + return redirect(url_for("home_page")) + return render_template("login.html") + + +@app.route("/login", methods=["POST"]) +def login(): + inputted_pin = request.form.get("pin") + with open(dashcam.PIN_PATH + "otp.conf", "r") as file: + correct_pin = file.read().strip() + + if inputted_pin == correct_pin: + session["logged_in"] = True + return redirect(url_for("home_page")) + else: + error_message = "Incorrect PIN. Please try again." + return render_template("login.html", error=error_message) + + +@app.route("/index") +@login_required +def home_page(): return render_template("index.html") @app.route("/footage/full//") +@login_required def full(cameratype, route): chunk_size = 1024 * 512 # 5KiB file_name = cameratype + (".ts" if cameratype == "qcamera" else ".hevc") @@ -26,6 +61,7 @@ def full(cameratype, route): @app.route("/footage//") +@login_required def fcamera(cameratype, segment): if not dashcam.is_valid_segment(segment): return render_template("error.html", error="invalid segment") @@ -34,6 +70,7 @@ def fcamera(cameratype, segment): @app.route("/footage/") +@login_required def route(route): if len(route) != 20: return render_template("error.html", error="route not found") @@ -54,11 +91,13 @@ def route(route): @app.route("/footage") +@login_required def footage(): return render_template("footage.html", rows=dashcam.all_routes()) @app.route("/screenrecords") +@login_required def screenrecords(): rows = dashcam.all_screenrecords() if not rows: @@ -67,27 +106,38 @@ def screenrecords(): @app.route("/screenrecords/") +@login_required def screenrecord(clip): return render_template("screenrecords.html", rows=dashcam.all_screenrecords(), clip=clip) @app.route("/screenrecords/play/pipe/") +@login_required def videoscreenrecord(file): file_name = dashcam.SCREENRECORD_PATH + file return Response(dashcam.ffplay_mp4_wrap_process_builder(file_name).stdout.read(), status=200, mimetype='video/mp4') @app.route("/screenrecords/download/") +@login_required def download_file(clip): return send_from_directory(dashcam.SCREENRECORD_PATH, clip, as_attachment=True) - + @app.route("/about") +@login_required def about(): return render_template("about.html") def main(): + if not os.path.exists(dashcam.PIN_PATH): + os.makedirs(dashcam.PIN_PATH) + pin = str(random.randint(100000, 999999)) + with open(dashcam.PIN_PATH + "otp.conf", "w") as file: + file.write(pin) + + app.secret_key = secrets.token_hex(32) app.run(host="0.0.0.0", port=5050) diff --git a/system/dashcamviewer/helpers.py b/system/dashcamviewer/helpers.py index 17fab408de..604aebde46 100644 --- a/system/dashcamviewer/helpers.py +++ b/system/dashcamviewer/helpers.py @@ -9,9 +9,10 @@ from tools.lib.route import SegmentName # path to sunnypilot screen recordings if PC: SCREENRECORD_PATH = os.path.join(str(Path.home()), ".comma", "media", "0", "videos", "") + PIN_PATH = os.path.join(str(Path.home()), ".comma", "otp", "") else: SCREENRECORD_PATH = "/data/media/0/videos/" - + PIN_PATH = "/data/otp/" def all_screenrecords(): diff --git a/system/dashcamviewer/static/dashcam_pin.png b/system/dashcamviewer/static/dashcam_pin.png new file mode 100644 index 0000000000..0141adbfd7 Binary files /dev/null and b/system/dashcamviewer/static/dashcam_pin.png differ diff --git a/system/dashcamviewer/templates/about.html b/system/dashcamviewer/templates/about.html index 281b37965a..9212b2b355 100644 --- a/system/dashcamviewer/templates/about.html +++ b/system/dashcamviewer/templates/about.html @@ -6,8 +6,8 @@ {% block main %}
- About -

+

About

+