From 302a30fc94e848db1da8708b6817aefe00c6e29f Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 25 Jun 2025 10:13:07 +0000 Subject: [PATCH] client: Create separate timers for access/refresh token refresh These are also now only initialized when we actually need them. That helps us to deal with all those status changes. Signed-off-by: Michael Tremer --- src/pakfire/client.c | 85 ++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/src/pakfire/client.c b/src/pakfire/client.c index 2c3046a6..8c4039b4 100644 --- a/src/pakfire/client.c +++ b/src/pakfire/client.c @@ -93,8 +93,9 @@ struct pakfire_client { char access_token[1024]; char refresh_token[1024]; - // Timer - sd_event_source* timer; + // Timers + sd_event_source* access_timer; + sd_event_source* refresh_timer; // Callback pakfire_client_auth_callback callback; @@ -195,14 +196,6 @@ ERROR: return r; } -static int pakfire_client_auth_timer(sd_event_source* event, uint64_t usec, void* data) { - struct pakfire_client* self = data; - - DEBUG(self->ctx, "Authentication timer fired\n"); - - return 0; -} - static int pakfire_client_xfer_auth(struct pakfire_client* self, struct pakfire_xfer* xfer) { int r; @@ -249,8 +242,10 @@ static int pakfire_client_init(sd_event_source* event, void* data) { } static void pakfire_client_free(struct pakfire_client* self) { - if (self->auth.timer) - sd_event_source_unref(self->auth.timer); + if (self->auth.access_timer) + sd_event_source_unref(self->auth.access_timer); + if (self->auth.refresh_timer) + sd_event_source_unref(self->auth.refresh_timer); // Event Loop if (self->loop) @@ -296,21 +291,6 @@ int pakfire_client_create(struct pakfire_client** client, // Initialize uploads STAILQ_INIT(&self->uploads); - // Setup the authentication timer - r = sd_event_add_time_relative(self->loop, &self->auth.timer, - CLOCK_MONOTONIC, 0, 0, pakfire_client_auth_timer, self); - if (r < 0) { - ERROR(self->ctx, "Could not register the auth timer: %s\n", strerror(-r)); - goto ERROR; - } - - // Disable the authentication timer - r = sd_event_source_set_enabled(self->auth.timer, SD_EVENT_OFF); - if (r < 0) { - ERROR(self->ctx, "Could not activate the auth timer: %s\n", strerror(-r)); - goto ERROR; - } - DEBUG(self->ctx, "Pakfire Build Service initialized for %s\n", pakfire_client_get_url(self)); @@ -386,6 +366,22 @@ int pakfire_client_set_auth_callback(struct pakfire_client* self, return 0; } +static int pakfire_client_access_timer(sd_event_source* event, uint64_t usec, void* data) { + struct pakfire_client* self = data; + + DEBUG(self->ctx, "Authentication access timer fired\n"); + + return 0; +} + +static int pakfire_client_refresh_timer(sd_event_source* event, uint64_t usec, void* data) { + struct pakfire_client* self = data; + + DEBUG(self->ctx, "Authentication refresh timer fired\n"); + + return 0; +} + static int pakfire_client_auth_successful( struct pakfire_client* self, struct json_object* response) { const char* refresh_token = NULL; @@ -422,18 +418,45 @@ static int pakfire_client_auth_successful( // Extract the expiry time of the access token expires_at = r = pakfire_jwt_expires_at(self->auth.access_token); - if (expires_at < 0) { + if (r < 0) { ERROR(self->ctx, "Failed to fetch the expiry time of the access token: %s\n", strerror(-r)); return r; } + // Create the access token timer (unless already done so) + if (!self->auth.access_timer) { + r = sd_event_add_time_relative(self->loop, &self->auth.access_timer, + CLOCK_MONOTONIC, 0, 0, pakfire_client_access_timer, self); + if (r < 0) { + ERROR(self->ctx, "Failed to register the auth access timer: %s\n", strerror(-r)); + return r; + } + } + // Call the timer just before the access token expires - r = sd_event_source_set_time(self->auth.timer, S_TO_US(expires_at - 60)); + r = sd_event_source_set_time(self->auth.access_timer, S_TO_US(expires_at - 60)); if (r < 0) return r; - // Enable the timer to fire once - r = sd_event_source_set_enabled(self->auth.timer, SD_EVENT_ONESHOT); + // Extract the expiry time of the refresh token + expires_at = r = pakfire_jwt_expires_at(self->auth.refresh_token); + if (r < 0) { + ERROR(self->ctx, "Failed to fetch the expiry time of the refresh token: %s\n", strerror(-r)); + return r; + } + + // Create the refresh token timer (unless already done so) + if (!self->auth.refresh_timer) { + r = sd_event_add_time_relative(self->loop, &self->auth.refresh_timer, + CLOCK_MONOTONIC, 0, 0, pakfire_client_refresh_timer, self); + if (r < 0) { + ERROR(self->ctx, "Failed to register the auth refresh timer: %s\n", strerror(-r)); + return r; + } + } + + // Call the timer just before the refresh token expires + r = sd_event_source_set_time(self->auth.refresh_timer, S_TO_US(expires_at - 60)); if (r < 0) return r; -- 2.47.2