defmodule Breddit do require Logger use OAuth2.Strategy alias OAuth2.Strategy.AuthCode # @scopes "identity edit flair history mysubreddits privatemessages read report save submit" @site "https://oauth.reddit.com" @root_url @site @default_config [ strategy: Breddit, site: "https://oauth.reddit.com/", authorize_url: "https://www.reddit.com/api/v1/authorize", token_url: "https://www.reddit.com/api/v1/access_token", params: %{duration: "permanent"}, headers: [ {"User-Agent", "web:breddit:v.0.0.1 (by u/andrex092)"}, {"Content-Type", "application/x-www-form-urlencoded"} ] ] @type response :: {:ok, any()} | {:error, OAuth2.Error.t()} # TODO: extract to mix config defp config do @default_config |> Config.Reader.merge(Application.get_env(:breddit, :oauth)) |> Keyword.update!(:params, &Map.merge(&1, Application.get_env(:breddit, :params))) #FIXME # |> Keyword.update!(:headers, &([Application.get_env(:breddit, :headers) | &1])) end defp url(uri, params, opts \\ []) do opts |> Keyword.get(:site, @root_url) |> URI.parse() |> URI.merge(uri) |> Map.put(:query, URI.encode_query(params)) |> URI.to_string() end # Public API def client(args \\ []) do config() |> Keyword.merge(args) |> OAuth2.Client.new() |> OAuth2.Client.put_serializer("application/json", Jason) end def get(client, uri, opts \\ [], headers \\ []) do url = url(uri, Keyword.get(opts, :params)) Logger.info("Getting: #{url}") client |> OAuth2.Client.put_serializer("application/json", Breddit.Serializer) |> OAuth2.Client.get(url, headers, opts) |> parse_response() end @spec parse_response({:ok, OAuth2.Response.t()} | {:error, OAuth2.Error.t()}) :: response() defp parse_response({:ok, %OAuth2.Response{body: body}}) do {:ok, body} end defp parse_response({:error, error}), do: {:error, error} def authorize_url!(params \\ []) do OAuth2.Client.authorize_url!( client(), Keyword.merge(params, client_secret: client().client_secret) ) end def get_token!(params \\ [], _headers \\ []) do OAuth2.Client.get_token!( client(), Keyword.merge(params, client_secret: client().client_secret) ) end # Strats def authorize_url(client, params) do AuthCode.authorize_url(client, params) end def get_token(client, params, headers) do client |> put_header("Accept", "application/json") |> AuthCode.get_token(params, headers) end end