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);
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");
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;
}
}
+ // 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);
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)
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);
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);
}