|
| 1 | +defmodule Cadet.Auth.Providers.CAS do |
| 2 | + @moduledoc """ |
| 3 | + Provides identity using CAS Protocol. |
| 4 | + https://apereo.github.io/cas/6.5.x/protocol/CAS-Protocol.html |
| 5 | + """ |
| 6 | + |
| 7 | + alias Cadet.Auth.Provider |
| 8 | + |
| 9 | + @behaviour Provider |
| 10 | + |
| 11 | + @type config :: %{service_validate_endpoint: String.t(), modules: %{}} |
| 12 | + |
| 13 | + @spec authorise(config(), Provider.code(), Provider.client_id(), Provider.redirect_uri()) :: |
| 14 | + {:ok, %{token: Provider.token(), username: String.t()}} |
| 15 | + | {:error, Provider.error(), String.t()} |
| 16 | + def authorise(config, code, _client_id, redirect_uri) do |
| 17 | + params = %{ |
| 18 | + ticket: code, |
| 19 | + service: redirect_uri |
| 20 | + } |
| 21 | + |
| 22 | + with {:validate, {:ok, %{body: body, status_code: 200}}} <- |
| 23 | + {:validate, HTTPoison.get(config.service_validate_endpoint, [], params: params)}, |
| 24 | + {:validation_response, data} <- {:validation_response, Jason.decode!(body)}, |
| 25 | + {:extract_username, %{"name" => username}} <- {:extract_username, data} do |
| 26 | + IO.inspect(data) |
| 27 | + {:ok, %{token: data, username: username}} |
| 28 | + else |
| 29 | + {:validate, {:ok, %{body: body, status_code: status}}} -> |
| 30 | + {:error, :upstream, "Status code #{status} from CAS: #{body}"} |
| 31 | + end |
| 32 | + end |
| 33 | + |
| 34 | + @spec get_name(config(), Provider.token()) :: |
| 35 | + {:ok, String.t()} | {:error, Provider.error(), String.t()} |
| 36 | + def get_name(_config, token) do |
| 37 | + %{"name" => name} = token |
| 38 | + {:ok, name} |
| 39 | + rescue |
| 40 | + _ -> |
| 41 | + {:error, :invalid_credentials, "Failed to retrieve user's name"} |
| 42 | + end |
| 43 | +end |
0 commit comments