An APIAuthState object manages an authorization state for
authentication with SpeedGoat APIs. When using a SpeedGoat API
the user is identified by their email address and project ID.
One email can be associated with multiple projects.
Authentication is organized by realms. A realm is a named group of APIs
that share a single token authority. For example, the "counts" realm
includes the counts API and any satellite APIs (e.g., sightability) that
trust its tokens. A realm either holds a credential or delegates to one that
does; every read resolves through to the authority, so rotating it is
visible to all delegates at once.
Authentication mechanisms include:
OIDC for shiny applications
API key for automated processes by end users
OAuth for interactive sessions
Methods
Method new()
Create a new APIAuthState instance with default authentication endpoint
Returns
A new APIAuthState object
Print authentication state information
Returns
Invisibly returns self (chainable)
Method init_realm()
Initialize a realm with default (unauthenticated) state.
Usage
APIAuthState$init_realm(name, base_url)
Arguments
name
Realm name
base_url
Base API URL for the realm (e.g.,
"https://counts.spdgt.com/api")
Returns
Invisible self (chainable)
Method get_realm()
Get realm state
Usage
APIAuthState$get_realm(name)
Returns
Named list with realm state
Method get_realm_for_api()
Get the realm name for a given API
Usage
APIAuthState$get_realm_for_api(api_name)
Returns
Realm name string, or NULL
Method get_apis_for_realm()
List every API registered in a realm, primary first.
Usage
APIAuthState$get_apis_for_realm(realm)
Returns
Character vector of API names; character() if the realm holds
none, or does not exist.
Method get_realms()
Names of every registered realm.
Usage
APIAuthState$get_realms()
Method get_api_names()
Names of every registered API.
Usage
APIAuthState$get_api_names()
Method set_realm_token()
Store credentials for a realm.
Usage
APIAuthState$set_realm_token(
realm,
token,
refresh_token = NULL,
expiration = NULL,
auth_type = NULL
)
Arguments
realm
Realm name
token
Access token
refresh_token
Refresh token (optional)
expiration
Token expiration time (optional)
auth_type
Authentication type ("oauth", "oidc", or "api_key")
Returns
Invisible self (chainable)
Method set_realm_delegation()
Get token for a realm
Delegate a realm's credential to another realm.
A delegating realm holds no credential of its own: every read
resolves to the authority. This is deliberately a reference rather
than a copy, so rotating the authority's token (a refresh, or
auth_switch_project(), which issues a new one) is visible to the
delegate immediately. Copying instead requires every rotation point
to remember to re-copy, and the one that forgets leaves a stale
token that fails exactly like an expired one.
Usage
APIAuthState$set_realm_delegation(realm, authority)
Arguments
realm
Realm that will delegate
authority
Realm holding the credential
Returns
Invisible self (chainable)
Method get_realm_authority()
Resolve a realm to the realm holding its credential.
Usage
APIAuthState$get_realm_authority(realm)
Returns
Realm name; the realm itself when it does not delegate
Method get_realm_token()
Usage
APIAuthState$get_realm_token(realm)
Returns
Token string or NULL
Method get_realm_auth_type()
Get auth type for a realm
Usage
APIAuthState$get_realm_auth_type(realm)
Returns
Auth type string or NULL
Method get_realm_refresh_token()
Get refresh token for a realm
Usage
APIAuthState$get_realm_refresh_token(realm)
Returns
Refresh token string or NULL
Method get_realm_expiration()
Get expiration for a realm
Usage
APIAuthState$get_realm_expiration(realm)
Returns
Expiration POSIXct or NULL
Method is_realm_auth()
Check if a realm is authenticated
Usage
APIAuthState$is_realm_auth(realm)
Method clear_realm_cred()
Clear credentials for a single realm.
Clearing a delegate drops its delegation rather than reaching into
the authority: one realm's failure must not sign the user out of
every realm sharing that credential.
Usage
APIAuthState$clear_realm_cred(realm)
Returns
Invisible self (chainable)
Method forward_realm_token()
Forward a token to a specific realm.
Usage
APIAuthState$forward_realm_token(
realm,
token,
refresh_token = NULL,
expires_in = 3600,
auth_type = "oidc"
)
Arguments
realm
Realm name
token
Token string
refresh_token
Refresh token, when the caller has one. Without
it the realm cannot refresh, and a 401 is terminal.
expires_in
Expiration time in seconds (default: 3600)
auth_type
Authentication type (default: "oidc")
Returns
Invisible self (chainable)
Method get_realm_base_url()
A realm's base URL, resolved for the session's region.
The region is applied when the URL is read rather than when the API
is registered. Registration happens in each package's .onLoad, so
baking the region in there would make any region set afterwards too
late — and rebuild the call-order trap this is meant to remove.
Usage
APIAuthState$get_realm_base_url(realm)
Returns
URL string, or NULL when the realm does not exist
Method get_realm_url()
Derive auth URLs from a realm's base_url
Usage
APIAuthState$get_realm_url(realm, path)
Arguments
realm
Realm name
path
One of "me", "login", "refresh", "oidc", "logout"
Register an API endpoint and assign it to a realm.
Usage
APIAuthState$add_api(name, url, package = NULL, realm = NULL)
Arguments
name
API name
url
API URL
package
Package registering the API, or NULL when unknown.
Not detected here: every caller of this method is inside spdgt.auth,
so its calling frame always names spdgt.auth. add_api() detects its
own caller and passes it.
realm
Realm name. If NULL, creates a new realm named after the
API. If provided, joins the existing realm.
Returns
Invisible self (chainable)
Method get_api_url()
Get the registered URL for an API by name.
Usage
APIAuthState$get_api_url(name, resolve = TRUE)
Arguments
name
API name
resolve
Apply the session's region (default TRUE). Pass FALSE
for the URL exactly as the registering package supplied it.
Method remove_api()
Remove an API registration.
Usage
APIAuthState$remove_api(name)
Returns
Invisible self (chainable)
Method get_user_agent()
Get the user agent string.
Usage
APIAuthState$get_user_agent()
Returns
User agent string
Method set_user_id()
Set user ID
Usage
APIAuthState$set_user_id(user_id)
Method get_user_id()
Get user ID
Usage
APIAuthState$get_user_id()
Method set_email()
Set user email.
Usage
APIAuthState$set_email(email)
Returns
Invisible self (chainable)
Method get_email()
Get user email
Method set_project_id()
Set project ID
Usage
APIAuthState$set_project_id(value)
Arguments
value
Project unique identifier
Method get_project_id()
Get project ID
A project belongs to the deployment that issued it, so one recorded
in another region is not the current project — it is a project that
does not exist here.
Usage
APIAuthState$get_project_id()
Returns
Project unique identifier, or NULL
Method set_project_abb()
Set project abbreviation
Usage
APIAuthState$set_project_abb(value)
Arguments
value
Project abbreviation string
Method get_project_abb()
Get project abbreviation
Usage
APIAuthState$get_project_abb(any_region = FALSE)
Arguments
any_region
Return the recorded value even when it was set in
a different region. Used to explain a cross-region switch.
Returns
Project abbreviation string, or NULL
Method project_is_current_region()
Was the recorded project set in the session's region?
Usage
APIAuthState$project_is_current_region()
Method get_project_region()
The region the recorded project came from.
Usage
APIAuthState$get_project_region()
Returns
Region string, or NULL if none has been recorded
Method get_is_auth()
Get authentication status (any realm)
Usage
APIAuthState$get_is_auth()
Returns
Logical, TRUE if any realm is authenticated
Method clear_cred()
Clear all credentials (all realms and global identity).
Usage
APIAuthState$clear_cred()
Returns
Invisible self (chainable)
user_id User's unique identifier
email User's email address
project_id Project unique identifier
project_abb Project abbreviation
Get user agent string
User agent string
Method clone()
The objects of this class are cloneable with this method.
Usage
APIAuthState$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.