Skip to content

Commit e039384

Browse files
committed
Create NUS Entra ID claim extractor
1 parent 626d425 commit e039384

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
defmodule Cadet.Auth.Providers.NusEntraIdClaimExtractor do
2+
@moduledoc """
3+
Extracts fields from NUS' Microsoft Entra ID JWTs.
4+
"""
5+
6+
@behaviour Cadet.Auth.Providers.OpenID.ClaimExtractor
7+
8+
@dialyzer {:nowarn_function, get_username: 2}
9+
def get_username(claims, access_token) do
10+
# TODO: Remove the debug statement after confirming the claims structure
11+
Jason.decode!(claims) |> IO.inspect(label: "Claims in NUS Entra ID")
12+
get_userinfo(access_token, "samAccountName")
13+
end
14+
15+
@dialyzer {:nowarn_function, get_name: 2}
16+
def get_name(claims, access_token) do
17+
# TODO: Remove the debug statement after confirming the claims structure
18+
Jason.decode!(claims) |> IO.inspect(label: "Claims in NUS Entra ID")
19+
get_userinfo(access_token, "displayName")
20+
end
21+
22+
def get_token_type, do: "access_token"
23+
24+
# Allowed Active Directory (AD) domains; modify as needed
25+
@allowed_domains ~w(student alum staff)
26+
27+
defp check_allowed_domain(claims) do
28+
domain = Map.get(claims, "onPremisesExtensionAttributes")["extensionAttribute6"]
29+
domain in @allowed_domains
30+
end
31+
32+
defp map_key_to_raw("samAccountName"), do: "onPremisesSamAccountName"
33+
defp map_key_to_raw(key), do: key
34+
35+
defp get_userinfo(token, key) do
36+
Jason.decode!(token) |> IO.inspect(label: "Token in NUS Entra ID")
37+
headers = [{"Authorization", "Bearer #{token}"}]
38+
options = [timeout: 10_000, recv_timeout: 10_000]
39+
40+
url =
41+
"https://graph.microsoft.com/v1.0/me?$select=onPremisesSamAccountName,onPremisesExtensionAttributes"
42+
43+
case HTTPoison.get(url, headers, options) do
44+
{:ok, %{body: body, status_code: 200}} ->
45+
data = Jason.decode!(body)
46+
47+
with true <- check_allowed_domain(data),
48+
mapped_key <- map_key_to_raw(key),
49+
value when not is_nil(value) <- Map.get(data, mapped_key) do
50+
value
51+
else
52+
false -> nil
53+
nil -> nil
54+
end
55+
56+
{:ok, _} ->
57+
nil
58+
end
59+
end
60+
end

0 commit comments

Comments
 (0)