Wait for any token-exchange before using cached OAuth token.

This fixes the logic in OAuthTokenGetterImpl::CallWithToken() for the
case where the stored access-token is valid (not expired) but might
have the wrong scopes because it's not yet exchanged.

Bug: 954427
Change-Id: Ie5c397602b17c73ac4eb160869ed5f8d034d89a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1583119
Commit-Queue: Joe Downing <joedow@chromium.org>
Reviewed-by: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#653888}
diff --git a/remoting/base/oauth_token_getter_impl.cc b/remoting/base/oauth_token_getter_impl.cc
index f84ef11..8d63d29 100644
--- a/remoting/base/oauth_token_getter_impl.cc
+++ b/remoting/base/oauth_token_getter_impl.cc
@@ -185,8 +185,10 @@
 
 void OAuthTokenGetterImpl::CallWithToken(TokenCallback on_access_token) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  pending_callbacks_.push(std::move(on_access_token));
+
   if (intermediate_credentials_) {
-    pending_callbacks_.push(std::move(on_access_token));
     if (!response_pending_) {
       GetOauthTokensFromAuthCode();
     }
@@ -197,13 +199,19 @@
         (!authorization_credentials_->is_service_account && !email_verified_);
 
     if (need_new_auth_token) {
-      pending_callbacks_.push(std::move(on_access_token));
       if (!response_pending_) {
         RefreshAccessToken();
       }
     } else {
-      std::move(on_access_token)
-          .Run(SUCCESS, authorization_credentials_->login, oauth_access_token_);
+      // If |response_pending_| is true here, |oauth_access_token_| is
+      // up-to-date but not yet exchanged (it might not have the needed scopes).
+      // In that case, wait for token-exchange to complete before returning the
+      // token.
+      if (!response_pending_) {
+        NotifyTokenCallbacks(OAuthTokenGetterImpl::SUCCESS,
+                             authorization_credentials_->login,
+                             oauth_access_token_);
+      }
     }
   }
 }