Diff

mod_oidc_userinfo_vcard4/mod_oidc_userinfo_vcard4.lua @ 5350:f8ec43db580b

mod_oidc_userinfo_vcard4: Provide profile details in mod_http_oauth2
author Kim Alvefur <zash@zash.se>
date Mon, 17 Apr 2023 08:01:09 +0200
child 5360:f05de5ac219f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_oidc_userinfo_vcard4/mod_oidc_userinfo_vcard4.lua	Mon Apr 17 08:01:09 2023 +0200
@@ -0,0 +1,80 @@
+-- Provide OpenID UserInfo data to mod_http_oauth2
+-- Alternatively, separate module for the whole HTTP endpoint?
+--
+local nodeprep = require "util.encodings".stringprep.nodeprep;
+
+local mod_pep = module:depends "pep";
+
+local gender_map = { M = "male"; F = "female"; O = "other"; N = "nnot applicable"; U = "unknown" }
+
+module:hook("token/userinfo", function(event)
+	local pep_service = mod_pep.get_pep_service(event.username);
+
+	local vcard4 = select(3, pep_service:get_last_item("urn:xmpp:vcard4", true));
+
+	local userinfo = event.userinfo;
+	if vcard4 and event.claims:contains("profile") then
+		userinfo.name = vcard4:find("fn/text#");
+		userinfo.family_name = vcard4:find("n/surname#");
+		userinfo.given_name = vcard4:find("n/given#");
+		userinfo.middle_name = vcard4:find("n/additional#");
+
+		userinfo.nickname = vcard4:find("nickname/text#");
+		if not userinfo.nickname then
+			local ok, _, nick_item = pep_service:get_last_item("http://jabber.org/protocol/nick", true);
+			if ok and nick_item then
+				userinfo.nickname = nick_item:get_child_text("nick", "http://jabber.org/protocol/nick");
+			end
+		end
+
+		userinfo.preferred_username = event.username;
+
+		-- profile -- page? not their website
+		-- picture -- mod_http_pep_avatar?
+		userinfo.website = vcard4:find("url/uri#");
+		userinfo.birthdate = vcard4:find("bday/date#");
+		userinfo.zoneinfo = vcard4:find("tz/text#");
+		userinfo.locale = vcard4:find("lang/language-tag#");
+
+		userinfo.gender = gender_map[vcard4:find("gender/sex#")] or vcard4:find("gender/text#");
+
+		-- updated_at -- we don't keep a vcard change timestamp?
+	end
+
+	if not userinfo.nickname and event.claims:contains("profile") then
+		local ok, _, nick_item = pep_service:get_last_item("http://jabber.org/protocol/nick", true);
+		if ok and nick_item then
+			userinfo.nickname = nick_item:get_child_text("nick", "http://jabber.org/protocol/nick");
+		end
+	end
+
+	if vcard4 and event.claims:contains("email") then
+		userinfo.email = vcard4:find("email/text#")
+		if userinfo.email then
+			userinfo.email_verified = false;
+		end
+	end
+
+	if vcard4 and event.claims:contains("address") then
+		local adr = vcard4:get_child("adr");
+		if adr then
+			userinfo.address = {
+				formatted = nil;
+				street_address = adr:get_child_text("street");
+				locality = adr:get_child_text("locality");
+				region = adr:get_child_text("region");
+				postal_code = adr:get_child_text("code");
+				country = adr:get_child_text("country");
+			}
+		end
+	end
+
+	if vcard4 and event.claims:contains("phone") then
+		userinfo.phone = vcard4:find("email/text#")
+		if userinfo.phone then
+			userinfo.phone_number_verified = false;
+		end
+	end
+
+
+end, 10);