defmodule Forcex.Client do require Logger @default_endpoint "https://login.salesforce.com" defstruct api_version: "41.0", authorization_header: [], endpoint: @default_endpoint, services: %{} @moduledoc """ This client delegates login to the appropriate endpoint depending on the type of credentials you have, and upon successful authentication keeps track of the authentication headers you'll need for subsequent calls. """ @doc """ Initially signs into Force.com API. Login credentials may be supplied. Order for locating credentials: 1. Map supplied to `login/1` 2. Environment variables 3. Applications configuration Supplying a Map of login credentials must be in the form of %{ username: "...", password: "...", security_token: "...", client_id: "...", client_secret: "...", endpoint: "..." } Environment variables - `SALESFORCE_USERNAME` - `SALESFORCE_PASSWORD` - `SALESFORCE_SECURITY_TOKEN` - `SALESFORCE_CLIENT_ID` - `SALESFORCE_CLIENT_SECRET` - `SALESFORCE_ENDPOINT` Application configuration config :forcex, Forcex.Client, username: "user@example.com", password: "my_super_secret_password", security_token: "EMAILED_FROM_SALESFORCE", client_id: "CONNECTED_APP_OAUTH_CLIENT_ID", client_secret: "CONNECTED_APP_OAUTH_CLIENT_SECRET", endpoint: "login.salesforce.com" If no `client_id` is passed login via session id will be attempted with `security_token`. Will require additional call to `locate_services/1` to identify which Force.com services are availabe for your deployment. client = Forcex.Client.login |> Forcex.Client.locate_services """ def login(config \\ default_config()) do login(config, %__MODULE__{endpoint: config[:endpoint] || @default_endpoint}) end def login(conf, starting_struct) do Logger.debug("conf=" <> inspect(conf)) case conf do %{client_id: _} -> struct(__MODULE__, Forcex.Auth.OAuth.login(conf, starting_struct)) %{security_token: _} -> struct(__MODULE__, Forcex.Auth.SessionId.login(conf, starting_struct)) end end def locate_services(client) do services = Forcex.services(client) client = %{client | services: services} Logger.debug(inspect(client)) client end def default_config() do [:username, :password, :security_token, :client_id, :client_secret, :endpoint] |> Enum.map(&({&1, get_val_from_env(&1)})) |> Enum.filter(fn {_, v} -> v end) |> Enum.into(%{}) end defp get_val_from_env(key) do key |> env_var |> System.get_env |> case do nil -> Application.get_env(:forcex, __MODULE__, []) |> Keyword.get(key) val -> val end end defp env_var(key), do: "SALESFORCE_#{key |> to_string |> String.upcase}" end