]> git.ipfire.org Git - pakfire.git/commitdiff
client: Store the access token, too
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 27 Jun 2025 07:59:51 +0000 (07:59 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 27 Jun 2025 07:59:51 +0000 (07:59 +0000)
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 <michael.tremer@ipfire.org>
src/pakfire/client.c

index 1637a4683f7ab08202f87d27f5029bdc2505c61c..c266106ad4d897feecf447ba46d045137ec11812 100644 (file)
@@ -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);
 }