buffet: Add RegistrationStatus::InvalidCredentials

If the device has been deleted from GCD then an oauth request will
return an error of invalid_grant. Make sure we handle this and set
the registration status to InvalidCredentials.

BUG=brillo:16
TEST=FEATURES=test emerge-${BOARD} buffet (I also tested this manually
by deregistering the device using
https://gcd.sandbox.google.com/clouddevices#) and
test_that <ipaddress> buffet_Registration buffet_BasicDBusAPI

Change-Id: I60aa68186d9c6f3a7ce812e4dddfda626ea2b42f
Reviewed-on: https://chromium-review.googlesource.com/254170
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Nathan Bullock <nathanbullock@google.com>
Tested-by: Nathan Bullock <nathanbullock@google.com>
diff --git a/buffet/device_registration_info_unittest.cc b/buffet/device_registration_info_unittest.cc
index dee5614..2912fb6 100644
--- a/buffet/device_registration_info_unittest.cc
+++ b/buffet/device_registration_info_unittest.cc
@@ -124,6 +124,28 @@
   response->ReplyJson(chromeos::http::status_code::Ok, &json);
 }
 
+void OAuth2HandlerFail(const ServerRequest& request,
+                       ServerResponse* response) {
+  base::DictionaryValue json;
+  EXPECT_EQ("refresh_token", request.GetFormField("grant_type"));
+  EXPECT_EQ(test_data::kRefreshToken, request.GetFormField("refresh_token"));
+  EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
+  EXPECT_EQ(test_data::kClientSecret, request.GetFormField("client_secret"));
+  json.SetString("error", "unable_to_authenticate");
+  response->ReplyJson(chromeos::http::status_code::BadRequest, &json);
+}
+
+void OAuth2HandlerDeregister(const ServerRequest& request,
+                             ServerResponse* response) {
+  base::DictionaryValue json;
+  EXPECT_EQ("refresh_token", request.GetFormField("grant_type"));
+  EXPECT_EQ(test_data::kRefreshToken, request.GetFormField("refresh_token"));
+  EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
+  EXPECT_EQ(test_data::kClientSecret, request.GetFormField("client_secret"));
+  json.SetString("error", "invalid_grant");
+  response->ReplyJson(chromeos::http::status_code::BadRequest, &json);
+}
+
 void DeviceInfoHandler(const ServerRequest& request, ServerResponse* response) {
   std::string auth = "Bearer ";
   auth += test_data::kAccessToken;
@@ -293,6 +315,46 @@
   EXPECT_EQ(1, transport_->GetRequestCount());
 }
 
+TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) {
+  SetDefaultDeviceRegistration(&data_);
+  storage_->Save(&data_);
+  EXPECT_TRUE(dev_reg_->Load());
+  EXPECT_EQ(RegistrationStatus::kOffline,
+            dev_reg_->GetRegistrationStatus());
+
+  transport_->AddHandler(dev_reg_->GetOAuthURL("token"),
+                         chromeos::http::request_type::kPost,
+                         base::Bind(OAuth2HandlerFail));
+  transport_->ResetRequestCount();
+  chromeos::ErrorPtr error;
+  EXPECT_FALSE(dev_reg_->CheckRegistration(&error));
+  EXPECT_EQ(1, transport_->GetRequestCount());
+  EXPECT_TRUE(error->HasError(buffet::kErrorDomainOAuth2,
+                              "unable_to_authenticate"));
+  EXPECT_EQ(RegistrationStatus::kOffline,
+            dev_reg_->GetRegistrationStatus());
+}
+
+TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) {
+  SetDefaultDeviceRegistration(&data_);
+  storage_->Save(&data_);
+  EXPECT_TRUE(dev_reg_->Load());
+  EXPECT_EQ(RegistrationStatus::kOffline,
+            dev_reg_->GetRegistrationStatus());
+
+  transport_->AddHandler(dev_reg_->GetOAuthURL("token"),
+                         chromeos::http::request_type::kPost,
+                         base::Bind(OAuth2HandlerDeregister));
+  transport_->ResetRequestCount();
+  chromeos::ErrorPtr error;
+  EXPECT_FALSE(dev_reg_->CheckRegistration(&error));
+  EXPECT_EQ(1, transport_->GetRequestCount());
+  EXPECT_TRUE(error->HasError(buffet::kErrorDomainOAuth2,
+                              "invalid_grant"));
+  EXPECT_EQ(RegistrationStatus::kInvalidCredentials,
+            dev_reg_->GetRegistrationStatus());
+}
+
 TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) {
   SetDefaultDeviceRegistration(&data_);
   storage_->Save(&data_);