Commit e1b2ceb3 authored by blundell's avatar blundell Committed by Commit bot

Move impl of identity.GetAuthToken() extension API to its own file

As a precursor to a refactoring of the identity extension API implementation
to use the Identity Service, I am moving the implementations of the six
identity extension API functions to their own files, rather than all
being lumped together in identity_api.*. This will make it easier to
analyze each of these function implementations independently and
incrementally convert them to use the Identity Service.

BUG=685654

Review-Url: https://codereview.chromium.org/2668203004
Cr-Commit-Position: refs/heads/master@{#447981}
parent 49e97227
...@@ -238,6 +238,8 @@ static_library("extensions") { ...@@ -238,6 +238,8 @@ static_library("extensions") {
"api/identity/identity_api.h", "api/identity/identity_api.h",
"api/identity/identity_constants.cc", "api/identity/identity_constants.cc",
"api/identity/identity_constants.h", "api/identity/identity_constants.h",
"api/identity/identity_get_auth_token_function.cc",
"api/identity/identity_get_auth_token_function.h",
"api/identity/identity_get_profile_user_info_function.cc", "api/identity/identity_get_profile_user_info_function.cc",
"api/identity/identity_get_profile_user_info_function.h", "api/identity/identity_get_profile_user_info_function.h",
"api/identity/identity_launch_web_auth_flow_function.cc", "api/identity/identity_launch_web_auth_flow_function.cc",
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/extensions/api/identity/extension_token_key.h" #include "chrome/browser/extensions/api/identity/extension_token_key.h"
#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h" #include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
#include "chrome/browser/extensions/api/identity/identity_get_auth_token_function.h"
#include "chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h" #include "chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h"
#include "chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h" #include "chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h"
#include "chrome/browser/extensions/api/identity/identity_mint_queue.h" #include "chrome/browser/extensions/api/identity/identity_mint_queue.h"
...@@ -31,18 +32,13 @@ ...@@ -31,18 +32,13 @@
#include "google_apis/gaia/oauth2_mint_token_flow.h" #include "google_apis/gaia/oauth2_mint_token_flow.h"
#include "google_apis/gaia/oauth2_token_service.h" #include "google_apis/gaia/oauth2_token_service.h"
class GoogleServiceAuthError;
class MockGetAuthTokenFunction;
namespace content { namespace content {
class BrowserContext; class BrowserContext;
} }
namespace extensions { namespace extensions {
class GetAuthTokenFunctionTest;
class IdentityGetAuthTokenFunction; class IdentityGetAuthTokenFunction;
class MockGetAuthTokenFunction;
class IdentityTokenCacheValue { class IdentityTokenCacheValue {
public: public:
...@@ -151,145 +147,6 @@ class IdentityGetAccountsFunction : public ChromeUIThreadExtensionFunction { ...@@ -151,145 +147,6 @@ class IdentityGetAccountsFunction : public ChromeUIThreadExtensionFunction {
ExtensionFunction::ResponseAction Run() override; ExtensionFunction::ResponseAction Run() override;
}; };
// identity.getAuthToken fetches an OAuth 2 function for the
// caller. The request has three sub-flows: non-interactive,
// interactive, and sign-in.
//
// In the non-interactive flow, getAuthToken requests a token from
// GAIA. GAIA may respond with a token, an error, or "consent
// required". In the consent required cases, getAuthToken proceeds to
// the second, interactive phase.
//
// The interactive flow presents a scope approval dialog to the
// user. If the user approves the request, a grant will be recorded on
// the server, and an access token will be returned to the caller.
//
// In some cases we need to display a sign-in dialog. Normally the
// profile will be signed in already, but if it turns out we need a
// new login token, there is a sign-in flow. If that flow completes
// successfully, getAuthToken proceeds to the non-interactive flow.
class IdentityGetAuthTokenFunction : public ChromeAsyncExtensionFunction,
public GaiaWebAuthFlow::Delegate,
public IdentityMintRequestQueue::Request,
public OAuth2MintTokenFlow::Delegate,
public IdentitySigninFlow::Delegate,
public OAuth2TokenService::Consumer {
public:
DECLARE_EXTENSION_FUNCTION("identity.getAuthToken",
EXPERIMENTAL_IDENTITY_GETAUTHTOKEN);
IdentityGetAuthTokenFunction();
const ExtensionTokenKey* GetExtensionTokenKeyForTest() {
return token_key_.get();
}
void Shutdown();
protected:
~IdentityGetAuthTokenFunction() override;
// IdentitySigninFlow::Delegate implementation:
void SigninSuccess() override;
void SigninFailed() override;
// GaiaWebAuthFlow::Delegate implementation:
void OnGaiaFlowFailure(GaiaWebAuthFlow::Failure failure,
GoogleServiceAuthError service_error,
const std::string& oauth_error) override;
void OnGaiaFlowCompleted(const std::string& access_token,
const std::string& expiration) override;
// Starts a login access token request.
virtual void StartLoginAccessTokenRequest();
// OAuth2TokenService::Consumer implementation:
void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
// Starts a mint token request to GAIA.
// Exposed for testing.
virtual void StartGaiaRequest(const std::string& login_access_token);
// Caller owns the returned instance.
// Exposed for testing.
virtual OAuth2MintTokenFlow* CreateMintTokenFlow();
std::unique_ptr<OAuth2TokenService::Request> login_token_request_;
private:
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest,
ComponentWithChromeClientId);
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest,
ComponentWithNormalClientId);
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, InteractiveQueueShutdown);
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, NoninteractiveShutdown);
// ExtensionFunction:
bool RunAsync() override;
// Helpers to report async function results to the caller.
void StartAsyncRun();
void CompleteAsyncRun(bool success);
void CompleteFunctionWithResult(const std::string& access_token);
void CompleteFunctionWithError(const std::string& error);
// Initiate/complete the sub-flows.
void StartSigninFlow();
void StartMintTokenFlow(IdentityMintRequestQueue::MintType type);
void CompleteMintTokenFlow();
// IdentityMintRequestQueue::Request implementation:
void StartMintToken(IdentityMintRequestQueue::MintType type) override;
// OAuth2MintTokenFlow::Delegate implementation:
void OnMintTokenSuccess(const std::string& access_token,
int time_to_live) override;
void OnMintTokenFailure(const GoogleServiceAuthError& error) override;
void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice) override;
#if defined(OS_CHROMEOS)
// Starts a login access token request for device robot account. This method
// will be called only in Chrome OS for:
// 1. Enterprise kiosk mode.
// 2. Whitelisted first party apps in public session.
virtual void StartDeviceLoginAccessTokenRequest();
bool IsOriginWhitelistedInPublicSession();
#endif
// Methods for invoking UI. Overridable for testing.
virtual void ShowLoginPopup();
virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice);
// Checks if there is a master login token to mint tokens for the extension.
bool HasLoginToken() const;
// Maps OAuth2 protocol errors to an error message returned to the
// developer in chrome.runtime.lastError.
std::string MapOAuth2ErrorToDescription(const std::string& error);
std::string GetOAuth2ClientId() const;
bool interactive_;
bool should_prompt_for_scopes_;
IdentityMintRequestQueue::MintType mint_token_flow_type_;
std::unique_ptr<OAuth2MintTokenFlow> mint_token_flow_;
OAuth2MintTokenFlow::Mode gaia_mint_token_mode_;
bool should_prompt_for_signin_;
std::unique_ptr<ExtensionTokenKey> token_key_;
std::string oauth2_client_id_;
// When launched in interactive mode, and if there is no existing grant,
// a permissions prompt will be popped up to the user.
IssueAdviceInfo issue_advice_;
std::unique_ptr<GaiaWebAuthFlow> gaia_web_auth_flow_;
std::unique_ptr<IdentitySigninFlow> signin_flow_;
};
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_ #endif // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#endif #endif
#include "chrome/browser/extensions/api/identity/identity_api.h" #include "chrome/browser/extensions/api/identity/identity_api.h"
#include "chrome/browser/extensions/api/identity/identity_constants.h" #include "chrome/browser/extensions/api/identity/identity_constants.h"
#include "chrome/browser/extensions/api/identity/identity_get_auth_token_function.h"
#include "chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h" #include "chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h"
#include "chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h" #include "chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h"
#include "chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.h" #include "chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.h"
......
// Copyright 2017 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.
#ifndef CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_GET_AUTH_TOKEN_FUNCTION_H_
#define CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_GET_AUTH_TOKEN_FUNCTION_H_
#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
#include "chrome/browser/extensions/api/identity/identity_mint_queue.h"
#include "chrome/browser/extensions/api/identity/identity_signin_flow.h"
#include "chrome/browser/extensions/chrome_extension_function.h"
#include "extensions/browser/extension_function_histogram_value.h"
#include "google_apis/gaia/oauth2_mint_token_flow.h"
#include "google_apis/gaia/oauth2_token_service.h"
namespace extensions {
// identity.getAuthToken fetches an OAuth 2 function for the
// caller. The request has three sub-flows: non-interactive,
// interactive, and sign-in.
//
// In the non-interactive flow, getAuthToken requests a token from
// GAIA. GAIA may respond with a token, an error, or "consent
// required". In the consent required cases, getAuthToken proceeds to
// the second, interactive phase.
//
// The interactive flow presents a scope approval dialog to the
// user. If the user approves the request, a grant will be recorded on
// the server, and an access token will be returned to the caller.
//
// In some cases we need to display a sign-in dialog. Normally the
// profile will be signed in already, but if it turns out we need a
// new login token, there is a sign-in flow. If that flow completes
// successfully, getAuthToken proceeds to the non-interactive flow.
class IdentityGetAuthTokenFunction : public ChromeAsyncExtensionFunction,
public GaiaWebAuthFlow::Delegate,
public IdentityMintRequestQueue::Request,
public OAuth2MintTokenFlow::Delegate,
public IdentitySigninFlow::Delegate,
public OAuth2TokenService::Consumer {
public:
DECLARE_EXTENSION_FUNCTION("identity.getAuthToken",
EXPERIMENTAL_IDENTITY_GETAUTHTOKEN);
IdentityGetAuthTokenFunction();
const ExtensionTokenKey* GetExtensionTokenKeyForTest() {
return token_key_.get();
}
void Shutdown();
protected:
~IdentityGetAuthTokenFunction() override;
// IdentitySigninFlow::Delegate implementation:
void SigninSuccess() override;
void SigninFailed() override;
// GaiaWebAuthFlow::Delegate implementation:
void OnGaiaFlowFailure(GaiaWebAuthFlow::Failure failure,
GoogleServiceAuthError service_error,
const std::string& oauth_error) override;
void OnGaiaFlowCompleted(const std::string& access_token,
const std::string& expiration) override;
// Starts a login access token request.
virtual void StartLoginAccessTokenRequest();
// OAuth2TokenService::Consumer implementation:
void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
// Starts a mint token request to GAIA.
// Exposed for testing.
virtual void StartGaiaRequest(const std::string& login_access_token);
// Caller owns the returned instance.
// Exposed for testing.
virtual OAuth2MintTokenFlow* CreateMintTokenFlow();
std::unique_ptr<OAuth2TokenService::Request> login_token_request_;
private:
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest,
ComponentWithChromeClientId);
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest,
ComponentWithNormalClientId);
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, InteractiveQueueShutdown);
FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, NoninteractiveShutdown);
// ExtensionFunction:
bool RunAsync() override;
// Helpers to report async function results to the caller.
void StartAsyncRun();
void CompleteAsyncRun(bool success);
void CompleteFunctionWithResult(const std::string& access_token);
void CompleteFunctionWithError(const std::string& error);
// Initiate/complete the sub-flows.
void StartSigninFlow();
void StartMintTokenFlow(IdentityMintRequestQueue::MintType type);
void CompleteMintTokenFlow();
// IdentityMintRequestQueue::Request implementation:
void StartMintToken(IdentityMintRequestQueue::MintType type) override;
// OAuth2MintTokenFlow::Delegate implementation:
void OnMintTokenSuccess(const std::string& access_token,
int time_to_live) override;
void OnMintTokenFailure(const GoogleServiceAuthError& error) override;
void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice) override;
#if defined(OS_CHROMEOS)
// Starts a login access token request for device robot account. This method
// will be called only in Chrome OS for:
// 1. Enterprise kiosk mode.
// 2. Whitelisted first party apps in public session.
virtual void StartDeviceLoginAccessTokenRequest();
bool IsOriginWhitelistedInPublicSession();
#endif
// Methods for invoking UI. Overridable for testing.
virtual void ShowLoginPopup();
virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice);
// Checks if there is a master login token to mint tokens for the extension.
bool HasLoginToken() const;
// Maps OAuth2 protocol errors to an error message returned to the
// developer in chrome.runtime.lastError.
std::string MapOAuth2ErrorToDescription(const std::string& error);
std::string GetOAuth2ClientId() const;
bool interactive_;
bool should_prompt_for_scopes_;
IdentityMintRequestQueue::MintType mint_token_flow_type_;
std::unique_ptr<OAuth2MintTokenFlow> mint_token_flow_;
OAuth2MintTokenFlow::Mode gaia_mint_token_mode_;
bool should_prompt_for_signin_;
std::unique_ptr<ExtensionTokenKey> token_key_;
std::string oauth2_client_id_;
// When launched in interactive mode, and if there is no existing grant,
// a permissions prompt will be popped up to the user.
IssueAdviceInfo issue_advice_;
std::unique_ptr<GaiaWebAuthFlow> gaia_web_auth_flow_;
std::unique_ptr<IdentitySigninFlow> signin_flow_;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_GET_AUTH_TOKEN_FUNCTION_H_
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