Skip to content

Commit 9eef5f2

Browse files
committed
fix handling of xml on successful validation with CAS server and update cadet.exs.example to include example CAS strategy
1 parent 156fbb0 commit 9eef5f2

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

config/cadet.exs.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ config :cadet,
5656
# # You may need to write your own claim extractor for other providers
5757
# claim_extractor: Cadet.Auth.Providers.CognitoClaimExtractor
5858
# }},
59+
# # To use authentication with CAS
60+
# "cas" =>
61+
# {Cadet.Auth.Providers.CAS,
62+
# %{service_validate_endpoint: "https://{CAS_SERVER_ENDPOINT}/serviceValidate"}},
63+
5964
"test" =>
6065
{Cadet.Auth.Providers.Config,
6166
[

lib/cadet/auth/providers/cas.ex

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ defmodule Cadet.Auth.Providers.CAS do
44
https://apereo.github.io/cas/6.5.x/protocol/CAS-Protocol.html
55
"""
66

7+
import SweetXml
8+
79
alias Cadet.Auth.Provider
810

911
@behaviour Provider
@@ -20,24 +22,37 @@ defmodule Cadet.Auth.Providers.CAS do
2022
}
2123

2224
with {:validate, {:ok, %{body: body, status_code: 200}}} <-
23-
{:validate, HTTPoison.get(config.service_validate_endpoint, [], params: params)} do
24-
# {:validation_response, data} <- {:validation_response, Jason.decode!(body)},
25-
# {:extract_username, %{"name" => username}} <- {:extract_username, data} do
26-
IO.inspect(body)
27-
{:ok, %{token: body, username: "placeholder"}}
25+
{:validate, HTTPoison.get(config.service_validate_endpoint, [], params: params)},
26+
{:authentication_success, success_xml} when not is_nil(success_xml) <-
27+
{:authentication_success, authentication_success(body)},
28+
{:extract_username, username} <- {:extract_username, get_username(success_xml)} do
29+
{:ok, %{token: success_xml, username: username}}
2830
else
2931
{:validate, {:ok, %{body: body, status_code: status}}} ->
3032
{:error, :upstream, "Status code #{status} from CAS: #{body}"}
33+
34+
{:authentication_success, nil} ->
35+
{:error, :upstream, "Authentication failure from CAS"}
3136
end
3237
end
3338

3439
@spec get_name(config(), Provider.token()) ::
3540
{:ok, String.t()} | {:error, Provider.error(), String.t()}
3641
def get_name(_config, token) do
37-
%{"name" => name} = token
42+
name = get_username(token)
3843
{:ok, name}
3944
rescue
4045
_ ->
4146
{:error, :invalid_credentials, "Failed to retrieve user's name"}
4247
end
48+
49+
defp authentication_success(xml) do
50+
xml
51+
|> xpath(~x"//cas:serviceResponse/cas:authenticationSuccess"e)
52+
end
53+
54+
defp get_username(xml) do
55+
xml
56+
|> xpath(~x"//cas:user/text()"s)
57+
end
4358
end

0 commit comments

Comments
 (0)