Packages
goth
0.0.2
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.1
1.3.0
1.3.0-rc.5
1.3.0-rc.4
1.3.0-rc.3
1.3.0-rc.2
1.3.0-rc.1
1.3.0-rc.0
1.2.0
1.1.0
1.0.1
1.0.1-beta
1.0.0
0.11.1
0.11.0
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.3
0.0.2
0.0.1
A simple library to generate and retrieve Oauth2 tokens for use with Google Cloud Service accounts.
Current section
Files
Jump to
Current section
Files
lib/goth/token.ex
defmodule Goth.Token do
@moduledoc """
Interface for retrieving access tokens, from either the `Goth.TokenStore`
or the Google token API. The first request for a token will hit the API,
but subsequent requests will retrieve the token from Goth's token store
"""
alias Goth.TokenStore
alias Goth.Client
@type token :: %__MODULE__{
token: String.t,
type: String.t,
scope: String.t,
expires: non_neg_integer
}
defstruct [:token, :type, :scope, :expires]
@doc """
Get a `%Goth.Token{}` for a particular `scope`. `scope` can be a single
scope or multiple scopes joined by a comma.
## Example
iex> Token.for_scope("https://www.googleapis.com/auth/pubsub")
{:ok, %Goth.Token{expires: ..., token: "...", type: "..."} }
"""
@spec for_scope(String.t) :: {:ok, token} | :error
def for_scope(scope) do
case TokenStore.find(scope) do
:error -> retrieve_and_store!(scope)
{:ok, token} -> {:ok, token}
end
end
@doc """
Parse a successful JSON response from Google's token API and extract a `%Goth.Token{}`
"""
def from_response_json(scope, json) do
{:ok, attrs} = json |> Poison.decode
%__MODULE__{
token: attrs["access_token"],
type: attrs["token_type"],
scope: scope,
expires: :os.system_time(:seconds) + attrs["expires_in"]
}
end
def refresh!(%__MODULE__{scope: scope}), do: refresh!(scope)
def refresh!(scope), do: retrieve_and_store!(scope)
def queue_for_refresh(%__MODULE__{}=token) do
diff = token.expires - :os.system_time(:seconds)
if diff < 10 do
# just do it immediately
Task.async fn ->
__MODULE__.refresh!(token)
end
else
:timer.apply_after((diff-10)*1000, __MODULE__, :refresh!, [token])
end
end
defp retrieve_and_store!(scope) do
{:ok, token} = Client.get_access_token(scope)
TokenStore.store(scope, token)
{:ok, token}
end
end