ML-5: document Last.fm OAuth callback trust boundary
Closes GitHub issue #178.
This commit is contained in:
@@ -1,4 +1,30 @@
|
||||
defmodule MusicLibraryWeb.LastFmController do
|
||||
@moduledoc """
|
||||
Handles the Last.fm OAuth callback.
|
||||
|
||||
## Trust boundary
|
||||
|
||||
`GET /auth/last_fm/callback` is deliberately outside the `:logged_in`
|
||||
pipeline: Last.fm redirects the browser back to us with a `token` query
|
||||
parameter, and that third-party redirect cannot carry our session cookie,
|
||||
so requiring a logged-in session here would break the OAuth flow.
|
||||
|
||||
What protects the endpoint:
|
||||
|
||||
* The `token` is validated by Last.fm via `LastFm.get_session/1`
|
||||
against the `LAST_FM_API_KEY` / `LAST_FM_SHARED_SECRET` pair — it
|
||||
cannot be forged locally.
|
||||
* The Last.fm HTTP client is rate-limited at the `Req` layer
|
||||
(`Req.RateLimiter`, 500ms between requests), bounding the quota a
|
||||
malicious caller could burn.
|
||||
* This is a single-user deployment; the stored session key grants
|
||||
scrobble access for one account, not multi-tenant credentials.
|
||||
|
||||
Failure mode: an invalid or forged `token` makes `get_session/1` return
|
||||
`{:error, reason}`; nothing is written to the `secrets` table, the user
|
||||
sees an error toast, and the upstream error is logged by the Req layer.
|
||||
"""
|
||||
|
||||
use MusicLibraryWeb, :controller
|
||||
|
||||
alias MusicLibrary.Secrets
|
||||
|
||||
@@ -52,6 +52,10 @@ defmodule MusicLibraryWeb.Router do
|
||||
get "/login", SessionController, :new
|
||||
post "/sessions/create", SessionController, :create
|
||||
|
||||
# Deliberately outside the `:logged_in` pipeline: this is the OAuth
|
||||
# callback from Last.fm and the third-party redirect can't carry our
|
||||
# session cookie. See `MusicLibraryWeb.LastFmController` moduledoc for
|
||||
# the full trust boundary.
|
||||
get "/auth/last_fm/callback", LastFmController, :callback
|
||||
|
||||
get "/public/assets/:transform_payload", AssetController, :show
|
||||
|
||||
Reference in New Issue
Block a user