#!/bin/bash set -euo pipefail source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" packages="$ROOT/install/omarchy-base.packages" cups_browsed_conf="$ROOT/etc/cups/cups-browsed.conf" cups_files_conf="$ROOT/etc/cups/cups-files.conf" sysusers_conf="$ROOT/etc/sysusers.d/omarchy-cups-browsed.conf" service_dropin="$ROOT/etc/systemd/system/cups-browsed.service.d/10-omarchy.conf" grep -qxF cups-browsed "$packages" || fail "cups-browsed remains in the base package set" grep -qxF cups-pk-helper "$packages" || fail "Polkit printer administration is installed" ! grep -qxF cups-pdf "$packages" || fail "the root CUPS-PDF backend is removed" pass "the base install keeps discovery and replaces CUPS-PDF with Polkit administration" grep -qxF 'CacheDir /var/cache/cups-browsed' "$cups_browsed_conf" || fail "cups-browsed keeps state outside the print-filter cache" grep -qxF 'CreateIPPPrinterQueues Driverless' "$cups_browsed_conf" || fail "automatic queues are limited to driverless IPP printers" grep -qxF 'CreateRemoteCUPSPrinterQueues No' "$cups_browsed_conf" || fail "remote CUPS queues are not created automatically" ! grep -q 'CreateRemotePrinters' "$cups_browsed_conf" || fail "the unsupported CreateRemotePrinters directive is gone" pass "cups-browsed uses explicit supported discovery policy and an isolated cache" grep -qxF 'SystemGroup cups-browsed sys root' "$cups_files_conf" || fail "only the printer discovery account receives passwordless CUPS administration" grep -qxF 'PeerCred on' "$cups_files_conf" || fail "the packaged CUPS policy enables peer credentials" [[ $(grep -ciE '^[[:space:]]*SystemGroup[[:space:]]' "$cups_files_conf") == 1 ]] || fail "the packaged CUPS policy has one SystemGroup directive" [[ $(grep -ciE '^[[:space:]]*PeerCred[[:space:]]' "$cups_files_conf") == 1 ]] || fail "the packaged CUPS policy has one PeerCred directive" [[ ! -e $ROOT/install/config/printing.sh ]] || fail "printing policy is not rewritten by an install script" ! grep -q 'config/printing.sh' "$ROOT/install/config/all.sh" "$ROOT/migrations/1787815267.sh" || fail "neither install nor update invokes a printing rewrite script" pass "CUPS authorization ships as a canonical package override" grep -qxF 'u cups-browsed - "CUPS printer discovery" / -' "$sysusers_conf" || fail "a locked cups-browsed system account is declared" for setting in \ 'User=cups-browsed' \ 'Group=cups-browsed' \ 'CacheDirectory=cups-browsed' \ 'CacheDirectoryMode=0750' \ 'UMask=0027' \ 'NoNewPrivileges=yes' \ 'ProtectSystem=strict' \ 'ProtectHome=yes' \ 'PrivateTmp=yes' \ 'RestrictSUIDSGID=yes'; do grep -qxF "$setting" "$service_dropin" || fail "cups-browsed service hardening includes $setting" done ! grep -q '^\(Ambient\|CapabilityBoundingSet\).*CAP_NET_BIND_SERVICE' "$service_dropin" || fail "cups-browsed is not granted an unverified network capability" pass "cups-browsed runs as its confined service account without added capabilities" test_tmp=$(mktemp -d) trap 'rm -rf "$test_tmp"' EXIT mock_bin="$test_tmp/bin" mkdir -p "$mock_bin" "$test_tmp/var/lib/omarchy/migrations" passwd_db="$test_tmp/passwd" group_db="$test_tmp/group" touch "$passwd_db" "$group_db" cat >"$mock_bin/getent" <<'SH' #!/bin/bash case "$1" in passwd) database="$OMARCHY_CUPS_TEST_PASSWD" ;; group) database="$OMARCHY_CUPS_TEST_GROUP" ;; *) exit 2 ;; esac if (($# == 1)); then cat "$database" else awk -F: -v name="$2" '$1 == name { print; found = 1 } END { exit !found }' "$database" fi SH cat >"$mock_bin/omarchy-pkg-present" <<'SH' #!/bin/bash [[ $1 == "cups" || $1 == "cups-browsed" ]] SH for command in omarchy-pkg-add omarchy-pkg-drop; do cat >"$mock_bin/$command" <<'SH' #!/bin/bash printf '%s\t%s\n' "${0##*/}" "$*" >>"$OMARCHY_CUPS_TEST_LOG" SH done cat >"$mock_bin/systemctl" <<'SH' #!/bin/bash printf 'systemctl\t%s\n' "$*" >>"$OMARCHY_CUPS_TEST_LOG" exit 0 SH cat >"$mock_bin/sudo" <<'SH' #!/bin/bash printf 'sudo\t%s\n' "$*" >>"$OMARCHY_CUPS_TEST_LOG" exec "$@" SH chmod +x "$mock_bin"/* log="$test_tmp/actions.log" touch "$log" export OMARCHY_CUPS_TEST_LOG="$log" export OMARCHY_CUPS_TEST_PASSWD="$passwd_db" export OMARCHY_CUPS_TEST_GROUP="$group_db" printf 'cups-browsed:x:1000:1000:Desktop user:/home/cups-browsed:/usr/bin/bash\n' >"$passwd_db" printf 'cups-browsed:x:1000:\n' >"$group_db" if PATH="$mock_bin:$PATH" \ OMARCHY_PATH="$ROOT" \ OMARCHY_CUPS_MIGRATION_MARKER="$test_tmp/desktop-collision-marker" \ bash -euo pipefail "$ROOT/migrations/1787815267.sh" 2>/dev/null; then fail "the migration accepts an existing desktop user named cups-browsed" fi [[ ! -s $log ]] || fail "an account collision stops the migration before changing the system" printf 'alice:x:1000:947:Desktop user:/home/alice:/usr/bin/bash\n' >"$passwd_db" printf 'cups-browsed:x:947:alice\n' >"$group_db" if PATH="$mock_bin:$PATH" \ OMARCHY_PATH="$ROOT" \ OMARCHY_CUPS_MIGRATION_MARKER="$test_tmp/group-collision-marker" \ bash -euo pipefail "$ROOT/migrations/1787815267.sh" 2>/dev/null; then fail "the migration accepts an existing cups-browsed group with members" fi [[ ! -s $log ]] || fail "a group collision stops the migration before changing the system" printf 'cups-browsed:x:947:947:CUPS printer discovery:/:/usr/bin/nologin\n' >"$passwd_db" printf 'cups-browsed:x:947:\n' >"$group_db" pass "the migration rejects account and group collisions before changing printing" marker="$test_tmp/var/lib/omarchy/migrations/1787815267" PATH="$mock_bin:$PATH" \ OMARCHY_PATH="$ROOT" \ OMARCHY_CUPS_MIGRATION_MARKER="$marker" \ bash -euo pipefail "$ROOT/migrations/1787815267.sh" grep -qxF $'omarchy-pkg-drop\tcups-pdf' "$log" || fail "the migration removes CUPS-PDF" grep -qxF $'omarchy-pkg-add\tcups-pk-helper' "$log" || fail "the migration installs authenticated printer administration" grep -qxF $'systemctl\tstop cups-browsed.service' "$log" || fail "the migration stops the root cups-browsed process before reconfiguration" grep -qxF $'systemctl\tdaemon-reload' "$log" || fail "the migration reloads the hardened service" grep -qxF $'systemctl\ttry-reload-or-restart cups.service' "$log" || fail "the migration reloads the packaged CUPS authorization" grep -qxF $'systemctl\trestart cups-browsed.service' "$log" || fail "the migration resumes an active cups-browsed service" [[ -f $marker ]] || fail "the migration records machine-wide completion" actions_after_first_run=$(wc -l <"$log") PATH="$mock_bin:$PATH" \ OMARCHY_PATH="$ROOT" \ OMARCHY_CUPS_MIGRATION_MARKER="$marker" \ bash -euo pipefail "$ROOT/migrations/1787815267.sh" [[ $(wc -l <"$log") == "$actions_after_first_run" ]] || fail "the machine-wide migration repeats privileged work" pass "the migration safely converts an active existing installation once" # An interrupted earlier run leaves cups-browsed stopped. A retry still needs # to resume an enabled service before recording completion. cat >"$mock_bin/systemctl" <<'SH' #!/bin/bash printf 'systemctl\t%s\n' "$*" >>"$OMARCHY_CUPS_TEST_LOG" [[ $1 == "is-active" ]] && exit 1 exit 0 SH chmod +x "$mock_bin/systemctl" retry_log="$test_tmp/retry.log" retry_marker="$test_tmp/var/lib/omarchy/migrations/1787815267-retry" OMARCHY_CUPS_TEST_LOG="$retry_log" \ PATH="$mock_bin:$PATH" \ OMARCHY_PATH="$ROOT" \ OMARCHY_CUPS_MIGRATION_MARKER="$retry_marker" \ bash -euo pipefail "$ROOT/migrations/1787815267.sh" grep -qxF $'systemctl\trestart cups-browsed.service' "$retry_log" || fail "the retry resumes cups-browsed after an interrupted earlier run" pass "a run following an interrupted one still resumes printer discovery" # A masked or disabled unit is deliberately left alone. cat >"$mock_bin/systemctl" <<'SH' #!/bin/bash printf 'systemctl\t%s\n' "$*" >>"$OMARCHY_CUPS_TEST_LOG" [[ $1 == "is-active" || $1 == "is-enabled" ]] && exit 1 exit 0 SH chmod +x "$mock_bin/systemctl" masked_log="$test_tmp/masked.log" masked_marker="$test_tmp/var/lib/omarchy/migrations/1787815267-masked" OMARCHY_CUPS_TEST_LOG="$masked_log" \ PATH="$mock_bin:$PATH" \ OMARCHY_PATH="$ROOT" \ OMARCHY_CUPS_MIGRATION_MARKER="$masked_marker" \ bash -euo pipefail "$ROOT/migrations/1787815267.sh" ! grep -qxF $'systemctl\trestart cups-browsed.service' "$masked_log" || fail "the migration leaves a masked or disabled cups-browsed alone" [[ -f $masked_marker ]] || fail "the migration completes with cups-browsed masked" pass "a masked or disabled cups-browsed is left alone and does not fail the migration"