# HG changeset patch # User Kim Alvefur # Date 1683568894 -7200 # Node ID 92ad8f03f225650c351ca5fd16a7e1762dcbec5e # Parent b40299bbdf14e7254ce81f26d330cff61cf524b0 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. diff -r b40299bbdf14 -r 92ad8f03f225 mod_auth_oauth_external/README.md --- 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 diff -r b40299bbdf14 -r 92ad8f03f225 mod_auth_oauth_external/mod_auth_oauth_external.lua --- 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