@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1818#ifndef AUTH_OIDC_CONFIG_H
1919#define AUTH_OIDC_CONFIG_H
2020
21+ #include < picojson/picojson.h>
2122#include < chrono>
2223#include < map>
2324#include < memory>
@@ -29,16 +30,38 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
2930
3031#include < mysql/components/services/bits/system_variables_bits.h>
3132#include < mysql/plugin.h>
33+ #include < mysql/psi/psi_memory.h>
3234#include < mysql/service_thd_alloc.h>
33- #include < picojson/picojson.h>
3435
3536#include < shared_mutex>
3637#include < vector>
3738
3839#include " jwks.h"
40+ #include " psi_openid_connect.h"
3941
4042class Id_token ;
4143
44+ template <typename T>
45+ using Config_allocator =
46+ Psi_openid_connect::Allocator<T, Psi_openid_connect::config_memory_key>;
47+
48+ using Config_string =
49+ std::basic_string<char , std::char_traits<char >,
50+ Psi_openid_connect::Config_allocator<char >>;
51+ using Config_string_set =
52+ std::unordered_set<Config_string, std::hash<Config_string>,
53+ std::equal_to<Config_string>,
54+ Psi_openid_connect::Config_allocator<Config_string>>;
55+ using Config_string_map =
56+ std::map<Config_string, Config_string, std::less<Config_string>,
57+ Psi_openid_connect::Config_allocator<
58+ std::pair<const Config_string, Config_string>>>;
59+ class Idp_config ;
60+ using Config_idp_map =
61+ std::map<Config_string, Idp_config, std::less<Config_string>,
62+ Psi_openid_connect::Config_allocator<
63+ std::pair<const Config_string, Idp_config>>>;
64+
4265/* *
4366 * @brief Statistics for Identity Provider (IDP) configurations.
4467 */
@@ -56,18 +79,16 @@ struct Idp_config_statistics {
5679 */
5780class Idp_config {
5881 private:
59- std::string issuer_name; // /< The token's issuer name.
60- Jwks jwks; // /< URL for the JSON Web Key Set.
61- std::string group_claim; // /< Name of the claim in the JWT that contains
62- // /< group information.
63- std::unordered_set<std::string>
64- audiences; // /< Set of allowed audiences for the token.
65- std::map<std::string, std::string>
66- roles; // /< Map of IDP groups to database roles.
67- std::map<std::string, std::string>
68- keys; // /< Map of Key ID (kid) to public key in PEM format.
82+ Config_string issuer_name; // /< The token's issuer name.
83+ Jwks jwks; // /< Object managing the JSON Web Key Set.
84+ Config_string group_claim; // /< Name of the claim in the JWT that contains
85+ // /< group information.
86+ Config_string_set audiences; // /< Set of allowed audiences for the token.
87+ Config_string_map roles; // /< Map of IDP groups to database roles.
88+ Config_string_map keys; // /< Map of Key ID (kid) to public key in PEM format.
6989
7090 public:
91+ static PSI_memory_key config_memory_key;
7192 /* *
7293 * @brief Constructs an Idp_config object.
7394 * @param issuer_name The token's issuer name.
@@ -76,10 +97,10 @@ class Idp_config {
7697 * @param audiences A set of allowed audiences.
7798 * @param roles A map of group-to-role mappings.
7899 */
79- Idp_config (const std::string &issuer_name, const std::string &jwks_url ,
80- const std::string &group_claim ,
81- std::unordered_set<std::string> &&audiences,
82- std::map<std::string, std::string> &&roles)
100+ Idp_config (const std::string_view &issuer_name,
101+ const std::string_view &jwks_url ,
102+ const std::string_view &group_claim, Config_string_set &&audiences,
103+ Config_string_map &&roles)
83104 : issuer_name(issuer_name),
84105 jwks (jwks_url),
85106 group_claim(group_claim),
@@ -108,7 +129,9 @@ class Idp_config {
108129 * @brief Gets the issuer name.
109130 * @return The issuer name string.
110131 */
111- const std::string &get_issuer_name () const noexcept { return issuer_name; }
132+ std::string get_issuer_name () const noexcept {
133+ return std::string (issuer_name);
134+ }
112135
113136 /* *
114137 * @brief Gets the JWKS URL.
@@ -120,7 +143,7 @@ class Idp_config {
120143 * @brief Gets the name of the group claim.
121144 * @return The group claim name.
122145 */
123- const std::string & get_group_claim () const noexcept { return group_claim; }
146+ std::string_view get_group_claim () const noexcept { return group_claim; }
124147
125148 /* *
126149 * @brief Gets the only public key.
@@ -129,7 +152,7 @@ class Idp_config {
129152 * @return The only public key in PEM format.
130153 * @throws std::runtime_error if no keys are available.
131154 */
132- const std::string & get_the_only_pub_key () const {
155+ std::string_view get_the_only_pub_key () const {
133156 if (keys.size () != 1 ) throw std::runtime_error (" incorrect number of keys" );
134157 const auto key{keys.cbegin ()};
135158 return key->second ;
@@ -141,8 +164,8 @@ class Idp_config {
141164 * @return The public key in PEM format.
142165 * @throws std::out_of_range if the Key ID is not found.
143166 */
144- const std::string & get_pub_key (const std::string &kid) const {
145- return keys.at (kid);
167+ std::string_view get_pub_key (const std::string_view &kid) const {
168+ return keys.at (Config_string ( kid) );
146169 }
147170
148171 /* *
@@ -156,18 +179,18 @@ class Idp_config {
156179 * @param audience The audience string from the token.
157180 * @return true if the audience is allowed
158181 */
159- bool is_audience_allowed (const std::string &audience) const noexcept {
160- return audiences.contains (audience);
182+ bool is_audience_allowed (const std::string_view &audience) const noexcept {
183+ return audiences.contains (Config_string ( audience) );
161184 }
162185
163186 /* *
164187 * @brief Gets the mapped database role for an IDP group.
165188 * @param group The IDP group name.
166189 * @return The mapped role name, or an empty string if no mapping exists.
167190 */
168- const std::string & get_role (const std::string &group) const noexcept {
169- static std::string no_role;
170- const auto it = roles.find (group);
191+ std::string_view get_role (const std::string_view &group) const noexcept {
192+ static Config_string no_role;
193+ const auto it = roles.find (Config_string ( group) );
171194 return it == roles.end () ? no_role : it->second ;
172195 }
173196
@@ -190,9 +213,8 @@ class Idp_config {
190213 */
191214class Idp_configs {
192215 private:
193- std::string sysvar_str{}; // /< Value of the configuration system variable.
194- std::map<std::string, Idp_config>
195- idp_configs{}; // /< Map of IDP names to Idp_config objects.
216+ Config_string sysvar_str{}; // /< Value of the configuration system variable.
217+ Config_idp_map idp_configs{}; // /< Map of IDP names to Idp_config objects.
196218 Idp_configs () = delete ;
197219
198220 /* *
@@ -255,8 +277,8 @@ class Idp_configs {
255277 * @return map of IDP group names to database role names. If no mapping is
256278 * present the returned map will be empty.
257279 */
258- static std::map<std::string, std::string> load_group_roles (
259- const picojson::object &idp_object, const std::string &idp_name);
280+ static Config_string_map load_group_roles ( const picojson::object &idp_object,
281+ const std::string &idp_name);
260282
261283 /* *
262284 * @brief Load the set of allowed audiences from an IDP JSON object.
@@ -268,8 +290,8 @@ class Idp_configs {
268290 * @return An unordered set containing the allowed audience
269291 * strings. If no audiences are configured the set will be empty.
270292 */
271- static std::unordered_set<std::string> load_audiences (
272- const picojson::object &idp_object, const std::string &idp_name);
293+ static Config_string_set load_audiences (const picojson::object &idp_object,
294+ const std::string &idp_name);
273295
274296 /* *
275297 * @brief Parses the prefix of the configuration system variable.
@@ -301,10 +323,11 @@ class Idp_configs {
301323 * @return reference to the Idp_config object, or nullptr if not found.
302324 * @throws std::runtime_error if the IDP is not found in the configuration.
303325 */
304- Idp_config &get_idp (const std::string &idp_name) {
326+ Idp_config &get_idp (const Config_string &idp_name) {
305327 const auto it = idp_configs.find (idp_name);
306328 if (it == idp_configs.end ())
307- throw std::runtime_error (" IDP not found: " + idp_name);
329+ throw std::runtime_error (std::string (" IDP not found: " ) +
330+ idp_name.c_str ());
308331 return it->second ;
309332 }
310333
@@ -315,7 +338,7 @@ class Idp_configs {
315338 * @param other_idp The second IDP config.
316339 * @throws std::runtime_error if the IDP is not found in the configuration.
317340 */
318- static void swap_idp_keys (const std::string &idp_name,
341+ static void swap_idp_keys (const Config_string &idp_name,
319342 Idp_config &other_idp) {
320343 std::unique_lock lock (mutex ());
321344 current ()->get_idp (idp_name).swap_keys (other_idp);
@@ -326,7 +349,7 @@ class Idp_configs {
326349 * @param idp_name The name of the IDP.
327350 * @return The JWKS URL for the specified IDP.
328351 */
329- static const std::string &get_safe_jwks_url (const std::string &idp_name) {
352+ static const std::string &get_safe_jwks_url (const Config_string &idp_name) {
330353 std::shared_lock lock (mutex (), lock_timeout);
331354 if (!lock.owns_lock ())
332355 throw std::runtime_error (" failed to acquire shared lock" );
@@ -337,7 +360,7 @@ class Idp_configs {
337360 * @brief Gets the JWKS URL for a specific IDP in a thread-safe manner.
338361 */
339362 static void swap_idp_keys (
340- std::vector<std::pair<std::string , Idp_config>> &configs) {
363+ std::vector<std::pair<Config_string , Idp_config>> &configs) {
341364 std::unique_lock lock (mutex (), lock_timeout);
342365 if (!lock.owns_lock ())
343366 throw std::runtime_error (" failed to acquire unique lock" );
@@ -353,7 +376,7 @@ class Idp_configs {
353376 * corresponding temporary Idp_config objects
354377 */
355378 static void create_tmp_configs (
356- std::vector<std::pair<std::string , Idp_config>> &configs) {
379+ std::vector<std::pair<Config_string , Idp_config>> &configs) {
357380 std::shared_lock lock (mutex (), lock_timeout);
358381 if (!lock.owns_lock ())
359382 throw std::runtime_error (" failed to acquire shared lock" );
0 commit comments