# HG changeset patch # User magicfelix # Date 1745087557 -7200 # Node ID ab14e7ecb82f556eaad4d057e17bb15dac835523 # Parent a931a95e363e0fc4a56f10c5ccbbc382bfa6e04c mod_http_oauth2: Allow JIDs as username for password grant diff -r a931a95e363e -r ab14e7ecb82f mod_http_oauth2/README.md --- a/mod_http_oauth2/README.md Sat Apr 19 18:30:57 2025 +0200 +++ b/mod_http_oauth2/README.md Sat Apr 19 20:32:37 2025 +0200 @@ -86,6 +86,15 @@ oauth2_security_policy = "default-src 'self'" -- this is the default ``` +For the Resource Owner Password Grant the `username` is expected to be the only +localpart by default. If the OAuth client includes the domainpart in the +`username` it submits (e.g. user@example.org instead of just user), set this to +`true`. Note that this requires all clients to follow this format. + +```lua +oauth2_expect_username_jid = false +``` + ### Token parameters The following options configure the lifetime of tokens issued by the module. diff -r a931a95e363e -r ab14e7ecb82f mod_http_oauth2/mod_http_oauth2.lua --- a/mod_http_oauth2/mod_http_oauth2.lua Sat Apr 19 18:30:57 2025 +0200 +++ b/mod_http_oauth2/mod_http_oauth2.lua Sat Apr 19 20:32:37 2025 +0200 @@ -134,6 +134,7 @@ local pkce_required = module:get_option_boolean("oauth2_require_code_challenge", true); local respect_prompt = module:get_option_boolean("oauth2_respect_oidc_prompt", false); +local expect_username_jid = module:get_option_boolean("oauth2_expect_username_jid", false); local verification_key; local sign_client, verify_client; @@ -419,7 +420,21 @@ return oauth_error("invalid_client", "incorrect credentials"); end - local request_username = assert(params.username, oauth_error("invalid_request", "missing 'username'")); + local request_username + + if expect_username_jid then + local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)")); + local _request_username, request_host, request_resource = jid.prepped_split(request_jid); + + if not (_request_username and request_host) or request_host ~= module.host then + return oauth_error("invalid_request", "invalid JID"); + end + + request_username = _request_username + else + request_username = assert(params.username, oauth_error("invalid_request", "missing 'username'")); + end + local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'")); if not usermanager.test_password(request_username, module.host, request_password) then