From: Michael Tremer Date: Fri, 27 Jun 2025 07:59:51 +0000 (+0000) Subject: client: Store the access token, too X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=50e65fa96f2454f5347f6b46afb730d9036dfad8;p=pakfire.git client: Store the access token, too Initially I thought this would be nonsense because the tokens would be very short-lived. However, one API request usually does not come alone and so we would save ourselves a couple of roundtrips with storing the access token, too. Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/client.c b/src/pakfire/client.c index 1637a468..c266106a 100644 --- a/src/pakfire/client.c +++ b/src/pakfire/client.c @@ -149,6 +149,23 @@ ERROR: return r; } +// Called when the client has been initialized for the first time +static int pakfire_client_ready(struct pakfire_client* self) { + int r; + + // Call the callback only once + if (self->ready.callback) { + r = self->ready.callback(self, self->ready.data); + if (r < 0) + return r; + + // Reset the callback + pakfire_client_set_ready_callback(self, NULL, NULL); + } + + return 0; +} + static int pakfire_client_auth_response(struct pakfire_xfer* xfer, pakfire_xfer_error_code_t code, json_object* response, void* data); @@ -162,14 +179,18 @@ static int pakfire_client_auth_refresh(struct pakfire_client* self) { struct json_object* request = NULL; int r; - // Cannot do this if we don't have a refresh token - if (!*self->auth.refresh_token) - return -ENOTSUP; + // Require full authentication if we don't have all credentials + if (!*self->auth.access_token || !*self->auth.refresh_token) + return pakfire_client_auth_required(self); - // Require authentication if the refresh token has completely expired - if (pakfire_jwt_has_expired(self->auth.refresh_token)) + // Also require full authentication if the refresh token has expired + else if (pakfire_jwt_has_expired(self->auth.refresh_token)) return pakfire_client_auth_required(self); + // There is nothing to do if the access token has not expired + else if (!pakfire_jwt_has_expired(self->auth.access_token)) + return pakfire_client_ready(self); + // Log action DEBUG(self->ctx, "Refreshing authentication tokens...\n"); @@ -296,6 +317,7 @@ static int pakfire_client_set_refresh_token(struct pakfire_client* self, const c static int pakfire_client_store_read(struct pakfire_client* self) { struct json_object* store = NULL; const char* refresh_token = NULL; + const char* access_token = NULL; char path[PATH_MAX]; char* error = NULL; int r; @@ -323,23 +345,37 @@ static int pakfire_client_store_read(struct pakfire_client* self) { } } + // Fetch the access token + r = pakfire_json_get_string(store, "access_token", &access_token); + if (r < 0) + goto ERROR; + // Fetch the refresh token r = pakfire_json_get_string(store, "refresh_token", &refresh_token); if (r < 0) goto ERROR; - // Set the refresh token - if (refresh_token) { - r = pakfire_client_set_refresh_token(self, refresh_token); + // Set the access token + if (access_token && !pakfire_jwt_has_expired(access_token)) { + r = pakfire_client_set_access_token(self, access_token); if (r < 0) goto ERROR; + } - // Trigger an immediate refresh - r = pakfire_client_auth_refresh(self); + // Set the refresh token + if (refresh_token && !pakfire_jwt_has_expired(refresh_token)) { + r = pakfire_client_set_refresh_token(self, refresh_token); if (r < 0) goto ERROR; } + // Trigger an immediate refresh + r = pakfire_client_auth_refresh(self); + if (r < 0) { + ERROR(self->ctx, "Failed to refresh authentication credentials: %s\n", strerror(-r)); + goto ERROR; + } + ERROR: if (store) json_object_put(store); @@ -364,6 +400,11 @@ static int pakfire_client_store_write(struct pakfire_client* self) { if (r < 0) goto ERROR; + // Add the access token + r = pakfire_json_add_string(store, "access_token", self->auth.access_token); + if (r < 0) + goto ERROR; + // Add the refresh token r = pakfire_json_add_string(store, "refresh_token", self->auth.refresh_token); if (r < 0) @@ -419,23 +460,11 @@ static int pakfire_client_auth_required(struct pakfire_client* self) { static int pakfire_client_init(sd_event_source* event, void* data) { struct pakfire_client* self = data; - int r; DEBUG(self->ctx, "Initializing client...\n"); // Read the store - r = pakfire_client_store_read(self); - if (r < 0) - return r; - - // Request authentication if we have no tokens - if (!*self->auth.access_token && !*self->auth.refresh_token) { - r = pakfire_client_auth_required(self); - if (r < 0) - return r; - } - - return 0; + return pakfire_client_store_read(self); } static void pakfire_client_upload_free(struct pakfire_client_upload* upload); @@ -568,23 +597,6 @@ void pakfire_client_set_ready_callback(struct pakfire_client* self, self->ready.data = data; } -// Called when the client has been initialized for the first time -static int pakfire_client_ready(struct pakfire_client* self) { - int r; - - // Call the callback only once - if (self->ready.callback) { - r = self->ready.callback(self, self->ready.data); - if (r < 0) - return r; - - // Reset the callback - pakfire_client_set_ready_callback(self, NULL, NULL); - } - - return 0; -} - int pakfire_client_run(struct pakfire_client* self) { return pakfire_httpclient_run(self->httpclient, NULL); }