Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2388)

Unified Diff: chrome/browser/net/gaia/authentication_service.cc

Issue 6894027: Initial refactoring complete Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixed some tests that were broken by previous refactoring Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/net/gaia/authentication_service.cc
diff --git a/chrome/browser/net/gaia/authentication_service.cc b/chrome/browser/net/gaia/authentication_service.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8828204efe675ac94c3d757c62e76d09e7e06d71
--- /dev/null
+++ b/chrome/browser/net/gaia/authentication_service.cc
@@ -0,0 +1,261 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/gaia/authentication_service.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/net/gaia/gaia_auth_fetcher.h"
+#include "chrome/common/net/gaia/gaia_constants.h"
+#include "content/browser/browser_thread.h"
+#include "content/common/notification_service.h"
+#include "net/url_request/url_request_context_getter.h"
+
+// Unfortunately kNumServices must be defined in the .h.
+// TODO(chron): Sync doesn't use the TalkToken anymore so we can stop
+// requesting it.
+const char* AuthenticationService::kServices[] = {
+ GaiaConstants::kGaiaService,
+ GaiaConstants::kSyncService,
+ GaiaConstants::kTalkService,
+ GaiaConstants::kDeviceManagementService
+};
+
+// static
+const char AuthenticationService::kClientLoginVariant[] = "ClientLogin";
+const char AuthenticationService::kOAuthVariant[] = "OAuth 2.0";
+
+AuthenticationService::AuthenticationService()
+ : token_loading_query_(0) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
+
+AuthenticationService::~AuthenticationService() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ResetCredentialsInMemory();
+}
+
+void AuthenticationService::Initialize(const char* const source,
+ Profile* profile) {
+
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!source_.empty()) {
+ // Already initialized.
+ return;
+ }
+ getter_ = profile->GetRequestContext();
+ // Since the user can create a bookmark in incognito, sync may be running.
+ // Thus we have to go for explicit access.
+ web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS);
+ source_ = std::string(source);
+
+#ifndef NDEBUG
+ CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+ // Allow the token service to be cleared from the command line.
+ if (cmd_line->HasSwitch(switches::kClearAuthenticationService))
+ EraseTokensFromDB();
+
+ // Allow a token to be injected from the command line.
+ if (cmd_line->HasSwitch(switches::kSetToken)) {
+ std::string value = cmd_line->GetSwitchValueASCII(switches::kSetToken);
+ int separator = value.find(':');
+ std::string service = value.substr(0, separator);
+ std::string token = value.substr(separator + 1);
+ token_map_[service] = token;
+ SaveAuthTokenToDB(service, token);
+ }
+#endif
+
+ registrar_.Add(this,
+ NotificationType::TOKEN_UPDATED,
+ NotificationService::AllSources());
+}
+
+void AuthenticationService::ResetCredentialsInMemory() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Terminate any running fetchers. Callbacks will not return.
+ for (int i = 0; i < kNumServices; i++) {
+ fetchers_[i].reset();
+ }
+
+ // Cancel pending loads. Callbacks will not return.
+ if (token_loading_query_) {
+ web_data_service_->CancelRequest(token_loading_query_);
+ token_loading_query_ = 0;
+ }
+
+ token_map_.clear();
+ credentials_.reset();
+}
+
+void AuthenticationService::UpdateCredentials(
+ AuthenticationConsumer::AuthenticationResult* credentials) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ credentials_.reset(credentials);
+
+ // Cancels any currently running requests.
+ for (int i = 0; i < kNumServices; i++) {
+ // fetchers_[i].reset(new GaiaAuthFetcher(this, source_, getter_));
+ fetchers_[i].reset(NULL);
+// fetchers_[i].reset(AuthenticationFetcher::CreateAuthenticationFetcher(
+// this, source_, getter_));
+ }
+}
+
+void AuthenticationService::LoadTokensFromDB() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ token_loading_query_ = web_data_service_->GetAllTokens(this);
+}
+
+void AuthenticationService::SaveAuthTokenToDB(const std::string& service,
+ const std::string& auth_token) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ web_data_service_->SetTokenForService(service, auth_token);
+}
+
+void AuthenticationService::EraseTokensFromDB() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ web_data_service_->RemoveAllTokens();
+}
+
+bool AuthenticationService::AreCredentialsValid() const {
+ return credentials_->IsValid();
+}
+
+void AuthenticationService::StartFetchingTokens() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(AreCredentialsValid());
+ for (int i = 0; i < kNumServices; i++) {
+ fetchers_[i]->StartIssueAuthToken(*credentials_, kServices[i]);
+ }
+}
+
+// Services dependent on a token will check if a token is available.
+// If it isn't, they'll go to sleep until they get a token event.
+bool AuthenticationService::HasTokenForService(
+ const char* const service) const {
+ return token_map_.count(service) > 0;
+}
+
+const std::string& AuthenticationService::GetTokenForService(
+ const char* const service) const {
+
+ if (token_map_.count(service) > 0) {
+ // Note map[key] is not const.
+ return (*token_map_.find(service)).second;
+ }
+ return EmptyString();
+}
+
+// Note that this can fire twice or more for any given service.
+// It can fire once from the DB read, and then once from the initial
+// fetcher. Future fetches can cause more notification firings.
+// The DB read will not however fire a notification if the fetcher
+// returned first. So it's always safe to use the latest notification.
+void AuthenticationService::FireTokenAvailableNotification(
+ const std::string& service,
+ const std::string& auth_token) {
+
+ TokenAvailableDetails details(service, auth_token);
+ NotificationService::current()->Notify(
+ NotificationType::TOKEN_AVAILABLE,
+ Source<AuthenticationService>(this),
+ Details<const TokenAvailableDetails>(&details));
+}
+
+void AuthenticationService::FireTokenRequestFailedNotification(
+ const std::string& service,
+ const GoogleServiceAuthError& error) {
+
+ TokenRequestFailedDetails details(service, error);
+ NotificationService::current()->Notify(
+ NotificationType::TOKEN_REQUEST_FAILED,
+ Source<AuthenticationService>(this),
+ Details<const TokenRequestFailedDetails>(&details));
+}
+
+void AuthenticationService::IssueAuthTokenForTest(const std::string& service,
+ const std::string& auth_token) {
+ token_map_[service] = auth_token;
+ FireTokenAvailableNotification(service, auth_token);
+}
+
+void AuthenticationService::OnIssueAuthTokenSuccess(const std::string& service,
+ const std::string& auth_token) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ VLOG(1) << "Got an authorization token for " << service;
+ token_map_[service] = auth_token;
+ FireTokenAvailableNotification(service, auth_token);
+ SaveAuthTokenToDB(service, auth_token);
+}
+
+void AuthenticationService::OnIssueAuthTokenFailure(const std::string& service,
+ const GoogleServiceAuthError& error) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ LOG(WARNING) << "Auth token issuing failed for service:" << service;
+ FireTokenRequestFailedNotification(service, error);
+}
+
+void AuthenticationService::OnWebDataServiceRequestDone(
+ WebDataService::Handle h,
+ const WDTypedResult* result) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(token_loading_query_);
+ token_loading_query_ = 0;
+
+ // If the fetch failed, there will be no result. In that case, we just don't
+ // load any tokens at all from the DB.
+ if (result) {
+ DCHECK(result->GetType() == TOKEN_RESULT);
+ const WDResult<std::map<std::string, std::string> > * token_result =
+ static_cast<const WDResult<std::map<std::string, std::string> > * > (
+ result);
+ LoadTokensIntoMemory(token_result->GetValue(), &token_map_);
+ }
+
+ NotificationService::current()->Notify(
+ NotificationType::TOKEN_LOADING_FINISHED,
+ Source<AuthenticationService>(this),
+ NotificationService::NoDetails());
+}
+
+// Load tokens from the db_token map into the in memory token map.
+void AuthenticationService::LoadTokensIntoMemory(
+ const std::map<std::string, std::string>& db_tokens,
+ std::map<std::string, std::string>* in_memory_tokens) {
+
+ for (int i = 0; i < kNumServices; i++) {
+ // OnIssueAuthTokenSuccess should come from the same thread.
+ // If a token is already present in the map, it could only have
+ // come from a DB read or from IssueAuthToken. Since we should never
+ // fetch from the DB twice in a browser session, it must be from
+ // OnIssueAuthTokenSuccess, which is a live fetcher.
+ //
+ // Network fetched tokens take priority over DB tokens, so exclude tokens
+ // which have already been loaded by the fetcher.
+ if (!in_memory_tokens->count(kServices[i]) &&
+ db_tokens.count(kServices[i])) {
+ std::string db_token = db_tokens.find(kServices[i])->second;
+ if (!db_token.empty()) {
+ VLOG(1) << "Loading " << kServices[i] << "token from DB: " << db_token;
+ (*in_memory_tokens)[kServices[i]] = db_token;
+ FireTokenAvailableNotification(kServices[i], db_token);
+ // Failures are only for network errors.
+ }
+ }
+ }
+}
+
+void AuthenticationService::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NotificationType::TOKEN_UPDATED);
+ TokenAvailableDetails* tok_details =
+ Details<TokenAvailableDetails>(details).ptr();
+ OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token());
+}
« no previous file with comments | « chrome/browser/net/gaia/authentication_service.h ('k') | chrome/browser/net/gaia/authentication_service_unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698