Created
December 1, 2015 16:41
-
-
Save johnhamelink/729009f8714fa6f4e6bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule GoogleContactsToGrandstream.Google.AccessToken do | |
| @moduledoc """ | |
| Retrieves an Authentication Access Token | |
| for Google from the Google apps account | |
| supplied. | |
| """ | |
| require Logger | |
| alias GoogleContactsToGrandstream.Google.Jwt | |
| @url "https://www.googleapis.com/oauth2/v3/token" | |
| @grant_type "urn:ietf:params:oauth:grant-type:jwt-bearer" | |
| def request(token: token, account_email: account_email) do | |
| Logger.info "Requesting Access Token for #{account_email}" | |
| HTTPoison.start | |
| Logger.debug "Built token:" | |
| Logger.debug token | |
| params = [ | |
| grant_type: @grant_type, | |
| assertion: token | |
| ] | |
| {:ok, response} = HTTPoison.post( | |
| @url, | |
| {:form, params}, | |
| %{"Content-type" => "application/x-www-form-urlencoded"} | |
| ) | |
| Logger.debug "Received: #{inspect response}" | |
| res = JSX.decode!(response.body) | |
| {:ok, res["access_token"]} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule GoogleContactsToGrandstream.Google.Account do | |
| @moduledoc """ | |
| Provides a generic module to define Google Apps | |
| accounts with. | |
| """ | |
| alias GoogleContactsToGrandstream.Google.AccessToken | |
| alias GoogleContactsToGrandstream.Google.Jwt | |
| defstruct [ | |
| :name, :client_id, :client_email, | |
| :scope, :account_emails, | |
| :rsa_key_path | |
| ] | |
| def start_link do | |
| cache = Enum.into([], HashDict.new) | |
| Agent.start_link(fn -> cache end) | |
| end | |
| def request_access_token(pid: pid, account: account) do | |
| Agent.get_and_update( | |
| pid, | |
| &do_request_access_token_with_cache(&1, account) | |
| ) | |
| end | |
| def do_request_access_token_with_cache(cache, account) do | |
| if cached = cache[account.name] do | |
| {cached, cache} | |
| else | |
| result = do_request_access_token(account) | |
| {result, Dict.put(cache, account.name, result)} | |
| end | |
| end | |
| def do_request_access_token(account) do | |
| # For each account, retrieve an access code | |
| # along with the email address. | |
| accounts = Enum.map(account.account_emails, fn(acc_email) -> | |
| # Build a JWT Token | |
| {:ok, token} = Jwt.get_token( | |
| client_email: account.client_email, | |
| scope: account.scope, | |
| account_email: acc_email, | |
| rsa_key_path: account.rsa_key_path | |
| ) | |
| # Retrive the Access Token using it | |
| {:ok, access_token} = AccessToken.request( | |
| token: token, | |
| account_email: acc_email | |
| ) | |
| %{ | |
| name: account.name, | |
| token: access_token, | |
| client_id: account.client_id, | |
| email: acc_email | |
| } | |
| end) | |
| {:ok, accounts} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule GoogleContactsToGrandstream.Google.Jwt do | |
| @moduledoc """ | |
| Builds a Google Apps compliant JWT signature | |
| from account details for use with retrieving | |
| and auth token from Google. | |
| """ | |
| require Logger | |
| import Joken | |
| @token_url "https://www.googleapis.com/oauth2/v3/token" | |
| # Produces a JWT containing all | |
| # attributes required for us to | |
| # be able to request an OAuth2 | |
| # token. | |
| def get_token(client_email: client_email, scope: scope, | |
| account_email: account_email, rsa_key_path: rsa_key_path) do | |
| timestamp = unix_timestamp | |
| expires = timestamp + 3599 | |
| jwt = %{ | |
| iss: client_email, | |
| scope: scope, | |
| aud: @token_url, | |
| iat: timestamp, | |
| exp: expires, | |
| sub: account_email | |
| } | |
| Logger.debug inspect(jwt) | |
| payload = jwt | |
| |> token | |
| |> use_pem_to_sign(rsa_key_path) | |
| |> sign | |
| {:ok, payload.token} | |
| end | |
| def use_pem_to_sign(token, rsa_key_path) do | |
| pem_key = JOSE.JWK.from_pem_file(rsa_key_path) | |
| token |> with_signer(pem_key |> rs256) | |
| end | |
| def unix_timestamp do | |
| time = :calendar.datetime_to_gregorian_seconds(:calendar.universal_time()) | |
| time-719528*24*3600 | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment