Skip to content

cgi-bin: Port Web Interface OAuth login to device authorization grant (#1232) - #1741

Open
abubakarsabir924-cell wants to merge 1 commit into
OpenPrinting:masterfrom
abubakarsabir924-cell:oauth-1232-device-grant
Open

abubakarsabir924-cell wants to merge 1 commit into
OpenPrinting:masterfrom
abubakarsabir924-cell:oauth-1232-device-grant

Conversation

@abubakarsabir924-cell

Copy link
Copy Markdown
Contributor

Summary

Implements #1232 by replacing the Web Interface's single-session OAuth authorization-code (PKCE) flow with the device authorization grant flow, following the direction from @michaelrsweet and the pattern already used by ippeveprinter's OAuth support in libcups.

Changes

  • cgi-bin/home.c: Removed do_login()/finish_login()'s PKCE redirect flow. The new do_login() tracks each browser session's device grant in a CUPS_DEVGRANT cookie:
    • No grant cookie → request a new device grant (cupsOAuthGetDeviceGrant()), show the user code and verification URL, with a meta-refresh timed to the server's polling interval.
    • Pending grant cookie → a single, non-blocking cupsOAuthGetTokens() attempt. Success stores the token in CUPS_BEARER and clears the grant cookie; still-pending shows the same page again; a hard failure discards the grant so the next visit starts fresh.
    • A new grant is only requested on POST (the CSRF-protected Login button), not on the GET requests used for polling.
    • do_logout() now also clears CUPS_DEVGRANT and calls cupsOAuthClearTokens(), in addition to clearing CUPS_BEARER.
  • templates/oauth-login.tmpl (new): shows the user code and verification URL.
  • templates/Makefile: registers the new template.

Notes for reviewers

  • The old code's referrer-restore redirect relied on mismatched env var/cookie names (CUPS_REFERER vs CUPS_REFERRER) and never actually worked; login now always redirects to /.
  • cupsOAuthGetDeviceGrant() looks up the client ID under CUPS_OAUTH_REDIRECT_URI. A server previously configured only for the authorization-code Web Interface flow may need its client ID re-registered under that redirect URI.
  • Not tested against a live OAuth provider. I set up an Auth0 tenant with the Device Code grant enabled to test this, but hit a local environment issue where HTTPS connections to the IdP failed CA validation (cupsGetCredentialsTrust() in cups/tls.c) — this appears unrelated to this change (it also affects tools/cups-oauth against the same tenant) and I wasn't able to resolve it. The device-grant call pattern mirrors tools/cups-oauth.c's existing, working usage, but manual verification against a live IdP before merging is strongly recommended.

Testing

Replace the single-session authorization-code (PKCE) flow in
do_login()/finish_login() with the device authorization grant flow,
following the pattern already used by ippeveprinter's OAuth support
in libcups.

Each browser session tracks its own device grant in a CUPS_DEVGRANT
cookie (the device code, polling interval, etc. as JSON). A request
to "/?LOGIN=Login":

  - with no CUPS_DEVGRANT cookie: requests a new device grant
    (cupsOAuthGetDeviceGrant()) and shows the user code and
    verification URL via a new oauth-login.tmpl template, with a
    meta-refresh timed to the server's requested polling interval.
  - with a pending CUPS_DEVGRANT cookie: makes a single, non-blocking
    cupsOAuthGetTokens() attempt. On success, stores the access token
    in CUPS_BEARER and clears the grant cookie. While still pending
    (authorization_pending/slow_down), the same page is shown again.
    On a hard failure, the grant is discarded so the next visit
    requests a fresh one.

A new grant is only requested on a POST (the existing Login button,
which is protected by the CSRF token), not on the GET requests used
for polling, so a stray GET can't silently start a new authorization
request against the OAuth server.

do_logout() now also clears the CUPS_DEVGRANT cookie and calls
cupsOAuthClearTokens() to clear the server-side token store, in
addition to clearing CUPS_BEARER as before.

Notes for reviewers:
- The old code's CUPS_REFERER/CUPS_REFERRER-based return-to-referrer
  redirect is dropped; the mismatched env var/cookie names meant it
  never actually worked, and login now always redirects to "/".
- cupsOAuthGetDeviceGrant() looks up the client ID under
  CUPS_OAUTH_REDIRECT_URI; a server previously configured only for
  the authorization-code Web Interface flow may need its client ID
  re-registered under that redirect URI.
- Not tested against a live OAuth provider: a local environment TLS
  trust issue (unrelated to this change) prevented HTTPS connections
  to an IdP during development. The device-grant call pattern mirrors
  tools/cups-oauth.c's existing, working usage; manual verification
  against a live IdP before merging is recommended.
@abubakarsabir924-cell

Copy link
Copy Markdown
Contributor Author

@michaelrsweet Sir,

Whenever you get a chance, I'd appreciate your review on this. Let me know if you'd like any changes to the approach.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant