Current section
Files
Jump to
Current section
Files
lib/spotify/authentication.ex
defmodule AuthenticationError do
defexception [:message]
def exception(_) do
%AuthenticationError{message: "No code provided by Spotify. Authorize your app again"}
end
end
defmodule Spotify.Authentication do
import Spotify.Cookies
@moduledoc """
Authenticates the Spotify user.
After your app is authorized, the user must be authenticated. A redirect
URL is specified in the config folder. This is the URL that Spotify
redirects to after authorization, and should ultimately end up hitting
this module's `authenticate` function. If the authorization is successful,
the param `code` will be present.
If a refresh token still exists, the client will refresh the access token.
"""
@doc """
Authenticates the user
The authorization code must be present from spotify or an exception
will be raised. The token will be refreshed if possible, otherwise
the app will request new access and request tokens.
## Example: ##
Spotify.authenticate(conn, %{"code" => code})
# {:ok, "your access token", conn}
Spotify.authenticate(conn, %{"not_a_code" => invalid})
# AuthenticationError, "No code provided by Spotify. Authorize your app again"
"""
def authenticate(conn, map)
def authenticate(conn, %{"code" => code}) do
if get_refresh_cookie(conn) do
AuthenticationClient.post(conn, refresh_body_params(conn))
else
AuthenticationClient.post(conn, body_params(code))
end
end
def authenticate(_conn, _) do
raise AuthenticationError, "No code provided by Spotify. Authorize your app again"
end
@doc """
Attempts to refresh your access token if the connection cookie exits.
"""
def refresh(conn) do
if get_refresh_cookie(conn) do
AuthenticationClient.post(conn, refresh_body_params(conn))
else
:unauthorized
end
end
@doc """
Checks for refresh and access tokens
## Example: ##
defmodule PlayListController do
plug :check_tokens
def check_tokens do
unless Spotify.Authentication.tokens_present?(conn) do
redirect conn, to: authorization_path(:authorize)
end
end
end
"""
def tokens_present?(conn) do
!!(get_refresh_cookie(conn) && get_access_cookie(conn))
end
def authenticated?(conn) do
get_access_cookie(conn)
end
@doc false
def refresh_body_params(conn) do
"grant_type=refresh_token&refresh_token=#{get_refresh_cookie(conn)}"
end
@doc false
def body_params(code) do
"grant_type=authorization_code&code=#{code}&redirect_uri=#{Spotify.callback_url}"
end
end