Comparison

mod_http_oauth2/mod_http_oauth2.lua @ 6282:7b3316ac24b3

mod_http_oauth2: Refactor client grant and response type checks Iterating over an array instead of creating a Set ought to create fewer short-lived tables. The arrays are usually very short so shouldn't be a performance issue. Moves validation earlier as to do less work before discovering that it can't proceed anyway.
author Kim Alvefur <zash@zash.se>
date Mon, 02 Jun 2025 22:21:44 +0200
parent 6281:9d88c3d9eea5
child 6285:b460b2a65f0b
comparison
equal deleted inserted replaced
6281:9d88c3d9eea5 6282:7b3316ac24b3
840 else 840 else
841 module:log("debug", "Challenge method %q enabled", handler_type); 841 module:log("debug", "Challenge method %q enabled", handler_type);
842 end 842 end
843 end 843 end
844 844
845 local function array_contains(haystack, needle)
846 for _, item in ipairs(haystack) do
847 if item == needle then
848 return true
849 end
850 end
851 return false
852 end
853
845 function handle_token_grant(event) 854 function handle_token_grant(event)
846 local credentials = get_request_credentials(event.request); 855 local credentials = get_request_credentials(event.request);
847 856
848 event.response.headers.content_type = "application/json"; 857 event.response.headers.content_type = "application/json";
849 event.response.headers.cache_control = "no-store"; 858 event.response.headers.cache_control = "no-store";
872 return oauth_error("invalid_client", "incorrect credentials"); 881 return oauth_error("invalid_client", "incorrect credentials");
873 end 882 end
874 883
875 884
876 local grant_type = params.grant_type 885 local grant_type = params.grant_type
886 if not array_contains(client.grant_types or { "authorization_code" }, grant_type) then
887 return oauth_error("invalid_request", "'grant_type' not registered");
888 end
889
877 local grant_handler = grant_type_handlers[grant_type]; 890 local grant_handler = grant_type_handlers[grant_type];
878 if not grant_handler then 891 if not grant_handler then
879 return oauth_error("invalid_request", "No such grant type."); 892 return oauth_error("invalid_request", "'grant_type' not available");
880 end
881
882 local grant_type_allowed = false;
883 for _, client_grant_type in ipairs(client.grant_types or { "authorization_code" }) do
884 if client_grant_type == grant_type then
885 grant_type_allowed = true;
886 break
887 end
888 end
889
890 if not grant_type_allowed then
891 return oauth_error("invalid_request", "'grant_type' not registered");
892 end 893 end
893 894
894 return grant_handler(params, client); 895 return grant_handler(params, client);
895 end 896 end
896 897
920 if not redirect_uri then 921 if not redirect_uri then
921 return render_error(oauth_error("invalid_request", "Invalid 'redirect_uri' parameter")); 922 return render_error(oauth_error("invalid_request", "Invalid 'redirect_uri' parameter"));
922 end 923 end
923 -- From this point we know that redirect_uri is safe to use 924 -- From this point we know that redirect_uri is safe to use
924 925
925 local client_response_types = set.new(array(client.response_types or { "code" })); 926 local response_type = params.response_type;
926 client_response_types = set.intersection(client_response_types, allowed_response_type_handlers); 927 if not array_contains(client.response_types or { "code" }, response_type) then
927 if not client_response_types:contains(params.response_type) then 928 return error_response(request, redirect_uri, oauth_error("invalid_client", "'response_type' not registered"));
928 return error_response(request, redirect_uri, oauth_error("invalid_client", "'response_type' not allowed")); 929 end
930 if not allowed_response_type_handlers:contains(response_type) then
931 return error_response(request, redirect_uri, oauth_error("unsupported_response_type", "'response_type' not allowed"));
932 end
933 local response_handler = response_type_handlers[response_type];
934 if not response_handler then
935 return error_response(request, redirect_uri, oauth_error("unsupported_response_type"));
929 end 936 end
930 937
931 local requested_scopes = parse_scopes(params.scope or ""); 938 local requested_scopes = parse_scopes(params.scope or "");
932 if client.scope then 939 if client.scope then
933 local client_scopes = set.new(parse_scopes(client.scope)); 940 local client_scopes = set.new(parse_scopes(client.scope));
1022 aud = params.client_id; 1029 aud = params.client_id;
1023 auth_time = auth_state.user.iat; 1030 auth_time = auth_state.user.iat;
1024 nonce = params.nonce; 1031 nonce = params.nonce;
1025 amr = auth_state.user.amr; 1032 amr = auth_state.user.amr;
1026 }); 1033 });
1027 local response_type = params.response_type;
1028 local response_handler = response_type_handlers[response_type];
1029 if not response_handler then
1030 return error_response(request, redirect_uri, oauth_error("unsupported_response_type"));
1031 end
1032 local ret = response_handler(client, params, user_jid, id_token); 1034 local ret = response_handler(client, params, user_jid, id_token);
1033 if errors.is_err(ret) then 1035 if errors.is_err(ret) then
1034 return error_response(request, redirect_uri, ret); 1036 return error_response(request, redirect_uri, ret);
1035 end 1037 end
1036 return ret; 1038 return ret;