1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-14 17:52:10 -04:00

feat(cups): add manual printer addition by IP/hostname (#1868)

Add a new "Add by Address" flow in the printer settings that allows
users to manually add printers by IP address or hostname, enabling
printing to devices not visible via mDNS/Avahi discovery (e.g.,
printers behind Tailscale subnet routers, VPNs, or across network
boundaries).

Go backend:
- New cups.testConnection IPC method that probes remote printers via
  IPP Get-Printer-Attributes with /ipp/print then / fallback
- Input validation with host sanitization and protocol allowlist
- Auth-aware probing (HTTP 401/403 reported as reachable)
- lpadmin CLI fallback for CreatePrinter/DeletePrinter when
  cups-pk-helper polkit authorization fails

QML frontend:
- "Add by Address" toggle alongside existing device discovery
- Manual entry form with host, port, protocol fields
- Test Connection button with loading state and result display
- Smart PPD auto-selection by probed makeModel with driverless fallback
- All strings use I18n.tr() with translator context

Includes 20+ unit tests covering validation, probe delegation, TLS
flag propagation, auth error detection, and handler routing.
This commit is contained in:
Giorgio De Trane
2026-03-01 02:36:16 +01:00
committed by GitHub
parent 9cb0d8baf2
commit 20d383d4ab
9 changed files with 1148 additions and 43 deletions

View File

@@ -70,6 +70,8 @@ func HandleRequest(conn net.Conn, req models.Request, manager *Manager) {
handleRestartJob(conn, req, manager)
case "cups.holdJob":
handleHoldJob(conn, req, manager)
case "cups.testConnection":
handleTestConnection(conn, req, manager)
default:
models.RespondError(conn, req.ID, fmt.Sprintf("unknown method: %s", req.Method))
}
@@ -464,3 +466,22 @@ func handleHoldJob(conn net.Conn, req models.Request, manager *Manager) {
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "job held"})
}
func handleTestConnection(conn net.Conn, req models.Request, manager *Manager) {
host, err := params.StringNonEmpty(req.Params, "host")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
port := params.IntOpt(req.Params, "port", 631)
protocol := params.StringOpt(req.Params, "protocol", "ipp")
result, err := manager.TestRemotePrinter(host, port, protocol)
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, result)
}