drivefs_auth.cc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/components/drivefs/drivefs_auth.h"
  5. #include "base/bind.h"
  6. #include "components/account_id/account_id.h"
  7. #include "components/signin/public/base/consent_level.h"
  8. #include "components/signin/public/identity_manager/access_token_info.h"
  9. #include "components/signin/public/identity_manager/identity_manager.h"
  10. #include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
  11. #include "google_apis/gaia/google_service_auth_error.h"
  12. #include "services/network/public/cpp/shared_url_loader_factory.h"
  13. namespace drivefs {
  14. namespace {
  15. constexpr char kIdentityConsumerId[] = "drivefs";
  16. } // namespace
  17. DriveFsAuth::DriveFsAuth(const base::Clock* clock,
  18. const base::FilePath& profile_path,
  19. std::unique_ptr<base::OneShotTimer> timer,
  20. Delegate* delegate)
  21. : clock_(clock),
  22. profile_path_(profile_path),
  23. timer_(std::move(timer)),
  24. delegate_(delegate) {}
  25. DriveFsAuth::~DriveFsAuth() = default;
  26. absl::optional<std::string> DriveFsAuth::GetCachedAccessToken() {
  27. const auto& token = GetOrResetCachedToken(true);
  28. if (token.empty()) {
  29. return absl::nullopt;
  30. }
  31. return token;
  32. }
  33. void DriveFsAuth::GetAccessToken(
  34. bool use_cached,
  35. mojom::DriveFsDelegate::GetAccessTokenCallback callback) {
  36. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  37. if (get_access_token_callback_) {
  38. std::move(callback).Run(mojom::AccessTokenStatus::kTransientError, "");
  39. return;
  40. }
  41. const std::string& token = GetOrResetCachedToken(use_cached);
  42. if (!token.empty()) {
  43. std::move(callback).Run(mojom::AccessTokenStatus::kSuccess, token);
  44. return;
  45. }
  46. signin::IdentityManager* identity_manager = delegate_->GetIdentityManager();
  47. if (!identity_manager) {
  48. std::move(callback).Run(mojom::AccessTokenStatus::kAuthError, "");
  49. return;
  50. }
  51. get_access_token_callback_ = std::move(callback);
  52. // Timer is cancelled when it is destroyed, so use base::Unretained().
  53. timer_->Start(
  54. FROM_HERE, base::Seconds(30),
  55. base::BindOnce(&DriveFsAuth::AuthTimeout, base::Unretained(this)));
  56. std::set<std::string> scopes({"https://www.googleapis.com/auth/drive"});
  57. access_token_fetcher_ =
  58. std::make_unique<signin::PrimaryAccountAccessTokenFetcher>(
  59. kIdentityConsumerId, identity_manager, scopes,
  60. base::BindOnce(&DriveFsAuth::GotChromeAccessToken,
  61. base::Unretained(this)),
  62. signin::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable,
  63. signin::ConsentLevel::kSignin);
  64. }
  65. void DriveFsAuth::GotChromeAccessToken(
  66. GoogleServiceAuthError error,
  67. signin::AccessTokenInfo access_token_info) {
  68. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  69. timer_->Stop();
  70. if (error.state() != GoogleServiceAuthError::NONE) {
  71. std::move(get_access_token_callback_)
  72. .Run(error.IsPersistentError()
  73. ? mojom::AccessTokenStatus::kAuthError
  74. : mojom::AccessTokenStatus::kTransientError,
  75. "");
  76. return;
  77. }
  78. UpdateCachedToken(access_token_info.token, access_token_info.expiration_time);
  79. std::move(get_access_token_callback_)
  80. .Run(mojom::AccessTokenStatus::kSuccess, access_token_info.token);
  81. }
  82. const std::string& DriveFsAuth::GetOrResetCachedToken(bool use_cached) {
  83. if (!use_cached || clock_->Now() >= last_token_expiry_) {
  84. last_token_.clear();
  85. }
  86. return last_token_;
  87. }
  88. void DriveFsAuth::UpdateCachedToken(const std::string& token,
  89. base::Time expiry) {
  90. last_token_ = token;
  91. last_token_expiry_ = expiry;
  92. }
  93. void DriveFsAuth::AuthTimeout() {
  94. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  95. access_token_fetcher_.reset();
  96. std::move(get_access_token_callback_)
  97. .Run(mojom::AccessTokenStatus::kTransientError, "");
  98. }
  99. } // namespace drivefs