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:
@@ -60,6 +60,11 @@ Rails.application.config.to_prepare do
|
||||
# It calls WarpEngine::DeviceGrantService#approve. A path is made absolute
|
||||
# against the request, so you need not know your own hostname (default "/devices").
|
||||
# c.identity_verification_url = "/devices"
|
||||
# A browser has a session rather than a bearer token, and the engine cannot
|
||||
# read one. Say how, and your signed-in visitors are recognised on the
|
||||
# read-only endpoints too:
|
||||
# c.subject_resolver = ->(request) { request.env["warden"]&.user }
|
||||
|
||||
# c.device_code_ttl = 600 # seconds a pending code lives
|
||||
# c.device_code_interval = 5 # seconds a client is told to wait between polls
|
||||
|
||||
|
||||
@@ -40,6 +40,12 @@ module WarpEngine
|
||||
# code. Path or absolute URL; nil falls back to "/devices". The page is the host's
|
||||
# because approving needs a session, a login and HTML — none of which is the
|
||||
# engine's business.
|
||||
# subject_resolver: how to recognise a caller that is not carrying a bearer token —
|
||||
# a browser with a session, typically. A callable taking the Rack request and
|
||||
# returning the host's own subject object, or nil:
|
||||
# c.subject_resolver = ->(request) { request.env["warden"]&.user }
|
||||
# nil (default) makes every non-bearer request anonymous, which is what the
|
||||
# read-only API always did.
|
||||
# device_code_ttl / device_code_interval: how long a pending device code lives, and
|
||||
# how often a client is told to poll for it.
|
||||
# woodpecker_url / woodpecker_api_token / woodpecker_repo_owner:
|
||||
@@ -63,6 +69,7 @@ module WarpEngine
|
||||
:storage_adapter,
|
||||
:access_policy,
|
||||
:access_token_owner_class,
|
||||
:subject_resolver,
|
||||
:identity_verification_url,
|
||||
:device_code_ttl,
|
||||
:device_code_interval
|
||||
@@ -86,6 +93,7 @@ module WarpEngine
|
||||
@storage_adapter = :local
|
||||
@access_policy = :open
|
||||
@access_token_owner_class = nil
|
||||
@subject_resolver = nil
|
||||
@identity_verification_url = nil
|
||||
@device_code_ttl = 600
|
||||
@device_code_interval = 5
|
||||
|
||||
Reference in New Issue
Block a user