# HG changeset patch # User Kim Alvefur # Date 1689764284 -7200 # Node ID ad9b8f659c96faa57a7f75f4890be14906b513dc # Parent 39bb7232326dc5466135fae0c7850cf6485234bf mod_http_oauth2: Namespace the various codes to minimize confusion Both for the programmer and in OAuth flows. While unlikely, it should not be possible to cause weirdness e.g. by typing a client id and authorization code into the device code entry. diff -r 39bb7232326d -r ad9b8f659c96 mod_http_oauth2/mod_http_oauth2.lua --- a/mod_http_oauth2/mod_http_oauth2.lua Mon Jul 17 16:40:45 2023 +0200 +++ b/mod_http_oauth2/mod_http_oauth2.lua Wed Jul 19 12:58:04 2023 +0200 @@ -398,7 +398,7 @@ code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code)); end end - local ok = codes:set(params.client_id .. "#" .. code, { + local ok = codes:set("authorization_code:" .. params.client_id .. "#" .. code, { expires = os.time() + 600; granted_jid = granted_jid; granted_scopes = granted_scopes; @@ -491,12 +491,12 @@ module:log("debug", "client_secret mismatch"); return oauth_error("invalid_client", "incorrect credentials"); end - local code, err = codes:get(params.client_id .. "#" .. params.code); + local code, err = codes:get("authorization_code:" .. params.client_id .. "#" .. params.code); if err then error(err); end -- MUST NOT use the authorization code more than once, so remove it to -- prevent a second attempted use -- TODO if a second attempt *is* made, revoke any tokens issued - codes:set(params.client_id .. "#" .. params.code, nil); + codes:set("authorization_code:" .. params.client_id .. "#" .. params.code, nil); if not code or type(code) ~= "table" or code_expired(code) then module:log("debug", "authorization_code invalid or expired: %q", code); return oauth_error("invalid_client", "incorrect credentials"); @@ -574,7 +574,7 @@ return oauth_error("invalid_client", "incorrect credentials"); end - local code = codes:get(params.client_id .. "#" .. params.device_code); + local code = codes:get("device_code:" .. params.device_code); if type(code) ~= "table" or code_expired(code) then return oauth_error("expired_token"); elseif code.error then @@ -582,7 +582,7 @@ elseif not code.granted_jid then return oauth_error("authorization_pending"); end - codes:set(client.client_hash .. "#" .. params.device_code, nil); + codes:set("device_code:" .. params.device_code, nil); return json.encode(new_access_token(code.granted_jid, code.granted_role, code.granted_scopes, client, code.id_token)); end @@ -882,10 +882,10 @@ local is_device, device_state = verify_device_token(params.state); if is_device then local device_code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code)); - local code = codes:get(params.client_id .. "#" .. device_code); + local code = codes:get("device_code:" .. params.client_id .. "#" .. device_code); code.error = oauth_error("access_denied"); code.expires = os.time() + 60; - codes:set(params.client_id .. "#" .. device_code, code); + codes:set("device_code:" .. params.client_id .. "#" .. device_code, code); end end return error_response(request, redirect_uri, oauth_error("access_denied")); @@ -969,7 +969,7 @@ -- screen onto a phone local user_code = (id.tiny() .. "-" .. id.tiny()):upper(); local collisions = 0; - while codes:get(user_code) do + while codes:get("authorization_code:" .. device_uri .. "#" .. user_code) do collisions = collisions + 1; if collisions > 10 then return oauth_error("temporarily_unavailable"); @@ -981,8 +981,8 @@ local verification_uri = module:http_url() .. "/device"; local verification_uri_complete = verification_uri .. "?" .. http.formencode({ user_code = user_code }); - local dc_ok = codes:set(params.client_id .. "#" .. device_code, { expires = os.time() + 1200 }); - local uc_ok = codes:set(user_code, + local dc_ok = codes:set("device_code:" .. params.client_id .. "#" .. device_code, { expires = os.time() + 1200 }); + local uc_ok = codes:set("user_code:" .. user_code, { user_code = user_code; expires = os.time() + 600; client_id = params.client_id; scope = requested_scopes:concat(" ") }); if not dc_ok or not uc_ok then @@ -1009,8 +1009,8 @@ return render_page(templates.device, { client = false }); end - local device_info = codes:get(params.user_code); - if not device_info or code_expired(device_info) or not codes:set(params.user_code, nil) then + local device_info = codes:get("user_code:" .. params.user_code); + if not device_info or code_expired(device_info) or not codes:set("user_code:" .. params.user_code, nil) then return render_error(oauth_error("expired_token", "Incorrect or expired code")); end