]> git.ipfire.org Git - pakfire.git/commitdiff
buildservice: Automatically refresh the access token on expiry
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 21 Jun 2025 17:09:24 +0000 (17:09 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 21 Jun 2025 17:09:24 +0000 (17:09 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/buildservice.c

index 03896dfd83978ed7b896d9bd6c92aab57be05d0e..df979caa656dba11f6b2ea4e5f9c01f9225736e8 100644 (file)
@@ -97,47 +97,6 @@ ERROR:
        return r;
 }
 
-static int pakfire_buildservice_auth_refresh(struct pakfire_buildservice* self) {
-       return 0; // XXX TODO
-}
-
-static int pakfire_buildservice_token_has_expired(const time_t t) {
-       time_t now = -1;
-
-       // Fetch the current time
-       now = time(NULL);
-       if (now < 0)
-               return -errno;
-
-       // We consider the token as expired if there are less than 60 seconds left
-       return (now - t) < 60;
-}
-
-static int pakfire_buildservice_xfer_auth(struct pakfire_buildservice* self, struct pakfire_xfer* xfer) {
-       int r;
-
-       // Fail if not authenticated
-       if (!*self->access_token)
-               return -ENOTSUP;
-
-       // Refresh if the access token has expired
-       if (pakfire_buildservice_token_has_expired(self->access_token_expires_at)) {
-               DEBUG(self->ctx, "The access token has expired. Trying to refresh...\n");
-
-               // Refresh the access token
-               r = pakfire_buildservice_auth_refresh(self);
-               if (r < 0)
-                       return r;
-       }
-
-       // Set the access token
-       r = pakfire_xfer_add_header(xfer, "Authorization: Bearer %s", self->access_token);
-       if (r < 0)
-               return r;
-
-       return 0;
-}
-
 static int pakfire_buildservice_set_access_token(struct pakfire_buildservice* self, const char* token) {
        char expires_at[1024];
        int r;
@@ -194,6 +153,100 @@ static int pakfire_buildservice_set_refresh_token(struct pakfire_buildservice* s
        return 0;
 }
 
+static int pakfire_buildservice_token_has_expired(const time_t t) {
+       time_t now = -1;
+
+       // Fetch the current time
+       now = time(NULL);
+       if (now < 0)
+               return -errno;
+
+       // We consider the token as expired if there are less than 60 seconds left
+       return (t - now) < 60;
+}
+
+static int pakfire_buildservice_auth_refresh(struct pakfire_buildservice* self) {
+       struct pakfire_xfer* xfer = NULL;
+       struct json_object* request = NULL;
+       struct json_object* response = NULL;
+       const char* access_token = NULL;
+       int r;
+
+       // Cannot do this if we don't have a refresh token
+       if (!*self->refresh_token)
+               return -ENOTSUP;
+
+       // We cannot do this either if the refresh token has expired
+       else if (pakfire_buildservice_token_has_expired(self->refresh_token_expires_at))
+               return -ENOTSUP;
+
+       // Create a new transfer
+       r = pakfire_buildservice_xfer_create(&xfer, self, "/api/v1/auth/refresh");
+       if (r < 0)
+               goto ERROR;
+
+       // Create a new JSON request object
+       r = pakfire_json_new_object(&request);
+       if (r < 0)
+               goto ERROR;
+
+       // Add the refresh token
+       r = pakfire_json_add_string(request, "refresh_token", self->refresh_token);
+       if (r < 0)
+               goto ERROR;
+
+       // Send the request
+       r = pakfire_xfer_run_api_request(xfer, request, &response);
+       if (r < 0)
+               goto ERROR;
+
+       // Extract the new access token
+       r = pakfire_json_get_string(response, "access_token", &access_token);
+       if (r < 0) {
+               ERROR(self->ctx, "Failed to fetch the access token: %s\n", strerror(-r));
+               goto ERROR;
+       }
+
+       // Store the new access token
+       r = pakfire_buildservice_set_access_token(self, access_token);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (xfer)
+               pakfire_xfer_unref(xfer);
+       if (request)
+               json_object_put(request);
+       if (response)
+               json_object_put(response);
+
+       return r;
+}
+
+static int pakfire_buildservice_xfer_auth(struct pakfire_buildservice* self, struct pakfire_xfer* xfer) {
+       int r;
+
+       // Fail if not authenticated
+       if (!*self->access_token)
+               return -ENOTSUP;
+
+       // Refresh if the access token has expired
+       if (pakfire_buildservice_token_has_expired(self->access_token_expires_at)) {
+               DEBUG(self->ctx, "The access token has expired. Trying to refresh...\n");
+
+               // Refresh the access token
+               r = pakfire_buildservice_auth_refresh(self);
+               if (r < 0)
+                       return r;
+       }
+
+       // Set the access token
+       r = pakfire_xfer_add_header(xfer, "Authorization: Bearer %s", self->access_token);
+       if (r < 0)
+               return r;
+
+       return 0;
+}
 static int pakfire_buildservice_setup_auth(struct pakfire_buildservice* service) {
        const char* error = NULL;
        int r;