Skip to content

Instantly share code, notes, and snippets.

@djinn
Last active January 21, 2017 21:00
Show Gist options
  • Save djinn/1f35c7c249c446b894f1 to your computer and use it in GitHub Desktop.
Save djinn/1f35c7c249c446b894f1 to your computer and use it in GitHub Desktop.
Shopify Oauth strategy for Elixir
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
@fastjames
Copy link

Are you using this strategy in production? I have been trying something similar with Boulevard/shopify but I haven't quite gotten it to work yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment