defmodule Shopify.Oauth do @moduledoc """ An OAuth2 strategy for Shopify. Based on the OAuth2 strategy for GitHub by Sonny Scroggin in https://github.com/scrogson/oauth2_example """ use OAuth2.Strategy alias OAuth2.Strategy.AuthCode alias OAuth2.Request alias OAuth2.AccessToken # Public API def create(shopid) do OAuth2.Client.new([ strategy: __MODULE__, client_id: System.get_env("CLIENT_ID"), client_secret: System.get_env("CLIENT_SECRET"), redirect_uri: System.get_env("REDIRECT_URI") <> "/auth/shopify/callback", site: "https://#{shopid}.myshopify.com/admin", authorize_url: "https://#{shopid}.myshopify.com/admin/oauth/authorize", token_url: "https://#{shopid}.myshopify.com/admin/oauth/access_token" ]) end def authorize_url!(shopid, params \\ []) do OAuth2.Client.authorize_url!(create(shopid), params) end def get_token!(shopid, params \\ [], headers \\ []) do OAuth2.Client.get_token!(create(shopid), params) end # Strategy Callbacks 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 defp prepare_url(token, url_) do case String.downcase(url_) do <<"http://":: utf8, _::binary>> -> url_ <<"https://":: utf8, _::binary>> -> url_ _ -> token.client.site <> url_ end end defp req_headers(token, headers) do headers1 = [{"X-Shopify-Access-Token", token.access_token} | headers] [{"Authorization", "#{token.token_type} #{token.access_token}"}| headers1] end defp req_post_headers(headers) do [{"Content-Type", "application/json; charset=utf-8"} | headers] end def get!(token, url_, header \\ [], opts \\ []) do headers = req_headers(token, header) url = prepare_url(token, url_) resp = AccessToken.get!(token, url, headers, opts) resp.body end def post!(token, url_, data, header \\ [], opts \\ []) do headers = req_headers(token, header) |> req_post_headers url = prepare_url(token, url_) payload = Poison.Encoder.encode(data, []) case apply(Request, :post, [url, data, headers, opts]) do {:ok, response} -> {:ok, response.body} {:error, error} -> {:error, error} end end def put!(token, url_, data, header \\ [], opts \\ []) do headers = req_headers(token, header) |> req_post_headers url = prepare_url(token, url_) IO.inspect url IO.inspect headers payload = Poison.Encoder.encode(data, []) IO.inspect payload case apply(Request, :put, [url, data, headers, opts]) do {:ok, response} -> {:ok, response.body} {:error, error} -> {:error, error} end end end