1 // Copyright (c) 2012 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.
5 #include "chrome/browser/chromeos/gdata/auth_service.h"
10 #include "base/bind.h"
11 #include "base/message_loop_proxy.h"
12 #include "chrome/browser/chromeos/gdata/operations_base.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/signin/token_service.h"
15 #include "chrome/browser/signin/token_service_factory.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/net/gaia/gaia_constants.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/notification_types.h"
23 using content::BrowserThread
;
27 void AuthService::Initialize(Profile
* profile
) {
29 // Get OAuth2 refresh token (if we have any) and register for its updates.
30 TokenService
* service
= TokenServiceFactory::GetForProfile(profile_
);
31 refresh_token_
= service
->GetOAuth2LoginRefreshToken();
33 chrome::NOTIFICATION_TOKEN_AVAILABLE
,
34 content::Source
<TokenService
>(service
));
36 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED
,
37 content::Source
<TokenService
>(service
));
39 if (!refresh_token_
.empty())
40 FOR_EACH_OBSERVER(Observer
, observers_
, OnOAuth2RefreshTokenChanged());
43 AuthService::AuthService(const std::vector
<std::string
>& scopes
)
46 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
50 AuthService::~AuthService() {
53 void AuthService::StartAuthentication(OperationRegistry
* registry
,
54 const AuthStatusCallback
& callback
) {
55 scoped_refptr
<base::MessageLoopProxy
> relay_proxy(
56 base::MessageLoopProxy::current());
58 if (HasAccessToken()) {
59 relay_proxy
->PostTask(FROM_HERE
,
60 base::Bind(callback
, gdata::HTTP_SUCCESS
, access_token_
));
61 } else if (HasRefreshToken()) {
62 BrowserThread::PostTask(
65 base::Bind(&AuthService::StartAuthenticationOnUIThread
,
66 weak_ptr_factory_
.GetWeakPtr(),
69 base::Bind(&AuthService::OnAuthCompleted
,
70 weak_ptr_factory_
.GetWeakPtr(),
74 relay_proxy
->PostTask(FROM_HERE
,
75 base::Bind(callback
, gdata::HTTP_UNAUTHORIZED
, std::string()));
79 void AuthService::StartAuthenticationOnUIThread(
80 OperationRegistry
* registry
,
81 scoped_refptr
<base::MessageLoopProxy
> relay_proxy
,
82 const AuthStatusCallback
& callback
) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
84 // We have refresh token, let's gets authenticated.
85 (new AuthOperation(registry
, callback
, scopes_
, refresh_token_
))->Start();
88 void AuthService::OnAuthCompleted(
89 scoped_refptr
<base::MessageLoopProxy
> relay_proxy
,
90 const AuthStatusCallback
& callback
,
92 const std::string
& access_token
) {
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
95 if (error
== HTTP_SUCCESS
)
96 access_token_
= access_token
;
98 // TODO(zelidrag): Add retry, back-off logic when things go wrong here.
99 if (!callback
.is_null())
100 relay_proxy
->PostTask(FROM_HERE
, base::Bind(callback
, error
, access_token
));
103 void AuthService::AddObserver(Observer
* observer
) {
104 observers_
.AddObserver(observer
);
107 void AuthService::RemoveObserver(Observer
* observer
) {
108 observers_
.RemoveObserver(observer
);
111 void AuthService::Observe(int type
,
112 const content::NotificationSource
& source
,
113 const content::NotificationDetails
& details
) {
114 DCHECK(type
== chrome::NOTIFICATION_TOKEN_AVAILABLE
||
115 type
== chrome::NOTIFICATION_TOKEN_REQUEST_FAILED
);
117 TokenService::TokenAvailableDetails
* token_details
=
118 content::Details
<TokenService::TokenAvailableDetails
>(details
).ptr();
119 if (token_details
->service() != GaiaConstants::kGaiaOAuth2LoginRefreshToken
)
122 access_token_
.clear();
123 if (type
== chrome::NOTIFICATION_TOKEN_AVAILABLE
) {
124 TokenService
* service
= TokenServiceFactory::GetForProfile(profile_
);
125 refresh_token_
= service
->GetOAuth2LoginRefreshToken();
127 refresh_token_
.clear();
129 FOR_EACH_OBSERVER(Observer
, observers_
, OnOAuth2RefreshTokenChanged());