This source file includes following definitions.
- callback_
- OnGetTokenSuccess
- OnGetTokenFailure
- weak_ptr_factory_
- StartAuthentication
- HasAccessToken
- HasRefreshToken
- access_token
- ClearAccessToken
- ClearRefreshToken
- OnAuthCompleted
- AddObserver
- RemoveObserver
- OnRefreshTokenAvailable
- OnRefreshTokenRevoked
- OnHandleRefreshToken
#include "google_apis/drive/auth_service.h"
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/metrics/histogram.h"
#include "google_apis/drive/auth_service_observer.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/url_request/url_request_context_getter.h"
namespace google_apis {
namespace {
const int kSuccessRatioHistogramFailure = 0;
const int kSuccessRatioHistogramSuccess = 1;
const int kSuccessRatioHistogramNoConnection = 2;
const int kSuccessRatioHistogramTemporaryFailure = 3;
const int kSuccessRatioHistogramMaxValue = 4;
class AuthRequest : public OAuth2TokenService::Consumer {
public:
AuthRequest(OAuth2TokenService* oauth2_token_service,
const std::string& account_id,
net::URLRequestContextGetter* url_request_context_getter,
const AuthStatusCallback& callback,
const std::vector<std::string>& scopes);
virtual ~AuthRequest();
private:
virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) OVERRIDE;
virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) OVERRIDE;
AuthStatusCallback callback_;
scoped_ptr<OAuth2TokenService::Request> request_;
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(AuthRequest);
};
AuthRequest::AuthRequest(
OAuth2TokenService* oauth2_token_service,
const std::string& account_id,
net::URLRequestContextGetter* url_request_context_getter,
const AuthStatusCallback& callback,
const std::vector<std::string>& scopes)
: OAuth2TokenService::Consumer("auth_service"),
callback_(callback) {
DCHECK(!callback_.is_null());
request_ = oauth2_token_service->
StartRequestWithContext(
account_id,
url_request_context_getter,
OAuth2TokenService::ScopeSet(scopes.begin(), scopes.end()),
this);
}
AuthRequest::~AuthRequest() {}
void AuthRequest::OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
DCHECK(thread_checker_.CalledOnValidThread());
UMA_HISTOGRAM_ENUMERATION("GData.AuthSuccess",
kSuccessRatioHistogramSuccess,
kSuccessRatioHistogramMaxValue);
callback_.Run(HTTP_SUCCESS, access_token);
delete this;
}
void AuthRequest::OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
DCHECK(thread_checker_.CalledOnValidThread());
LOG(WARNING) << "AuthRequest: token request using refresh token failed: "
<< error.ToString();
if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
UMA_HISTOGRAM_ENUMERATION("GData.AuthSuccess",
kSuccessRatioHistogramNoConnection,
kSuccessRatioHistogramMaxValue);
callback_.Run(GDATA_NO_CONNECTION, std::string());
} else if (error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE) {
UMA_HISTOGRAM_ENUMERATION("GData.AuthSuccess",
kSuccessRatioHistogramTemporaryFailure,
kSuccessRatioHistogramMaxValue);
callback_.Run(HTTP_FORBIDDEN, std::string());
} else {
UMA_HISTOGRAM_ENUMERATION("GData.AuthSuccess",
kSuccessRatioHistogramFailure,
kSuccessRatioHistogramMaxValue);
callback_.Run(HTTP_UNAUTHORIZED, std::string());
}
delete this;
}
}
AuthService::AuthService(
OAuth2TokenService* oauth2_token_service,
const std::string& account_id,
net::URLRequestContextGetter* url_request_context_getter,
const std::vector<std::string>& scopes)
: oauth2_token_service_(oauth2_token_service),
account_id_(account_id),
url_request_context_getter_(url_request_context_getter),
scopes_(scopes),
weak_ptr_factory_(this) {
DCHECK(oauth2_token_service);
oauth2_token_service_->AddObserver(this);
has_refresh_token_ = oauth2_token_service_->RefreshTokenIsAvailable(
account_id_);
}
AuthService::~AuthService() {
oauth2_token_service_->RemoveObserver(this);
}
void AuthService::StartAuthentication(const AuthStatusCallback& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
scoped_refptr<base::MessageLoopProxy> relay_proxy(
base::MessageLoopProxy::current());
if (HasAccessToken()) {
relay_proxy->PostTask(FROM_HERE,
base::Bind(callback, HTTP_SUCCESS, access_token_));
} else if (HasRefreshToken()) {
new AuthRequest(oauth2_token_service_,
account_id_,
url_request_context_getter_,
base::Bind(&AuthService::OnAuthCompleted,
weak_ptr_factory_.GetWeakPtr(),
callback),
scopes_);
} else {
relay_proxy->PostTask(FROM_HERE,
base::Bind(callback, GDATA_NOT_READY, std::string()));
}
}
bool AuthService::HasAccessToken() const {
return !access_token_.empty();
}
bool AuthService::HasRefreshToken() const {
return has_refresh_token_;
}
const std::string& AuthService::access_token() const {
return access_token_;
}
void AuthService::ClearAccessToken() {
access_token_.clear();
}
void AuthService::ClearRefreshToken() {
has_refresh_token_ = false;
FOR_EACH_OBSERVER(AuthServiceObserver,
observers_,
OnOAuth2RefreshTokenChanged());
}
void AuthService::OnAuthCompleted(const AuthStatusCallback& callback,
GDataErrorCode error,
const std::string& access_token) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!callback.is_null());
if (error == HTTP_SUCCESS) {
access_token_ = access_token;
} else if (error == HTTP_UNAUTHORIZED) {
ClearRefreshToken();
}
callback.Run(error, access_token);
}
void AuthService::AddObserver(AuthServiceObserver* observer) {
observers_.AddObserver(observer);
}
void AuthService::RemoveObserver(AuthServiceObserver* observer) {
observers_.RemoveObserver(observer);
}
void AuthService::OnRefreshTokenAvailable(const std::string& account_id) {
OnHandleRefreshToken(true);
}
void AuthService::OnRefreshTokenRevoked(const std::string& account_id) {
OnHandleRefreshToken(false);
}
void AuthService::OnHandleRefreshToken(bool has_refresh_token) {
access_token_.clear();
has_refresh_token_ = has_refresh_token;
FOR_EACH_OBSERVER(AuthServiceObserver,
observers_,
OnOAuth2RefreshTokenChanged());
}
}