#include <pakfire/os.h>
#include <pakfire/path.h>
#include <pakfire/string.h>
+#include <pakfire/util.h>
#include <pakfire/xfer.h>
struct pakfire_client {
// Tokens
char access_token[1024];
- time_t access_token_expires_at;
char refresh_token[1024];
- time_t refresh_token_expires_at;
// Callbacks
struct pakfire_client_auth_callback {
return r;
}
-static int pakfire_client_set_access_token(struct pakfire_client* self, const char* token) {
- char expires_at[1024];
- int r;
-
- // Store the token
- r = pakfire_string_set(self->access_token, token);
- if (r < 0)
- return r;
-
- // Fetch the expiry time
- self->access_token_expires_at = pakfire_jwt_expires_at(self->access_token);
- if (self->access_token_expires_at < 0) {
- ERROR(self->ctx, "Failed to fetch the JWT expiry time: %s\n", strerror(-r));
- return self->access_token_expires_at;
- }
-
- // Format the expiry time
- r = pakfire_strftime(expires_at, "%Y-%m-%dT%H:%M:%SZ", self->access_token_expires_at);
- if (r < 0)
- return r;
-
- // Log action
- DEBUG(self->ctx, "Set access token: %s\n", self->access_token);
- DEBUG(self->ctx, " Expires: %s\n", expires_at);
-
- return 0;
-}
-
-static int pakfire_client_set_refresh_token(struct pakfire_client* self, const char* token) {
- char expires_at[1024];
- int r;
-
- // Store the token
- r = pakfire_string_set(self->refresh_token, token);
- if (r < 0)
- return r;
-
- // Fetch the expiry time
- self->refresh_token_expires_at = pakfire_jwt_expires_at(self->refresh_token);
- if (self->refresh_token_expires_at < 0) {
- ERROR(self->ctx, "Failed to fetch the JWT expiry time: %s\n", strerror(-r));
- return self->refresh_token_expires_at;
- }
-
- // Format the expiry time
- r = pakfire_strftime(expires_at, "%Y-%m-%dT%H:%M:%SZ", self->refresh_token_expires_at);
- if (r < 0)
- return r;
-
- // Log action
- DEBUG(self->ctx, "Set refresh token: %s\n", self->refresh_token);
- DEBUG(self->ctx, " Expires: %s\n", expires_at);
-
- return 0;
-}
-
-static int pakfire_client_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_client_auth_refresh(struct pakfire_client* self) {
struct pakfire_xfer* xfer = NULL;
struct json_object* request = NULL;
if (!*self->refresh_token)
return -ENOTSUP;
- // We cannot do this either if the refresh token has expired
- else if (pakfire_client_token_has_expired(self->refresh_token_expires_at))
- return -ENOTSUP;
-
// Create a new transfer
r = pakfire_client_xfer_create(&xfer, self, "/api/v1/auth/refresh");
if (r < 0)
}
// Store the new access token
- r = pakfire_client_set_access_token(self, access_token);
+ r = pakfire_string_set(self->access_token, access_token);
if (r < 0)
goto ERROR;
if (!*self->access_token)
return -ENOTSUP;
- // Refresh if the access token has expired
- if (pakfire_client_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_client_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)
struct pakfire_client* self, struct json_object* response) {
const char* refresh_token = NULL;
const char* access_token = NULL;
+ time_t expires_at = -1;
int r;
// Log action
}
// Store the access token
- r = pakfire_client_set_access_token(self, access_token);
+ r = pakfire_string_set(self->access_token, access_token);
if (r < 0)
return r;
// Store the refresh token
- r = pakfire_client_set_refresh_token(self, refresh_token);
+ r = pakfire_string_set(self->refresh_token, refresh_token);
+ if (r < 0)
+ return r;
+
+ // Extract the expiry time of the access token
+ expires_at = r = pakfire_jwt_expires_at(self->access_token);
+ if (expires_at < 0) {
+ ERROR(self->ctx, "Failed to fetch the expiry time of the access token: %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));
+ if (r < 0)
+ return r;
+
+ // Enable the timer to fire once
+ r = sd_event_source_set_enabled(self->auth.timer, SD_EVENT_ONESHOT);
if (r < 0)
return r;