Software /
code /
prosody-modules
Diff
mod_http_oauth2/mod_http_oauth2.lua @ 6245:ea58d2893afb draft default tip
Merge update
author | Trần H. Trung <xmpp:trần.h.trung@trung.fun> |
---|---|
date | Tue, 29 Apr 2025 23:27:06 +0700 |
parent | 6211:750d64c47ec6 |
parent | 6240:ab14e7ecb82f |
line wrap: on
line diff
--- a/mod_http_oauth2/mod_http_oauth2.lua Fri Apr 11 23:19:21 2025 +0700 +++ b/mod_http_oauth2/mod_http_oauth2.lua Tue Apr 29 23:27:06 2025 +0700 @@ -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; @@ -397,21 +398,52 @@ return oauth_error("invalid_request"); end +local function make_client_secret(client_id) --> client_secret + return hashes.hmac_sha256(verification_key, client_id, true); +end + +local function verify_client_secret(client_id, client_secret) + return hashes.equals(make_client_secret(client_id), client_secret); +end + function grant_type_handlers.password(params) - local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)")); - local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'")); - local request_username, request_host, request_resource = jid.prepped_split(request_jid); + if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end + if not params.client_secret then return oauth_error("invalid_request", "missing 'client_secret'"); end + + local client = check_client(params.client_id); + if not client then + return oauth_error("invalid_client", "incorrect credentials"); + end - if not (request_username and request_host) or request_host ~= module.host then - return oauth_error("invalid_request", "invalid JID"); + if not verify_client_secret(params.client_id, params.client_secret) then + module:log("debug", "client_secret mismatch"); + return oauth_error("invalid_client", "incorrect credentials"); end - if not usermanager.test_password(request_username, request_host, request_password) then + + 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 return oauth_error("invalid_grant", "incorrect credentials"); end - local granted_jid = jid.join(request_username, request_host, request_resource); + local granted_jid = jid.join(request_username, module.host); local granted_scopes, granted_role = filter_scopes(request_username, params.scope); - return json.encode(new_access_token(granted_jid, granted_role, granted_scopes, nil)); + return json.encode(new_access_token(granted_jid, granted_role, granted_scopes, client)); end function response_type_handlers.code(client, params, granted_jid, id_token) @@ -505,14 +537,6 @@ } end -local function make_client_secret(client_id) --> client_secret - return hashes.hmac_sha256(verification_key, client_id, true); -end - -local function verify_client_secret(client_id, client_secret) - return hashes.equals(make_client_secret(client_id), client_secret); -end - function grant_type_handlers.authorization_code(params) if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end if not params.client_secret then return oauth_error("invalid_request", "missing 'client_secret'"); end