Commit 7e9878b8 authored by munjal@chromium.org's avatar munjal@chromium.org

Add a mode to OAuth2MintTokenFlow that fetches the messages to show to the user.

Change OAuth2MintTokenFlow to use OAuth2ApiCallFlow.
Review URL: https://chromiumcodereview.appspot.com/10012051

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132242 0039d316-1c4b-4281-b951-d872f2087c98
parent e65251d7
...@@ -43,10 +43,16 @@ bool GetAuthTokenFunction::RunImpl() { ...@@ -43,10 +43,16 @@ bool GetAuthTokenFunction::RunImpl() {
TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
flow_.reset( flow_.reset(new OAuth2MintTokenFlow(
new OAuth2MintTokenFlow(profile()->GetRequestContext(), this)); profile()->GetRequestContext(),
flow_->Start(token_service->GetOAuth2LoginRefreshToken(), this,
extension->id(), oauth2_info.client_id, oauth2_info.scopes); OAuth2MintTokenFlow::Parameters(
token_service->GetOAuth2LoginRefreshToken(),
extension->id(),
oauth2_info.client_id,
oauth2_info.scopes,
OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE)));
flow_->Start();
return true; return true;
} }
......
...@@ -42,20 +42,6 @@ static const char kGetAccessTokenBodyWithScopeFormat[] = ...@@ -42,20 +42,6 @@ static const char kGetAccessTokenBodyWithScopeFormat[] =
static const char kAccessTokenKey[] = "access_token"; static const char kAccessTokenKey[] = "access_token";
static bool GetStringFromDictionary(const DictionaryValue* dict,
const std::string& key,
std::string* value) {
Value* json_value;
if (!dict->Get(key, &json_value))
return false;
if (json_value->GetType() != base::Value::TYPE_STRING)
return false;
StringValue* json_str_value = static_cast<StringValue*>(json_value);
json_str_value->GetAsString(value);
return true;
}
static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) { static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) {
CHECK(!status.is_success()); CHECK(!status.is_success());
if (status.status() == URLRequestStatus::CANCELED) { if (status.status() == URLRequestStatus::CANCELED) {
...@@ -210,5 +196,5 @@ bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse( ...@@ -210,5 +196,5 @@ bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
return false; return false;
DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
return GetStringFromDictionary(dict, kAccessTokenKey, access_token); return dict->GetString(kAccessTokenKey, access_token);
} }
...@@ -50,7 +50,7 @@ class OAuth2ApiCallFlow ...@@ -50,7 +50,7 @@ class OAuth2ApiCallFlow
virtual ~OAuth2ApiCallFlow(); virtual ~OAuth2ApiCallFlow();
// Start the flow. // Start the flow.
void Start(); virtual void Start();
// OAuth2AccessTokenFetcher implementation. // OAuth2AccessTokenFetcher implementation.
virtual void OnGetTokenSuccess(const std::string& access_token) OVERRIDE; virtual void OnGetTokenSuccess(const std::string& access_token) OVERRIDE;
......
...@@ -6,33 +6,93 @@ ...@@ -6,33 +6,93 @@
#define CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_ #define CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_
#include <string> #include <string>
#include <vector>
#include "base/memory/scoped_ptr.h" #include "chrome/common/net/gaia/oauth2_api_call_flow.h"
#include "base/memory/weak_ptr.h"
#include "chrome/common/net/gaia/oauth2_access_token_consumer.h"
#include "chrome/common/net/gaia/oauth2_access_token_fetcher.h"
#include "chrome/common/net/gaia/oauth2_mint_token_consumer.h"
#include "chrome/common/net/gaia/oauth2_mint_token_fetcher.h"
class GoogleServiceAuthError; class GoogleServiceAuthError;
class OAuth2MintTokenFlowTest; class OAuth2MintTokenFlowTest;
namespace base {
class DictionaryValue;
}
namespace content {
class URLFetcher;
}
namespace net { namespace net {
class URLRequestContextGetter; class URLRequestContextGetter;
} }
// IssueAdvice: messages to show to the user to get a user's approval.
// The structure is as follows:
// * Descritpion 1
// - Detail 1.1
// - Details 1.2
// * Description 2
// - Detail 2.1
// - Detail 2.2
// - Detail 2.3
// * Description 3
// - Detail 3.1
struct IssueAdviceInfoEntry {
public:
IssueAdviceInfoEntry();
~IssueAdviceInfoEntry();
std::string description;
std::vector<std::string> details;
bool operator==(const IssueAdviceInfoEntry& rhs) const;
};
typedef std::vector<IssueAdviceInfoEntry> IssueAdviceInfo;
// This class implements the OAuth2 flow to Google to mint an OAuth2 // This class implements the OAuth2 flow to Google to mint an OAuth2
// token for the given client and the given set of scopes from the // token for the given client and the given set of scopes from the
// OAuthLogin scoped "master" OAuth2 token for the user logged in to // OAuthLogin scoped "master" OAuth2 token for the user logged in to
// Chrome. // Chrome.
class OAuth2MintTokenFlow class OAuth2MintTokenFlow : public OAuth2ApiCallFlow {
: public OAuth2AccessTokenConsumer,
public OAuth2MintTokenConsumer {
public: public:
// There are four differnt modes when minting a token to grant
// access to third-party app for a user.
enum Mode {
// Get the messages to display to the user without minting a token.
MODE_ISSUE_ADVICE,
// Record a grant but do not get a token back.
MODE_RECORD_GRANT,
// Mint a token for an existing grant.
MODE_MINT_TOKEN_NO_FORCE,
// Mint a token forcefully even if there is no existing grant.
MODE_MINT_TOKEN_FORCE,
};
// Parameters needed to mint a token.
struct Parameters {
public:
Parameters();
Parameters(const std::string& rt,
const std::string& eid,
const std::string& cid,
const std::vector<std::string>& scopes_arg,
Mode mode_arg);
~Parameters();
std::string login_refresh_token;
std::string extension_id;
std::string client_id;
std::vector<std::string> scopes;
Mode mode;
};
class Delegate { class Delegate {
public: public:
virtual void OnMintTokenSuccess(const std::string& access_token) { } Delegate() {}
virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) { } virtual ~Delegate() {}
virtual void OnMintTokenSuccess(const std::string& access_token) {}
virtual void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice) {}
virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) {}
}; };
// An interceptor for tests. // An interceptor for tests.
...@@ -47,89 +107,47 @@ class OAuth2MintTokenFlow ...@@ -47,89 +107,47 @@ class OAuth2MintTokenFlow
static void SetInterceptorForTests(InterceptorForTests* interceptor); static void SetInterceptorForTests(InterceptorForTests* interceptor);
OAuth2MintTokenFlow(net::URLRequestContextGetter* context, OAuth2MintTokenFlow(net::URLRequestContextGetter* context,
Delegate* delegate); Delegate* delegate,
const Parameters& parameters);
virtual ~OAuth2MintTokenFlow(); virtual ~OAuth2MintTokenFlow();
// Start the process to mint a token. virtual void Start() OVERRIDE;
void Start(const std::string& login_refresh_token,
const std::string& extension_id,
const std::string& client_id,
const std::vector<std::string>& scopes);
// OAuth2AccessTokenConsumer implementation.
virtual void OnGetTokenSuccess(const std::string& access_token) OVERRIDE;
virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
// OAuth2MintTokenConsumer implementation.
virtual void OnMintTokenSuccess(const std::string& access_token) OVERRIDE;
virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
// Getters for various members.
const std::string& extension_id() const { return extension_id_; }
const std::string& client_id() const { return client_id_; }
protected: protected:
// Helper to create an instance of access token fetcher. // Implementation of template methods in OAuth2ApiCallFlow.
// Caller owns the returned instance. virtual GURL CreateApiCallUrl() OVERRIDE;
virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(); virtual std::string CreateApiCallBody() OVERRIDE;
// Helper to create an instance of mint token fetcher. virtual void ProcessApiCallSuccess(
// Caller owns the returned instance. const content::URLFetcher* source) OVERRIDE;
virtual OAuth2MintTokenFetcher* CreateMintTokenFetcher(); virtual void ProcessApiCallFailure(
const content::URLFetcher* source) OVERRIDE;
virtual void ProcessNewAccessToken(const std::string& access_token) OVERRIDE;
virtual void ProcessMintAccessTokenFailure(
const GoogleServiceAuthError& error) OVERRIDE;
private: private:
// The steps this class performs are:
// 1. Create a login scoped access token from login scoped refresh token.
// 2. Use login scoped access token to call the API to mint an access token
// for the app.
enum State {
INITIAL,
FETCH_LOGIN_ACCESS_TOKEN_STARTED,
FETCH_LOGIN_ACCESS_TOKEN_DONE,
MINT_ACCESS_TOKEN_STARTED,
MINT_ACCESS_TOKEN_DONE,
ERROR_STATE
};
enum SetupError {
NONE,
AUTH_ERROR,
INTERNAL_ERROR,
USER_CANCELLED,
// This is used for histograms, and should always be the last value.
SETUP_ERROR_BOUNDARY
};
friend class OAuth2MintTokenFlowTest; friend class OAuth2MintTokenFlowTest;
FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, CreateApiCallBody);
// Creates an instance of URLFetcher that does not send or save cookies. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseIssueAdviceResponse);
// The URLFether's method will be GET if body is empty, POST otherwise. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseMintTokenResponse);
// Caller owns the returned instance. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ProcessApiCallSuccess);
content::URLFetcher* CreateURLFetcher( FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ProcessApiCallFailure);
const GURL& url, const std::string& body, const std::string& auth_token); FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
void BeginGetLoginAccessToken(); ProcessMintAccessTokenFailure);
void EndGetLoginAccessToken(const GoogleServiceAuthError* error);
void BeginMintAccessToken(); void ReportSuccess(const std::string& access_token);
void EndMintAccessToken(const GoogleServiceAuthError* error); void ReportSuccess(const IssueAdviceInfo& issue_advice);
void ReportSuccess();
void ReportFailure(const GoogleServiceAuthError& error); void ReportFailure(const GoogleServiceAuthError& error);
static std::string GetErrorString(SetupError error); static bool ParseIssueAdviceResponse(
const base::DictionaryValue* dict, IssueAdviceInfo* issue_advice);
static bool ParseMintTokenResponse(
const base::DictionaryValue* dict, std::string* access_token);
net::URLRequestContextGetter* context_; net::URLRequestContextGetter* context_;
Delegate* delegate_; Delegate* delegate_;
State state_; Parameters parameters_;
std::string login_refresh_token_;
std::string extension_id_;
std::string client_id_;
std::vector<std::string> scopes_;
scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_;
scoped_ptr<OAuth2MintTokenFetcher> oauth2_mint_token_fetcher_;
std::string login_access_token_;
std::string app_access_token_;
DISALLOW_COPY_AND_ASSIGN(OAuth2MintTokenFlow); DISALLOW_COPY_AND_ASSIGN(OAuth2MintTokenFlow);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment