Skip to content

Commit 4faeb81

Browse files
authored
fix the scope for oauthbearer OIDC (confluentinc#3912)
1 parent faacc74 commit 4faeb81

File tree

1 file changed

+91
-14
lines changed

1 file changed

+91
-14
lines changed

src/rdkafka_sasl_oauthbearer_oidc.c

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,33 @@ static const char *rd_kafka_jwt_b64_decode_payload(const char *src,
205205
return errstr;
206206
}
207207

208+
/**
209+
* @brief Build post_fields with \p scope.
210+
* The format of the post_fields is
211+
* `grant_type=client_credentials&scope=scope`
212+
* The post_fields will be returned in \p *post_fields.
213+
* The post_fields_size will be returned in \p post_fields_size.
214+
*
215+
*/
216+
static void rd_kafka_oidc_build_post_fields(const char *scope,
217+
char **post_fields,
218+
size_t *post_fields_size) {
219+
size_t scope_size = 0;
220+
221+
if (scope)
222+
scope_size = strlen(scope);
223+
if (scope_size == 0) {
224+
*post_fields = rd_strdup("grant_type=client_credentials");
225+
*post_fields_size = strlen("grant_type=client_credentials");
226+
} else {
227+
*post_fields_size =
228+
strlen("grant_type=client_credentials&scope=") + scope_size;
229+
*post_fields = rd_malloc(*post_fields_size + 1);
230+
rd_snprintf(*post_fields, *post_fields_size + 1,
231+
"grant_type=client_credentials&scope=%s", scope);
232+
}
233+
}
234+
208235

209236
/**
210237
* @brief Implementation of Oauth/OIDC token refresh callback function,
@@ -240,7 +267,6 @@ void rd_kafka_oidc_token_refresh_cb(rd_kafka_t *rk,
240267
size_t post_fields_size;
241268
size_t extension_cnt;
242269
size_t extension_key_value_cnt = 0;
243-
size_t scope_size = 0;
244270

245271
char set_token_errstr[512];
246272
char decode_payload_errstr[512];
@@ -256,19 +282,8 @@ void rd_kafka_oidc_token_refresh_cb(rd_kafka_t *rk,
256282
&headers);
257283

258284
/* Build post fields */
259-
if (rk->rk_conf.sasl.oauthbearer.scope)
260-
scope_size = strlen(rk->rk_conf.sasl.oauthbearer.scope);
261-
if (scope_size == 0) {
262-
post_fields = rd_strdup("grant_type=client_credentials");
263-
post_fields_size = strlen("grant_type=client_credentials");
264-
} else {
265-
post_fields_size =
266-
strlen("grant_type=client_credentials&scope=") + scope_size;
267-
post_fields = rd_malloc(post_fields_size + 1);
268-
rd_snprintf(post_fields, post_fields_size,
269-
"grant_type=client_credentials&scope=%s",
270-
rk->rk_conf.sasl.oauthbearer.scope);
271-
}
285+
rd_kafka_oidc_build_post_fields(rk->rk_conf.sasl.oauthbearer.scope,
286+
&post_fields, &post_fields_size);
272287

273288
token_url = rk->rk_conf.sasl.oauthbearer.token_endpoint_url;
274289

@@ -510,6 +525,66 @@ static int ut_sasl_oauthbearer_oidc_with_empty_key(void) {
510525
RD_UT_PASS();
511526
}
512527

528+
/**
529+
* @brief Make sure the post_fields return correct with the scope.
530+
*/
531+
static int ut_sasl_oauthbearer_oidc_post_fields(void) {
532+
static const char *scope = "test-scope";
533+
static const char *expected_post_fields =
534+
"grant_type=client_credentials&scope=test-scope";
535+
536+
size_t expected_post_fields_size = strlen(expected_post_fields);
537+
538+
size_t post_fields_size;
539+
540+
char *post_fields;
541+
542+
RD_UT_BEGIN();
543+
544+
rd_kafka_oidc_build_post_fields(scope, &post_fields, &post_fields_size);
545+
546+
RD_UT_ASSERT(expected_post_fields_size == post_fields_size,
547+
"Expected expected_post_fields_size is %zu"
548+
"received post_fields_size is %zu",
549+
expected_post_fields_size, post_fields_size);
550+
RD_UT_ASSERT(!strcmp(expected_post_fields, post_fields),
551+
"Expected expected_post_fields is %s"
552+
"received post_fields is %s",
553+
expected_post_fields, post_fields);
554+
555+
RD_UT_PASS();
556+
}
557+
558+
/**
559+
* @brief Make sure the post_fields return correct with the empty scope.
560+
*/
561+
static int ut_sasl_oauthbearer_oidc_post_fields_with_empty_scope(void) {
562+
static const char *scope = NULL;
563+
static const char *expected_post_fields =
564+
"grant_type=client_credentials";
565+
566+
size_t expected_post_fields_size = strlen(expected_post_fields);
567+
568+
size_t post_fields_size;
569+
570+
char *post_fields;
571+
572+
RD_UT_BEGIN();
573+
574+
rd_kafka_oidc_build_post_fields(scope, &post_fields, &post_fields_size);
575+
576+
RD_UT_ASSERT(expected_post_fields_size == post_fields_size,
577+
"Expected expected_post_fields_size is %zu"
578+
"received post_fields_size is %zu",
579+
expected_post_fields_size, post_fields_size);
580+
RD_UT_ASSERT(!strcmp(expected_post_fields, post_fields),
581+
"Expected expected_post_fields is %s"
582+
"received post_fields is %s",
583+
expected_post_fields, post_fields);
584+
585+
RD_UT_PASS();
586+
}
587+
513588

514589
/**
515590
* @brief make sure the jwt is able to be extracted from HTTP(S) requests
@@ -519,5 +594,7 @@ int unittest_sasl_oauthbearer_oidc(void) {
519594
int fails = 0;
520595
fails += ut_sasl_oauthbearer_oidc_should_succeed();
521596
fails += ut_sasl_oauthbearer_oidc_with_empty_key();
597+
fails += ut_sasl_oauthbearer_oidc_post_fields();
598+
fails += ut_sasl_oauthbearer_oidc_post_fields_with_empty_scope();
522599
return fails;
523600
}

0 commit comments

Comments
 (0)