Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Clear the inventory data hash on re-authentication #1719

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/api/auth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct AuthData {
using ExpectedAuthData = expected::expected<AuthData, error::Error>;

using AuthenticatedAction = function<void(ExpectedAuthData)>;
using ReAuthenticatedAction = function<void()>;

class Authenticator {
public:
Expand All @@ -78,9 +79,15 @@ class Authenticator {
}

void ExpireToken();

error::Error WithToken(AuthenticatedAction action);

// Register a callback to be called on re-authentication. Will overwrite the
// stored callback with the new one.
void RegisterTokenReceivedCallback(ReAuthenticatedAction action) {
action_ = action;
}


protected:
enum class NoTokenAction {
Finish,
Expand All @@ -97,11 +104,11 @@ class Authenticator {
void HandleReceivedToken(common::ExpectedStringPair ex_auth_dbus_data, NoTokenAction no_token);

events::EventLoop &loop_;

bool token_fetch_in_progress_ = false;
vector<AuthenticatedAction> pending_actions_;
chrono::seconds auth_timeout_;
events::Timer auth_timeout_timer_;
ReAuthenticatedAction action_ {nullptr};
};

#ifdef MENDER_USE_DBUS
Expand Down
5 changes: 3 additions & 2 deletions src/api/auth/auth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ error::Error Authenticator::WithToken(AuthenticatedAction action) {
}
// else record that token is already being fetched (by GetJwtToken()).
token_fetch_in_progress_ = true;

return error::NoError;
}

Expand Down Expand Up @@ -151,7 +150,9 @@ void Authenticator::HandleReceivedToken(
return;
}
}

if (no_token == NoTokenAction::Finish && action_ != nullptr) {
action_();
}
PostPendingActions(ex_auth_data);
}

Expand Down
1 change: 0 additions & 1 deletion src/api/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ error::Error HTTPClient::AsyncCall(
});
return;
}
reauthenticated_ = true;
};

return authenticator_.WithToken(
Expand Down
9 changes: 0 additions & 9 deletions src/api/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,10 @@ class HTTPClient : public Client {
authenticator_.ExpireToken();
}

bool HasReauthenticated() {
return reauthenticated_;
}

void SetReauthenticated(bool reauthenticated) {
reauthenticated_ = reauthenticated;
danielskinstad marked this conversation as resolved.
Show resolved Hide resolved
}

private:
events::EventLoop &event_loop_;
http::Client http_client_;
auth::Authenticator &authenticator_;
bool reauthenticated_ {false};
};

} // namespace api
Expand Down
3 changes: 0 additions & 3 deletions src/mender-update/daemon/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ class Context {
mender::auth::api::auth::AuthenticatorHttp authenticator;
#endif

public:
// For polling, and for making status updates.
api::HTTPClient http_client;
// For the artifact download.
Expand All @@ -175,8 +174,6 @@ class Context {
shared_ptr<deployments::DeploymentAPI> deployment_client;
shared_ptr<inventory::InventoryAPI> inventory_client;

bool has_submitted_inventory {false};

struct {
unique_ptr<StateData> state_data;
io::ReaderPtr artifact_reader;
Expand Down
8 changes: 7 additions & 1 deletion src/mender-update/daemon/state_machine/state_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,14 @@ StateMachine::StateMachine(Context &ctx, events::EventLoop &event_loop) :
runner_(ctx) {
runner_.AddStateMachine(deployment_tracking_.states_);
runner_.AddStateMachine(main_states_);

runner_.AttachToEventLoop(event_loop_);
ctx.authenticator.RegisterTokenReceivedCallback([&ctx]() {
if (ctx.inventory_client->has_submitted_inventory) {
log::Debug("Client has re-authenticated - clear inventory data cache");
ctx.inventory_client->ClearDataCache();
ctx.inventory_client->has_submitted_inventory = false;
}
});

using se = StateEvent;
using tf = sm::TransitionFlag;
Expand Down
21 changes: 3 additions & 18 deletions src/mender-update/daemon/states.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ void SubmitInventoryState::DoSubmitInventory(Context &ctx, sm::EventPoster<State
return;
}
retry_.backoff.Reset();
ctx.has_submitted_inventory = true;
ctx.inventory_client->has_submitted_inventory = true;
poster.PostEvent(StateEvent::Success);
};

Expand Down Expand Up @@ -261,16 +261,7 @@ void PollForDeploymentState::OnEnter(Context &ctx, sm::EventPoster<StateEvent> &
[this, &ctx, &poster](mender::update::deployments::CheckUpdatesAPIResponse response) {
if (!response) {
log::Error("Error while polling for deployment: " + response.error().String());

// When unauthenticated,
// invalidate the cached inventory data so that it can be sent again
// and set clear the context flag so that it is triggered on re-authorization
if (response.error().code == auth::MakeError(auth::UnauthorizedError, "").code) {
if (ctx.has_submitted_inventory) {
ctx.inventory_client->ClearDataCache();
ctx.has_submitted_inventory = false;
}
} else {
if (response.error().code != auth::MakeError(auth::UnauthorizedError, "").code) {
// Replace the update poll timer with a backoff
HandlePollingError(ctx, poster);
}
Expand All @@ -279,13 +270,7 @@ void PollForDeploymentState::OnEnter(Context &ctx, sm::EventPoster<StateEvent> &
} else if (!response.value()) {
log::Info("No update available");
poster.PostEvent(StateEvent::NothingToDo);
if (ctx.http_client.HasReauthenticated()) {
log::Debug("Client has reauthenticated, clear inventory data cache");
ctx.inventory_client->ClearDataCache();
ctx.has_submitted_inventory = false;
ctx.http_client.SetReauthenticated(false);
}
if (not ctx.has_submitted_inventory) {
if (not ctx.inventory_client->has_submitted_inventory) {
// If we have not submitted inventory successfully at least
// once, schedule this after receiving a successful response
// with no update. This enables inventory to be submitted
Expand Down
2 changes: 2 additions & 0 deletions src/mender-update/inventory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class InventoryAPI {
APIResponseHandler api_handler) = 0;

virtual void ClearDataCache() = 0;

bool has_submitted_inventory {false};
};

class InventoryClient : public InventoryAPI {
Expand Down