buffet: Forcibly refresh access token when handling HTTP error 401. It's not enough to just check that the access token hasn't expired so always fetch a new access token when the server specifically tells us that the access token is wrong (e.g. HTTP error code 401). BUG=brillo:275 TEST=Unit tests pass. Change-Id: Ib619883a9629e313c9f76679232bcd245bf83bb9 Reviewed-on: https://chromium-review.googlesource.com/255590 Reviewed-by: Nathan Bullock <nathanbullock@google.com> Reviewed-by: Christopher Wiley <wiley@chromium.org> Tested-by: David Zeuthen <zeuthen@chromium.org> Commit-Queue: David Zeuthen <zeuthen@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc index 0b98cb7..72d6d67 100644 --- a/buffet/device_registration_info.cc +++ b/buffet/device_registration_info.cc
@@ -268,7 +268,7 @@ bool DeviceRegistrationInfo::CheckRegistration(chromeos::ErrorPtr* error) { return HaveRegistrationCredentials(error) && - ValidateAndRefreshAccessToken(error); + MaybeRefreshAccessToken(error); } bool DeviceRegistrationInfo::HaveRegistrationCredentials( @@ -311,7 +311,7 @@ return resp; } -bool DeviceRegistrationInfo::ValidateAndRefreshAccessToken( +bool DeviceRegistrationInfo::MaybeRefreshAccessToken( chromeos::ErrorPtr* error) { LOG(INFO) << "Checking access token expiration."; if (!access_token_.empty() && @@ -320,7 +320,12 @@ LOG(INFO) << "Access token is still valid."; return true; } + return RefreshAccessToken(error); +} +bool DeviceRegistrationInfo::RefreshAccessToken( + chromeos::ErrorPtr* error) { + LOG(INFO) << "Refreshing access token."; auto response = chromeos::http::PostFormDataAndBlock(GetOAuthURL("token"), { {"refresh_token", refresh_token_}, {"client_id", client_id_}, @@ -687,7 +692,8 @@ if (error->HasError(chromeos::errors::http::kDomain, std::to_string(chromeos::http::status_code::Denied))) { chromeos::ErrorPtr reauthorization_error; - if (!self->ValidateAndRefreshAccessToken(&reauthorization_error)) { + // Forcibly refresh the access token. + if (!self->RefreshAccessToken(&reauthorization_error)) { // TODO(antonm): Check if the device has been actually removed. error_cb(request_id, reauthorization_error.get()); return;
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h index 7b2e3da..c96c09c 100644 --- a/buffet/device_registration_info.h +++ b/buffet/device_registration_info.h
@@ -147,8 +147,13 @@ // Checks whether we have credentials generated during registration. bool HaveRegistrationCredentials(chromeos::ErrorPtr* error); - // Makes sure the access token is available and up-to-date. - bool ValidateAndRefreshAccessToken(chromeos::ErrorPtr* error); + // If we currently have an access token and it doesn't like like it + // has expired yet, returns true immediately. Otherwise calls + // RefreshAccessToken(). + bool MaybeRefreshAccessToken(chromeos::ErrorPtr* error); + + // Forcibly refreshes the access token. + bool RefreshAccessToken(chromeos::ErrorPtr* error); // Parse the OAuth response, and sets registration status to // kInvalidCredentials if our registration is no longer valid.