WarpEngine: let the host say who a browser is
The access policy asks who the caller is, and until now only a bearer token
could answer. That is what a desktop client carries — but a person clicking a
download link on the site carries a session instead, and the engine has no idea
what a session is. So a host that gated its catalog found its own signed-in
visitors refused at /api/download, which is a regression the shadowed route used
to hide.
c.subject_resolver is a callable taking the Rack request and returning the
host's subject: `->(request) { request.env["warden"]&.user }` for a Devise app.
Unset — every deployment today — a non-bearer request stays anonymous, exactly
as before. A resolver that raises is logged and treated as anonymous, because a
broken one turning every read into a 500 is worse than an anonymous request.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -220,6 +220,9 @@ Rails.application.config.to_prepare do
|
||||
# none: /api/auth/* answers 404 and GET /api/service reports auth: null.
|
||||
# c.access_token_owner_class = "User"
|
||||
# c.identity_verification_url = "/devices"
|
||||
#
|
||||
# How to recognise a caller with a session instead of a bearer token.
|
||||
# c.subject_resolver = ->(request) { request.env["warden"]&.user }
|
||||
|
||||
# If your app's own models reference catalog images, register them so the
|
||||
# admin Images page counts them as "in use":
|
||||
@@ -465,6 +468,21 @@ The flow:
|
||||
4. the client's next `POST /api/auth/device/token` carries the token away. It is
|
||||
handed over exactly once and never stored in the clear afterwards.
|
||||
|
||||
### Recognising a browser
|
||||
|
||||
A bearer token is what a *client* carries; a browser carries a session, and the
|
||||
engine has no idea what a session is. A host that wants its signed-in visitors
|
||||
recognised on these endpoints too — so that clicking a download link on the site
|
||||
works the same way the client's download does — says how:
|
||||
|
||||
```ruby
|
||||
c.subject_resolver = ->(request) { request.env["warden"]&.user }
|
||||
```
|
||||
|
||||
Without one, a request with no bearer token is anonymous, which is what the
|
||||
read-only API always did. A resolver that raises is logged and treated as
|
||||
anonymous rather than taking the request down with it.
|
||||
|
||||
The token is a `WarpEngine::ApplicationToken` with the `catalog` scope, sent as
|
||||
`Authorization: Bearer …`. `DELETE /api/auth/token` revokes it (signing out),
|
||||
and the admin lists both kinds of token and the sign-ins behind them.
|
||||
|
||||
Reference in New Issue
Block a user