Changeset

5434:92ad8f03f225

mod_auth_oauth_external: Work without token validation endpoint In this mode, only PLAIN is possible and the provided username is assumed to be the XMPP localpart.
author Kim Alvefur <zash@zash.se>
date Mon, 08 May 2023 20:01:34 +0200
parents 5433:b40299bbdf14
children 5435:b3e7886fea6a
files mod_auth_oauth_external/README.md mod_auth_oauth_external/mod_auth_oauth_external.lua
diffstat 2 files changed, 28 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/mod_auth_oauth_external/README.md	Mon May 08 19:57:10 2023 +0200
+++ b/mod_auth_oauth_external/README.md	Mon May 08 20:01:34 2023 +0200
@@ -50,6 +50,8 @@
     logging in the field specified by `oauth_external_username_field`.
     Commonly the [OpenID `UserInfo`
     endpoint](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
+    If left unset, only `SASL PLAIN` is supported and the username
+    provided there is assumed correct.
 
 `oauth_external_username_field`
 :   String. Default is `"preferred_username"`. Field in the JSON
--- a/mod_auth_oauth_external/mod_auth_oauth_external.lua	Mon May 08 19:57:10 2023 +0200
+++ b/mod_auth_oauth_external/mod_auth_oauth_external.lua	Mon May 08 20:01:34 2023 +0200
@@ -53,6 +53,12 @@
 			if not token_resp or string.lower(token_resp.token_type or "") ~= "bearer" then
 				return false, nil;
 			end
+			if not validation_endpoint then
+				-- We're not going to get more info, only the username
+				self.username = jid.escape(username);
+				self.token_info = token_resp;
+				return true, true;
+			end
 			local ret, err = async.wait_for(self.profile.http_client:request(validation_endpoint,
 				{ headers = { ["Authorization"] = "Bearer " .. token_resp.access_token; ["Accept"] = "application/json" } }));
 			if err then
@@ -73,25 +79,28 @@
 			return true, true;
 		end
 	end
-	function profile:oauthbearer(token)
-		if token == "" then
-			return false, nil, extra;
-		end
+	if validation_endpoint then
+		function profile:oauthbearer(token)
+			if token == "" then
+				return false, nil, extra;
+			end
 
-		local ret, err = async.wait_for(self.profile.http_client:request(validation_endpoint,
-			{ headers = { ["Authorization"] = "Bearer " .. token; ["Accept"] = "application/json" } }));
-		if err then
-			return false, nil, extra;
+			local ret, err = async.wait_for(self.profile.http_client:request(validation_endpoint, {
+				headers = { ["Authorization"] = "Bearer " .. token; ["Accept"] = "application/json" };
+			}));
+			if err then
+				return false, nil, extra;
+			end
+			local response = ret and json.decode(ret.body);
+			if not (ret.code >= 200 and ret.code < 300) then
+				return false, nil, response or extra;
+			end
+			if type(response) ~= "table" or type(response[username_field]) ~= "string" then
+				return false, nil, nil;
+			end
+
+			return response[username_field], true, response;
 		end
-		local response = ret and json.decode(ret.body);
-		if not (ret.code >= 200 and ret.code < 300) then
-			return false, nil, response or extra;
-		end
-		if type(response) ~= "table" or type(response[username_field]) ~= "string" then
-			return false, nil, nil;
-		end
-
-		return response[username_field], true, response;
 	end
 	return sasl.new(host, profile);
 end