Skip to content

Commit

Permalink
Merge pull request #30 from jeffweiss/fix_login_encoding
Browse files Browse the repository at this point in the history
HTML encode SOAP login info
  • Loading branch information
mmrobins authored Mar 20, 2018
2 parents 0e1896d + 59f4da2 commit de644bc
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 13 deletions.
6 changes: 5 additions & 1 deletion lib/forcex/auth/session_id.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ defmodule Forcex.Auth.SessionId do
schema_instance = "http://www.w3.org/2001/XMLSchema-instance"
env = "http://schemas.xmlsoap.org/soap/envelope/"

# Encode otherwise response comes back with error like
# UNKNOWN_EXCEPTION: The reference to entity "v4Hq" must end with the ';' delimiter.
conf = for {key, val} <- conf, into: %{}, do: {key, HtmlEntities.encode(val)}

body = """
<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="#{schema}" xmlns:xsi="#{schema_instance}" xmlns:env="#{env}">
Expand All @@ -29,7 +33,7 @@ defmodule Forcex.Auth.SessionId do
{"SOAPAction", "login"}
]

url = "https://login.salesforce.com/services/Soap/u/#{starting_struct.api_version}"
url = starting_struct.endpoint <> "/services/Soap/u/#{starting_struct.api_version}"

Logger.debug("api=#{@api}")
@api.raw_request(:post, url, body, headers, [])
Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ defmodule Forcex.Mixfile do
{:earmark, "~> 1.1", only: :dev, override: true},
{:dialyxir, "~> 0.4", only: :dev},
{:mox, "~> 0.3", only: :test},
{:mix_test_watch, "~> 0.5", only: [:dev, :test], runtime: false}
{:mix_test_watch, "~> 0.5", only: [:dev, :test], runtime: false},
{:html_entities, "~> 0.4"}
]
end

Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"},
"gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [], [], "hexpm"},
"hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
"httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [], [], "hexpm"},
Expand Down
38 changes: 27 additions & 11 deletions test/forcex/client_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,49 @@ defmodule Forcex.ClientTest do
setup :verify_on_exit!

describe "session_id based login" do
test "sets the auth header and endpoint when successful" do
session_id = "forcex_session_id"
server_url = "https://forcex.my.salesforce.com/services/Soap/u/41.0/00Dd0000000cQ8L"
org_id = "org_id"

response = """
<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns=\"urn:partner.soap.sforce.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body><loginResponse><result><metadataServerUrl>#{server_url}</metadataServerUrl><passwordExpired>false</passwordExpired><sandbox>false</sandbox><serverUrl>#{server_url}</serverUrl><sessionId>#{session_id}</sessionId><userId>005d0000001Jb9tAAC</userId><userInfo><accessibilityMode>false</accessibilityMode><chatterExternal>false</chatterExternal><currencySymbol>$</currencySymbol><orgAttachmentFileSizeLimit>5242880</orgAttachmentFileSizeLimit><orgDefaultCurrencyIsoCode>USD</orgDefaultCurrencyIsoCode><orgDefaultCurrencyLocale>en_US</orgDefaultCurrencyLocale><orgDisallowHtmlAttachments>false</orgDisallowHtmlAttachments><orgHasPersonAccounts>true</orgHasPersonAccounts><organizationId>#{org_id}</organizationId><organizationMultiCurrency>false</organizationMultiCurrency><organizationName>MY-ORG</organizationName><profileId>00ed0000000Ods2AAC</profileId><roleId>00Ed0000000II8UEAW</roleId><sessionSecondsValid>7200</sessionSecondsValid><userDefaultCurrencyIsoCode xsi:nil=\"true\"/><userEmail>forcex@example.com</userEmail><userFullName>John Doe</userFullName><userId>005d0000001Jb9tAAC</userId><userLanguage>en_US</userLanguage><userLocale>en_US</userLocale><userName>forcex@example.com</userName><userTimeZone>America/New_York</userTimeZone><userType>Standard</userType><userUiSkin>Theme3</userUiSkin></userInfo></result></loginResponse></soapenv:Body></soapenv:Envelope>
@session_id "forcex_session_id"
@server_url "https://forcex.my.salesforce.com/services/Soap/u/41.0/00Dd0000000cQ8L"
@org_id "org_id"
@response """
<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns=\"urn:partner.soap.sforce.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body><loginResponse><result><metadataServerUrl>#{@server_url}</metadataServerUrl><passwordExpired>false</passwordExpired><sandbox>false</sandbox><serverUrl>#{@server_url}</serverUrl><sessionId>#{@session_id}</sessionId><userId>005d0000001Jb9tAAC</userId><userInfo><accessibilityMode>false</accessibilityMode><chatterExternal>false</chatterExternal><currencySymbol>$</currencySymbol><orgAttachmentFileSizeLimit>5242880</orgAttachmentFileSizeLimit><orgDefaultCurrencyIsoCode>USD</orgDefaultCurrencyIsoCode><orgDefaultCurrencyLocale>en_US</orgDefaultCurrencyLocale><orgDisallowHtmlAttachments>false</orgDisallowHtmlAttachments><orgHasPersonAccounts>true</orgHasPersonAccounts><organizationId>#{@org_id}</organizationId><organizationMultiCurrency>false</organizationMultiCurrency><organizationName>MY-ORG</organizationName><profileId>00ed0000000Ods2AAC</profileId><roleId>00Ed0000000II8UEAW</roleId><sessionSecondsValid>7200</sessionSecondsValid><userDefaultCurrencyIsoCode xsi:nil=\"true\"/><userEmail>forcex@example.com</userEmail><userFullName>John Doe</userFullName><userId>005d0000001Jb9tAAC</userId><userLanguage>en_US</userLanguage><userLocale>en_US</userLocale><userName>forcex@example.com</userName><userTimeZone>America/New_York</userTimeZone><userType>Standard</userType><userUiSkin>Theme3</userUiSkin></userInfo></result></loginResponse></soapenv:Body></soapenv:Envelope>
"""

Forcex.Api.MockHttp
|> expect(:raw_request, fn :post, _, _, _, _ -> response end)

test "sets the auth header and endpoint when successful" do
config = %{
password: "password",
security_token: "security_token",
username: "forcex@example.com"
}

Forcex.Api.MockHttp
|> expect(:raw_request, fn :post, _, _, _, _ -> @response end)

client = Forcex.Client.login(config)

assert client.authorization_header == [{
"Authorization",
"Bearer #{session_id}"
"Bearer #{@session_id}"
}]

assert client.endpoint == "https://forcex.my.salesforce.com/"
end

test "login info is HTML encoded" do
config = %{
password: "amper&and",
security_token: "flash!",
username: "<<probablynotvalid>>@example.com"
}

encoded_config = for {key, val} <- config, into: %{}, do: {key, HtmlEntities.encode(val)}

expected_body = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n<env:Body>\n<n1:login xmlns:n1=\"urn:partner.soap.sforce.com\">\n <n1:username>&lt;&lt;probablynotvalid&gt;&gt;@example.com</n1:username>\n <n1:password>amper&amp;andflash!</n1:password>\n</n1:login>\n</env:Body>\n</env:Envelope>\n"

Forcex.Api.MockHttp
|> expect(:raw_request, fn :post, _, ^expected_body, _, _ -> @response end)

client = Forcex.Client.login(config)
end
end

describe "oauth based login" do
Expand Down

0 comments on commit de644bc

Please sign in to comment.