Software /
code /
prosody-modules
Diff
mod_http_oauth2/mod_http_oauth2.lua @ 5663:f6e8165a2ec2
Merge upstream
author | Trần H. Trung <xmpp:trần.h.trung@trung.fun> |
---|---|
date | Tue, 29 Aug 2023 22:46:27 +0700 |
parent | 5651:dd2079b3dec6 |
child | 5665:7c105277a9ca |
line wrap: on
line diff
--- a/mod_http_oauth2/mod_http_oauth2.lua Tue Aug 01 01:27:45 2023 +0700 +++ b/mod_http_oauth2/mod_http_oauth2.lua Tue Aug 29 22:46:27 2023 +0700 @@ -394,15 +394,19 @@ return oauth_error("invalid_request", "PKCE required"); end + local prefix = "authorization_code:"; local code = id.medium(); if params.redirect_uri == device_uri then local is_device, device_state = verify_device_token(params.state); if is_device then -- reconstruct the device_code + prefix = "device_code:"; code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code)); + else + return oauth_error("invalid_request"); end end - local ok = codes:set("authorization_code:" .. params.client_id .. "#" .. code, { + local ok = codes:set(prefix.. params.client_id .. "#" .. code, { expires = os.time() + 600; granted_jid = granted_jid; granted_scopes = granted_scopes; @@ -578,7 +582,7 @@ return oauth_error("invalid_client", "incorrect credentials"); end - local code = codes:get("device_code:" .. params.device_code); + local code = codes:get("device_code:" .. params.client_id .. "#" .. params.device_code); if type(code) ~= "table" or code_expired(code) then return oauth_error("expired_token"); elseif code.error then @@ -586,7 +590,7 @@ elseif not code.granted_jid then return oauth_error("authorization_pending"); end - codes:set("device_code:" .. params.device_code, nil); + codes:set("device_code:" .. params.client_id .. "#" .. params.device_code, nil); return json.encode(new_access_token(code.granted_jid, code.granted_role, code.granted_scopes, client, code.id_token)); end @@ -991,9 +995,10 @@ local verification_uri = module:http_url() .. "/device"; local verification_uri_complete = verification_uri .. "?" .. http.formencode({ user_code = user_code }); - local dc_ok = codes:set("device_code:" .. params.client_id .. "#" .. device_code, { expires = os.time() + 1200 }); + local expires = os.time() + 600; + local dc_ok = codes:set("device_code:" .. params.client_id .. "#" .. device_code, { expires = expires }); local uc_ok = codes:set("user_code:" .. user_code, - { user_code = user_code; expires = os.time() + 600; client_id = params.client_id; + { user_code = user_code; expires = expires; client_id = params.client_id; scope = requested_scopes:concat(" ") }); if not dc_ok or not uc_ok then return oauth_error("temporarily_unavailable"); @@ -1041,6 +1046,8 @@ } end +local strict_auth_revoke = module:get_option_boolean("oauth2_require_auth_revoke", false); + local function handle_revocation_request(event) local request, response = event.request, event.response; response.headers.cache_control = "no-store"; @@ -1055,6 +1062,11 @@ if not verify_client_secret(credentials.username, credentials.password) then return 401; end + -- TODO check that it's their token I guess? + elseif strict_auth_revoke then + -- Why require auth to revoke a leaked token? + response.headers.www_authenticate = string.format("Basic realm=%q", module.host.."/"..module.name); + return 401; end local form_data = strict_formdecode(event.request.body); @@ -1224,6 +1236,16 @@ return nil, oauth_error("invalid_request", "Failed schema validation."); end + local client_uri = url.parse(client_metadata.client_uri); + if not client_uri or client_uri.scheme ~= "https" or loopbacks:contains(client_uri.host) then + return nil, oauth_error("invalid_client_metadata", "Missing, invalid or insecure client_uri"); + end + + if not client_metadata.application_type and redirect_uri_allowed(client_metadata.redirect_uris[1], client_uri, "native") then + client_metadata.application_type = "native"; + -- else defaults to "web" + end + -- Fill in default values for propname, propspec in pairs(registration_schema.properties) do if client_metadata[propname] == nil and type(propspec) == "table" and propspec.default ~= nil then @@ -1238,11 +1260,6 @@ end end - local client_uri = url.parse(client_metadata.client_uri); - if not client_uri or client_uri.scheme ~= "https" or loopbacks:contains(client_uri.host) then - return nil, oauth_error("invalid_client_metadata", "Missing, invalid or insecure client_uri"); - end - for _, redirect_uri in ipairs(client_metadata.redirect_uris) do if not redirect_uri_allowed(redirect_uri, client_uri, client_metadata.application_type) then return nil, oauth_error("invalid_redirect_uri", "Invalid, insecure or inappropriate redirect URI.");