Comparison

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
comparison
equal deleted inserted replaced
6232:d72010642b31 6245:ea58d2893afb
132 local registration_options = module:get_option("oauth2_registration_options", 132 local registration_options = module:get_option("oauth2_registration_options",
133 { default_ttl = registration_ttl; accept_expired = not registration_ttl }); 133 { default_ttl = registration_ttl; accept_expired = not registration_ttl });
134 134
135 local pkce_required = module:get_option_boolean("oauth2_require_code_challenge", true); 135 local pkce_required = module:get_option_boolean("oauth2_require_code_challenge", true);
136 local respect_prompt = module:get_option_boolean("oauth2_respect_oidc_prompt", false); 136 local respect_prompt = module:get_option_boolean("oauth2_respect_oidc_prompt", false);
137 local expect_username_jid = module:get_option_boolean("oauth2_expect_username_jid", false);
137 138
138 local verification_key; 139 local verification_key;
139 local sign_client, verify_client; 140 local sign_client, verify_client;
140 if registration_key then 141 if registration_key then
141 -- Tie it to the host if global 142 -- Tie it to the host if global
395 -- Access tokens are delivered via redirect when using the implict flow, not 396 -- Access tokens are delivered via redirect when using the implict flow, not
396 -- via the token endpoint, so how did you get here? 397 -- via the token endpoint, so how did you get here?
397 return oauth_error("invalid_request"); 398 return oauth_error("invalid_request");
398 end 399 end
399 400
401 local function make_client_secret(client_id) --> client_secret
402 return hashes.hmac_sha256(verification_key, client_id, true);
403 end
404
405 local function verify_client_secret(client_id, client_secret)
406 return hashes.equals(make_client_secret(client_id), client_secret);
407 end
408
400 function grant_type_handlers.password(params) 409 function grant_type_handlers.password(params)
401 local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)")); 410 if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end
411 if not params.client_secret then return oauth_error("invalid_request", "missing 'client_secret'"); end
412
413 local client = check_client(params.client_id);
414 if not client then
415 return oauth_error("invalid_client", "incorrect credentials");
416 end
417
418 if not verify_client_secret(params.client_id, params.client_secret) then
419 module:log("debug", "client_secret mismatch");
420 return oauth_error("invalid_client", "incorrect credentials");
421 end
422
423 local request_username
424
425 if expect_username_jid then
426 local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)"));
427 local _request_username, request_host, request_resource = jid.prepped_split(request_jid);
428
429 if not (_request_username and request_host) or request_host ~= module.host then
430 return oauth_error("invalid_request", "invalid JID");
431 end
432
433 request_username = _request_username
434 else
435 request_username = assert(params.username, oauth_error("invalid_request", "missing 'username'"));
436 end
437
402 local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'")); 438 local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'"));
403 local request_username, request_host, request_resource = jid.prepped_split(request_jid); 439
404 440 if not usermanager.test_password(request_username, module.host, request_password) then
405 if not (request_username and request_host) or request_host ~= module.host then
406 return oauth_error("invalid_request", "invalid JID");
407 end
408 if not usermanager.test_password(request_username, request_host, request_password) then
409 return oauth_error("invalid_grant", "incorrect credentials"); 441 return oauth_error("invalid_grant", "incorrect credentials");
410 end 442 end
411 443
412 local granted_jid = jid.join(request_username, request_host, request_resource); 444 local granted_jid = jid.join(request_username, module.host);
413 local granted_scopes, granted_role = filter_scopes(request_username, params.scope); 445 local granted_scopes, granted_role = filter_scopes(request_username, params.scope);
414 return json.encode(new_access_token(granted_jid, granted_role, granted_scopes, nil)); 446 return json.encode(new_access_token(granted_jid, granted_role, granted_scopes, client));
415 end 447 end
416 448
417 function response_type_handlers.code(client, params, granted_jid, id_token) 449 function response_type_handlers.code(client, params, granted_jid, id_token)
418 local request_username, request_host = jid.split(granted_jid); 450 local request_username, request_host = jid.split(granted_jid);
419 if not request_host or request_host ~= module.host then 451 if not request_host or request_host ~= module.host then
501 cache_control = "no-store"; 533 cache_control = "no-store";
502 pragma = "no-cache"; 534 pragma = "no-cache";
503 location = url.build(redirect); 535 location = url.build(redirect);
504 }; 536 };
505 } 537 }
506 end
507
508 local function make_client_secret(client_id) --> client_secret
509 return hashes.hmac_sha256(verification_key, client_id, true);
510 end
511
512 local function verify_client_secret(client_id, client_secret)
513 return hashes.equals(make_client_secret(client_id), client_secret);
514 end 538 end
515 539
516 function grant_type_handlers.authorization_code(params) 540 function grant_type_handlers.authorization_code(params)
517 if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end 541 if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end
518 if not params.client_secret then return oauth_error("invalid_request", "missing 'client_secret'"); end 542 if not params.client_secret then return oauth_error("invalid_request", "missing 'client_secret'"); end