OAuth client for intervals.icu.
This module owns every HTTP conversation with intervals.icu: building the authorize URL, exchanging an authorization code for a token, and making authenticated API calls on the token's behalf.
Configuration
config :ueberauth, Ueberauth.Strategy.IntervalsIcu.OAuth,
client_id: System.get_env("INTERVALS_ICU_CLIENT_ID"),
client_secret: System.get_env("INTERVALS_ICU_CLIENT_SECRET")Endpoints
Note that the authorize and token endpoints live under different path prefixes, which is why both are configured as absolute URLs:
https://intervals.icu/oauth/authorize # authorize
https://intervals.icu/api/oauth/token # tokenBoth are overridable via :authorize_url and :token_url should
intervals.icu ever move them.
Passing options to Req
Anything under :req_options is merged into every request, overriding this
module's own defaults. Use it to supply a custom Finch pool, a retry policy,
timeouts, or a test plug:
config :ueberauth, Ueberauth.Strategy.IntervalsIcu.OAuth,
client_id: "...",
client_secret: "...",
req_options: [receive_timeout: 10_000]Retries are off by default
Req retries transient failures with backoff out of the box. This module turns that off, because an OAuth callback is an interactive request: the athlete is waiting on a redirect, so several seconds of backoff before an inevitable failure is worse than failing fast. The authorization code is also only valid for two minutes, so a long retry chain can consume the very window it is meant to protect.
If your application would rather retry, say so explicitly:
req_options: [retry: :safe_transient]Errors
get_access_token/2 reports failures as {:error, %{key: key, message: message}},
ready to be handed to Ueberauth.Strategy.Helpers.error/2.
Summary
Functions
Builds the URL the athlete is redirected to in order to grant access.
Builds the resolved client configuration.
The default intervals.icu endpoints, useful for tests and introspection.
Performs an authenticated GET against the intervals.icu API.
Exchanges an authorization code for an access token.
Types
Functions
Builds the URL the athlete is redirected to in order to grant access.
params are merged into the query string. :scope and :state are the
interesting ones; :client_id, :redirect_uri and :response_type are
filled in from the client unless you override them.
Examples
authorize_url!([scope: "ACTIVITY:READ", state: "csrf"],
redirect_uri: "https://example.com/auth/intervals_icu/callback")
Builds the resolved client configuration.
Application config is merged over the defaults, and opts over that, so a
call site can always override configuration.
Raises ArgumentError when configuration is missing, is not a keyword list,
or omits :client_id / :client_secret.
@spec defaults() :: keyword()
The default intervals.icu endpoints, useful for tests and introspection.
@spec get(Ueberauth.Strategy.IntervalsIcu.Token.t(), String.t(), keyword(), keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Performs an authenticated GET against the intervals.icu API.
url may be an absolute URL or a path, which is resolved against the
configured :site. The token is sent as an Authorization: Bearer header.
Returns Req's usual {:ok, %Req.Response{}} / {:error, exception}.
Examples
get(token, "/api/v1/athlete/0")
@spec get_access_token(keyword(), keyword()) :: {:ok, Ueberauth.Strategy.IntervalsIcu.Token.t()} | {:error, error()}
Exchanges an authorization code for an access token.
intervals.icu expects client_id, client_secret and code as
form-encoded body parameters, not HTTP Basic credentials, so that is what
this sends.
The code is only valid for two minutes after the redirect.
Returns {:ok, %Token{}} or {:error, %{key: key, message: message}}.