From 3192a3c1f23fdda841ff71d7c078d9736a2da65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20M=C3=A4nnchen?= Date: Sat, 3 Oct 2026 13:33:43 +0200 Subject: [PATCH] Use set for provider worker ETS table Co-Authored-By: Claude Opus 5.5 (1M context) --- src/oidcc_provider_configuration_worker.erl | 2 +- ...dcc_provider_configuration_worker_test.erl | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/oidcc_provider_configuration_worker.erl b/src/oidcc_provider_configuration_worker.erl index 845e72e..e640267 100644 --- a/src/oidcc_provider_configuration_worker.erl +++ b/src/oidcc_provider_configuration_worker.erl @@ -403,7 +403,7 @@ get_ets_table_name(_Ref) -> register_ets_table(Opts) -> case maps:get(name, Opts, undefined) of {local, Name} -> - ets:new(Name, [named_table, bag, protected, {read_concurrency, true}]); + ets:new(Name, [named_table, set, protected, {read_concurrency, true}]); _OtherName -> undefined end. diff --git a/test/oidcc_provider_configuration_worker_test.erl b/test/oidcc_provider_configuration_worker_test.erl index a5ac065..7ad7e0a 100644 --- a/test/oidcc_provider_configuration_worker_test.erl +++ b/test/oidcc_provider_configuration_worker_test.erl @@ -5,6 +5,7 @@ -include_lib("eunit/include/eunit.hrl"). -include_lib("jose/include/jose_jwk.hrl"). +-include_lib("oidcc/include/oidcc_provider_configuration.hrl"). does_not_start_without_issuer_test() -> ?assertMatch( @@ -252,6 +253,72 @@ accepts_generic_plus_json_content_type_test() -> ) end). +replaces_changed_configuration_in_ets_test() -> + Name = ?FUNCTION_NAME, + Requests = atomics:new(1, []), + HttpFun = + fun + ( + get, + {"https://example.com/.well-known/openid-configuration", []}, + _HttpOpts, + _Opts, + _Profile + ) -> + Scopes = + case atomics:add_get(Requests, 1, 1) of + 1 -> [<<"openid">>]; + _ -> [<<"openid">>, <<"email">>] + end, + {ok, { + {"HTTP/1.1", 200, "OK"}, + [{"content-type", "application/json"}], + iolist_to_binary( + json:encode(#{ + issuer => <<"https://example.com">>, + jwks_uri => <<"https://example.com/keys">>, + authorization_endpoint => <<"https://example.com/authorize">>, + scopes_supported => Scopes, + response_types_supported => [<<"code">>], + subject_types_supported => [<<"public">>], + id_token_signing_alg_values_supported => [<<"RS256">>] + }) + ) + }}; + ( + get, + {<<"https://example.com/keys">>, []}, + _HttpOpts, + _Opts, + _Profile + ) -> + {ok, { + {"HTTP/1.1", 200, "OK"}, + [{"content-type", "application/json"}], + iolist_to_binary(json:encode(#{keys => []})) + }} + end, + + with_httpc_mock(HttpFun, fun() -> + with_live_provider_worker( + #{ + issuer => <<"https://example.com">>, + name => {local, Name} + }, + fun(_Pid) -> + ok = oidcc_provider_configuration_worker:refresh_configuration(Name), + ?assertMatch( + [ + {provider_configuration, #oidcc_provider_configuration{ + scopes_supported = [<<"openid">>, <<"email">>] + }} + ], + ets:lookup(Name, provider_configuration) + ) + end + ) + end). + with_httpc_mock(HttpFun, TestFun) -> ok = meck:new(httpc, [no_link]), try