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

Unified Diff: chrome/common/net/gaia/oauth2_mint_token_flow.cc

Issue 10012051: Add a mode to OAuth2MintTokenFlow that fetches the messages to show to the user. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 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/common/net/gaia/oauth2_mint_token_flow.cc
===================================================================
--- chrome/common/net/gaia/oauth2_mint_token_flow.cc (revision 130985)
+++ chrome/common/net/gaia/oauth2_mint_token_flow.cc (working copy)
@@ -10,19 +10,85 @@
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/json/json_reader.h"
#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/values.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/gaia/gaia_urls.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
+#include "content/public/common/url_fetcher.h"
+#include "net/base/escape.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_status.h"
+using content::URLFetcher;
using net::URLRequestContextGetter;
+using net::URLRequestStatus;
namespace {
+static const char kForceValueFalse[] = "false";
+static const char kForceValueTrue[] = "true";
+static const char kResponseTypeValueNone[] = "none";
+static const char kResponseTypeValueToken[] = "token";
+
+static const char kOAuth2IssueTokenBodyFormat[] =
+ "force=%s"
+ "&response_type=%s"
+ "&scope=%s"
+ "&client_id=%s"
+ "&origin=%s";
+static const char kIssueAdviceKey[] = "issueAdvice";
+static const char kIssueAdviceValueAuto[] = "auto";
+static const char kIssueAdviceValueConsent[] = "consent";
+static const char kAccessTokenKey[] = "token";
+static const char kConsentKey[] = "consent";
+static const char kScopesKey[] = "scopes";
+static const char kDescriptionKey[] = "description";
+static const char kDetailKey[] = "detail";
+static const char kDetailSeparators[] = "\n";
+
+static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) {
+ CHECK(!status.is_success());
+ if (status.status() == URLRequestStatus::CANCELED) {
+ return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
+ } else {
+ DLOG(WARNING) << "Could not reach Google Accounts servers: errno "
+ << status.error();
+ return GoogleServiceAuthError::FromConnectionError(status.error());
+ }
+}
+
OAuth2MintTokenFlow::InterceptorForTests* g_interceptor_for_tests = NULL;
} // namespace
+IssueAdviceInfoEntry::IssueAdviceInfoEntry() {}
+IssueAdviceInfoEntry::~IssueAdviceInfoEntry() {}
+
+bool IssueAdviceInfoEntry::operator ==(const IssueAdviceInfoEntry& rhs) const {
+ return description == rhs.description && details == rhs.details;
+}
+
+OAuth2MintTokenFlow::Parameters::Parameters() : mode(MODE_ISSUE_ADVICE) {}
+
+OAuth2MintTokenFlow::Parameters::Parameters(
+ const std::string& rt,
+ const std::string& eid,
+ const std::string& cid,
+ const std::vector<std::string>& scopes_arg,
+ Mode mode_arg)
+ : login_refresh_token(rt),
+ extension_id(eid),
+ client_id(cid),
+ scopes(scopes_arg),
+ mode(mode_arg) {
+}
+
+OAuth2MintTokenFlow::Parameters::~Parameters() {}
+
// static
void OAuth2MintTokenFlow::SetInterceptorForTests(
OAuth2MintTokenFlow::InterceptorForTests* interceptor) {
@@ -33,24 +99,19 @@
OAuth2MintTokenFlow::OAuth2MintTokenFlow(
URLRequestContextGetter* context,
- Delegate* delegate)
- : context_(context),
+ Delegate* delegate,
+ const Parameters& parameters)
+ : OAuth2ApiCallFlow(
+ context, parameters.login_refresh_token,
+ "", std::vector<std::string>()),
+ context_(context),
delegate_(delegate),
- state_(INITIAL) {
+ parameters_(parameters) {
}
OAuth2MintTokenFlow::~OAuth2MintTokenFlow() { }
-void OAuth2MintTokenFlow::Start(
- const std::string& login_refresh_token,
- const std::string& extension_id,
- const std::string& client_id,
- const std::vector<std::string>& scopes) {
- login_refresh_token_ = login_refresh_token;
- extension_id_ = extension_id;
- client_id_ = client_id;
- scopes_ = scopes;
-
+void OAuth2MintTokenFlow::Start() {
if (g_interceptor_for_tests) {
std::string auth_token;
GoogleServiceAuthError error = GoogleServiceAuthError::None();
@@ -72,100 +133,140 @@
return;
}
- BeginGetLoginAccessToken();
+ OAuth2ApiCallFlow::Start();
}
-void OAuth2MintTokenFlow::OnGetTokenSuccess(
- const std::string& access_token) {
- login_access_token_ = access_token;
- EndGetLoginAccessToken(NULL);
+void OAuth2MintTokenFlow::ReportSuccess(const std::string& access_token) {
+ if (delegate_) {
+ delegate_->OnMintTokenSuccess(access_token);
+ }
}
-void OAuth2MintTokenFlow::OnGetTokenFailure(
+void OAuth2MintTokenFlow::ReportSuccess(const IssueAdviceInfo& issue_advice) {
+ if (delegate_) {
+ delegate_->OnIssueAdviceSuccess(issue_advice);
+ }
+}
+
+void OAuth2MintTokenFlow::ReportFailure(
const GoogleServiceAuthError& error) {
- EndGetLoginAccessToken(&error);
+ if (delegate_) {
+ delegate_->OnMintTokenFailure(error);
+ }
}
-void OAuth2MintTokenFlow::BeginGetLoginAccessToken() {
- CHECK_EQ(INITIAL, state_);
- state_ = FETCH_LOGIN_ACCESS_TOKEN_STARTED;
+GURL OAuth2MintTokenFlow::CreateApiCallUrl() {
+ return GURL(GaiaUrls::GetInstance()->oauth2_issue_token_url());
+}
- oauth2_access_token_fetcher_.reset(CreateAccessTokenFetcher());
- oauth2_access_token_fetcher_->Start(
- GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
- GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
- login_refresh_token_,
- std::vector<std::string>());
+std::string OAuth2MintTokenFlow::CreateApiCallBody() {
+ const char* force_value =
+ (parameters_.mode == MODE_MINT_TOKEN_FORCE ||
+ parameters_.mode == MODE_RECORD_GRANT)
+ ? kForceValueTrue : kForceValueFalse;
+ const char* response_type_value =
+ (parameters_.mode == MODE_MINT_TOKEN_NO_FORCE ||
+ parameters_.mode == MODE_MINT_TOKEN_FORCE)
+ ? kResponseTypeValueToken : kResponseTypeValueNone;
+ return StringPrintf(
+ kOAuth2IssueTokenBodyFormat,
+ net::EscapeUrlEncodedData(force_value, true).c_str(),
+ net::EscapeUrlEncodedData(response_type_value, true).c_str(),
+ net::EscapeUrlEncodedData(
+ JoinString(parameters_.scopes, ' '), true).c_str(),
+ net::EscapeUrlEncodedData(parameters_.client_id, true).c_str(),
+ net::EscapeUrlEncodedData(parameters_.extension_id, true).c_str());
}
-void OAuth2MintTokenFlow::EndGetLoginAccessToken(
- const GoogleServiceAuthError* error) {
- CHECK_EQ(FETCH_LOGIN_ACCESS_TOKEN_STARTED, state_);
- if (!error) {
- state_ = FETCH_LOGIN_ACCESS_TOKEN_DONE;
- BeginMintAccessToken();
+void OAuth2MintTokenFlow::ProcessApiCallSuccess(
+ const content::URLFetcher* source) {
+ // TODO(munjal): Change error code paths in this method to report an
+ // internal error.
+ std::string response_body;
+ source->GetResponseAsString(&response_body);
+ base::JSONReader reader;
+ scoped_ptr<base::Value> value(reader.Read(response_body, false));
+ DictionaryValue* dict = NULL;
+ if (!value.get() || !value->GetAsDictionary(&dict)) {
+ ReportFailure(GoogleServiceAuthError::FromConnectionError(101));
+ return;
+ }
+
+ std::string issue_advice;
+ if (!dict->GetString(kIssueAdviceKey, &issue_advice)) {
+ ReportFailure(GoogleServiceAuthError::FromConnectionError(101));
+ return;
+ }
+ if (issue_advice == kIssueAdviceValueConsent) {
+ IssueAdviceInfo issue_advice;
+ if (ParseIssueAdviceResponse(dict, &issue_advice))
+ ReportSuccess(issue_advice);
+ else
+ ReportFailure(GoogleServiceAuthError::FromConnectionError(101));
} else {
- state_ = ERROR_STATE;
- ReportFailure(*error);
+ std::string access_token;
+ if (ParseMintTokenResponse(dict, &access_token))
+ ReportSuccess(access_token);
+ else
+ ReportFailure(GoogleServiceAuthError::FromConnectionError(101));
}
}
-void OAuth2MintTokenFlow::OnMintTokenSuccess(
+void OAuth2MintTokenFlow::ProcessApiCallFailure(
+ const content::URLFetcher* source) {
+ ReportFailure(CreateAuthError(source->GetStatus()));
+}
+void OAuth2MintTokenFlow::ProcessNewAccessToken(
const std::string& access_token) {
- app_access_token_ = access_token;
- EndMintAccessToken(NULL);
+ // We don't currently store new access tokens. We generate one every time.
+ // So we have nothing to do here.
+ return;
}
-void OAuth2MintTokenFlow::OnMintTokenFailure(
+void OAuth2MintTokenFlow::ProcessMintAccessTokenFailure(
const GoogleServiceAuthError& error) {
- EndMintAccessToken(&error);
+ ReportFailure(error);
}
-void OAuth2MintTokenFlow::BeginMintAccessToken() {
- CHECK_EQ(FETCH_LOGIN_ACCESS_TOKEN_DONE, state_);
- state_ = MINT_ACCESS_TOKEN_STARTED;
-
- oauth2_mint_token_fetcher_.reset(CreateMintTokenFetcher());
- oauth2_mint_token_fetcher_->Start(
- login_access_token_,
- client_id_,
- scopes_,
- extension_id_);
+// static
+bool OAuth2MintTokenFlow::ParseMintTokenResponse(
+ const base::DictionaryValue* dict, std::string* access_token) {
+ CHECK(dict);
+ CHECK(access_token);
+ return dict->GetString(kAccessTokenKey, access_token);
}
-void OAuth2MintTokenFlow::EndMintAccessToken(
- const GoogleServiceAuthError* error) {
- CHECK_EQ(MINT_ACCESS_TOKEN_STARTED, state_);
+// static
+bool OAuth2MintTokenFlow::ParseIssueAdviceResponse(
+ const base::DictionaryValue* dict, IssueAdviceInfo* issue_advice) {
+ CHECK(dict);
+ CHECK(issue_advice);
- if (!error) {
- state_ = MINT_ACCESS_TOKEN_DONE;
- ReportSuccess();
- } else {
- state_ = ERROR_STATE;
- ReportFailure(*error);
- }
-}
+ base::DictionaryValue* consent_dict = NULL;
+ if (!dict->GetDictionary(kConsentKey, &consent_dict))
+ return false;
-void OAuth2MintTokenFlow::ReportSuccess() {
- CHECK_EQ(MINT_ACCESS_TOKEN_DONE, state_);
+ base::ListValue* scopes_list = NULL;
+ if (!consent_dict->GetList(kScopesKey, &scopes_list))
+ return false;
- if (delegate_) {
- delegate_->OnMintTokenSuccess(app_access_token_);
- }
-}
+ bool success = true;
+ for (size_t index = 0; index < scopes_list->GetSize(); ++index) {
+ base::DictionaryValue* scopes_entry = NULL;
+ IssueAdviceInfoEntry entry;
+ std::string detail;
+ if (!scopes_list->GetDictionary(index, &scopes_entry) ||
+ !scopes_entry->GetString(kDescriptionKey, &entry.description) ||
+ !scopes_entry->GetString(kDetailKey, &detail)) {
+ success = false;
+ break;
+ }
-void OAuth2MintTokenFlow::ReportFailure(
- const GoogleServiceAuthError& error) {
- CHECK_EQ(ERROR_STATE, state_);
-
- if (delegate_) {
- delegate_->OnMintTokenFailure(error);
+ Tokenize(detail, kDetailSeparators, &entry.details);
+ issue_advice->push_back(entry);
}
-}
-OAuth2AccessTokenFetcher* OAuth2MintTokenFlow::CreateAccessTokenFetcher() {
- return new OAuth2AccessTokenFetcher(this, context_);
-}
+ if (!success)
+ issue_advice->clear();
-OAuth2MintTokenFetcher* OAuth2MintTokenFlow::CreateMintTokenFetcher() {
- return new OAuth2MintTokenFetcher(this, context_, "OAuth2MintTokenFlow");
+ return success;
}
« no previous file with comments | « chrome/common/net/gaia/oauth2_mint_token_flow.h ('k') | chrome/common/net/gaia/oauth2_mint_token_flow_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698