mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 06:15:09 +00:00
* refactor(install): generate the web sudoers rules in one place /etc/sudoers.d/ledmatrix_web was written by two copies of the same allow-list: a heredoc in first_time_install.sh Step 10 and a block of echo lines in scripts/install/configure_web_sudo.sh. They drifted before (safe_pip_install.sh was granted by one only), and a test existed just to catch that. Both now call web_sudoers_rules() from the new scripts/install/lib_sudoers.sh and keep their own validate (visudo -c), install and confirm flows. - first_time_install.sh output is byte-for-byte unchanged, so a device re-running the installer gets "already up to date". If the library is missing, Step 10 keeps the installed file and carries on, the same way it handles rules that fail visudo (an empty file would pass visudo). - configure_web_sudo.sh now writes the installer's layout: same 18 rules, different comments and order. It still leaves out reboot, poweroff and journalctl when they are missing; the library does that for both. The drift test now pins the generator's grants, checks that neither installer writes rules of its own, and runs each installer's call line to check the argument order. Tests that read the rule text now read the library. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(install): detect the web service user in one function first_time_install.sh pasted the same WEB_SERVICE_USER detection block three times (Step 3.1's fallback, the plugin-repos setup and Step 11). The copies were identical apart from comments; they now call detect_web_service_user(), whose body is that block unchanged. Behaviour is the same: the function sets the same global and always returns 0, as the inline if-chain did. Checked on Linux against all three original copies across 13 layouts (installed unit with and without User=, the repo as shipped, each grep branch, template placeholders). The comment notes that the install_web_service.sh / install_service.sh greps no longer match anything, so until Step 8 installs the unit the result is "root". That behaviour is left as it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
3.6 KiB
Bash
Executable File
77 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# The web interface's passwordless-sudo allow-list, /etc/sudoers.d/ledmatrix_web.
|
|
#
|
|
# Sourced by first_time_install.sh (Step 10) and
|
|
# scripts/install/configure_web_sudo.sh. Both used to carry their own copy of
|
|
# these rules, and the copies drifted: one granted safe_pip_install.sh and the
|
|
# other did not. Each caller still owns its own validate (visudo -c) / install /
|
|
# confirm flow; this file only prints the rules.
|
|
#
|
|
# Add or remove a grant here and nowhere else.
|
|
|
|
# web_sudoers_rules WEB_USER PROJECT_ROOT SYSTEMCTL_PATH BASH_PATH REBOOT_PATH POWEROFF_PATH JOURNALCTL_PATH
|
|
#
|
|
# Print the ledmatrix_web sudoers rules to stdout.
|
|
#
|
|
# SYSTEMCTL_PATH and BASH_PATH are required, and the caller must make sure they
|
|
# are not empty: `visudo -c` does not catch every such rule (with an empty
|
|
# BASH_PATH the helper rules still parse, granting the script itself).
|
|
# first_time_install.sh stops on a failed `which`; configure_web_sudo.sh checks
|
|
# them before calling this.
|
|
# REBOOT_PATH, POWEROFF_PATH and JOURNALCTL_PATH are optional: pass "" and
|
|
# their rules are left out.
|
|
web_sudoers_rules() {
|
|
local WEB_USER="${1:-}"
|
|
local PROJECT_ROOT="${2:-}"
|
|
local SYSTEMCTL_PATH="${3:-}"
|
|
local BASH_PATH="${4:-}"
|
|
local REBOOT_PATH="${5:-}"
|
|
local POWEROFF_PATH="${6:-}"
|
|
local JOURNALCTL_PATH="${7:-}"
|
|
|
|
cat << EOF
|
|
# LED Matrix Web Interface passwordless sudo configuration
|
|
# This allows the web interface user to run specific commands without a password
|
|
|
|
# Allow $WEB_USER to run specific commands without a password for the LED Matrix web interface
|
|
EOF
|
|
if [ -n "$REBOOT_PATH" ]; then
|
|
printf '%s\n' "$WEB_USER ALL=(ALL) NOPASSWD: $REBOOT_PATH"
|
|
fi
|
|
if [ -n "$POWEROFF_PATH" ]; then
|
|
printf '%s\n' "$WEB_USER ALL=(ALL) NOPASSWD: $POWEROFF_PATH"
|
|
fi
|
|
cat << EOF
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH start ledmatrix.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH stop ledmatrix.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH restart ledmatrix.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH enable ledmatrix.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH disable ledmatrix.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH status ledmatrix.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH is-active ledmatrix
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH is-active ledmatrix.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH start ledmatrix-web.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH stop ledmatrix-web.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH restart ledmatrix-web.service
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $BASH_PATH $PROJECT_ROOT/scripts/fix_perms/safe_plugin_rm.sh *
|
|
# Install a requirements.txt as root via vetted helper, so packages are visible
|
|
# to root-run ledmatrix.service (not just the web interface's own user).
|
|
$WEB_USER ALL=(ALL) NOPASSWD: $BASH_PATH $PROJECT_ROOT/scripts/fix_perms/safe_pip_install.sh *
|
|
EOF
|
|
if [ -n "$JOURNALCTL_PATH" ]; then
|
|
cat << EOF
|
|
# NOEXEC, because these rules end in a wildcard and journalctl starts a pager
|
|
# when its output is a terminal. From that pager (less) a "!sh" is a root
|
|
# shell -- the standard journalctl escalation. The web interface always passes
|
|
# --no-pager, so nothing here needs it, but the rule cannot require a flag that
|
|
# sits in the middle of the command line. NOEXEC stops the command executing
|
|
# another program at all, which closes the hole without depending on wildcard
|
|
# matching subtleties.
|
|
$WEB_USER ALL=(ALL) NOPASSWD:NOEXEC: $JOURNALCTL_PATH -u ledmatrix.service *
|
|
$WEB_USER ALL=(ALL) NOPASSWD:NOEXEC: $JOURNALCTL_PATH -u ledmatrix *
|
|
$WEB_USER ALL=(ALL) NOPASSWD:NOEXEC: $JOURNALCTL_PATH -t ledmatrix *
|
|
EOF
|
|
fi
|
|
}
|