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

Unified Diff: chrome/browser/extensions/api/identity/web_auth_flow.cc

Issue 10826078: Anti Phising UI for web auth flow window: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 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/browser/extensions/api/identity/web_auth_flow.cc
===================================================================
--- chrome/browser/extensions/api/identity/web_auth_flow.cc (revision 149223)
+++ chrome/browser/extensions/api/identity/web_auth_flow.cc (working copy)
@@ -10,15 +10,27 @@
#include "base/message_loop.h"
#include "base/stringprintf.h"
#include "base/string_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
-#include "content/public/browser/invalidate_type.h"
+#include "content/public/browser/load_notification_details.h"
#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/page_transition_types.h"
+#include "googleurl/src/gurl.h"
+#include "webkit/glue/window_open_disposition.h"
#include "ipc/ipc_message.h"
-using content::BrowserContext;
+using content::LoadNotificationDetails;
+using content::NavigationController;
+using content::ResourceRedirectDetails;
using content::WebContents;
-using content::WebContentsDelegate;
namespace {
@@ -33,24 +45,24 @@
WebAuthFlow::WebAuthFlow(
Delegate* delegate,
- BrowserContext* browser_context,
+ Profile* profile,
const std::string& extension_id,
const GURL& provider_url,
Mode mode)
: delegate_(delegate),
- browser_context_(browser_context),
+ profile_(profile),
provider_url_(provider_url),
mode_(mode),
contents_(NULL),
- window_(NULL) {
+ tab_contents_(NULL) {
InitValidRedirectUrlPrefixes(extension_id);
}
WebAuthFlow::~WebAuthFlow() {
- if (window_)
- delete window_;
+ if (tab_contents_) {
+ tab_contents_->web_contents()->Close();
+ }
if (contents_) {
- contents_->SetDelegate(NULL);
contents_->Stop();
// Tell message loop to delete contents_ instead of deleting it
// directly since destructor can run in response to a callback from
@@ -61,48 +73,64 @@
void WebAuthFlow::Start() {
contents_ = CreateWebContents();
- contents_->SetDelegate(this);
- contents_->GetController().LoadURL(
+
+ NavigationController* controller = &(contents_->GetController());
+
+ // Register for appropriate notifications to intercept navigation to the
+ // redirect URLs.
+ registrar_.Add(
+ this,
+ content::NOTIFICATION_LOAD_START,
+ content::Source<NavigationController>(controller));
+ registrar_.Add(
+ this,
+ content::NOTIFICATION_LOAD_STOP,
+ content::Source<NavigationController>(controller));
+ registrar_.Add(
+ this,
+ content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
+ content::Source<WebContents>(contents_));
+ registrar_.Add(
+ this,
+ content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
+ content::Source<WebContents>(contents_));
+
+ controller->LoadURL(
provider_url_,
content::Referrer(),
content::PAGE_TRANSITION_START_PAGE,
std::string());
}
-void WebAuthFlow::LoadingStateChanged(WebContents* source) {
- if (source->IsLoading())
- return;
- OnUrlLoaded();
+WebContents* WebAuthFlow::CreateWebContents() {
+ return WebContents::Create(profile_, NULL, MSG_ROUTING_NONE, NULL, NULL);
}
-void WebAuthFlow::NavigationStateChanged(
- const WebContents* source, unsigned changed_flags) {
- // If the URL has not changed, do not perform the check again (for
- // efficiency).
- if ((changed_flags & content::INVALIDATE_TYPE_URL) == 0)
- return;
+void WebAuthFlow::ShowAuthFlowPopup() {
+ // Pass ownership of WebContents to TabContents.
+ tab_contents_ = new TabContents(contents_);
+ contents_ = NULL;
+ Browser* browser = new Browser(Browser::CreateParams(
+ Browser::TYPE_POPUP, profile_));
+ chrome::NavigateParams params(browser, tab_contents_);
+ params.disposition = CURRENT_TAB;
+ params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+ chrome::Navigate(&params);
+ // Observe method will be called before URLs are loaded. That is where
+ // we check for redirect to the right URL.
+}
- // If the URL is a valid extension redirect URL, capture the
- // results and end the flow.
- const GURL& url = source->GetURL();
-
+bool WebAuthFlow::BeforeUrlLoaded(const GURL& url) {
if (IsValidRedirectUrl(url)) {
ReportResult(url);
+ return true;
}
+ return false;
}
-WebContents* WebAuthFlow::CreateWebContents() {
- return WebContents::Create(
- browser_context_, NULL, MSG_ROUTING_NONE, NULL, NULL);
-}
-
-WebAuthFlowWindow* WebAuthFlow::CreateAuthWindow() {
- return WebAuthFlowWindow::Create(this, browser_context_, contents_);
-}
-
-void WebAuthFlow::OnUrlLoaded() {
- // Do nothing if a window is already created.
- if (window_)
+void WebAuthFlow::AfterUrlLoaded() {
+ // Do nothing if a popup is already created.
+ if (tab_contents_)
return;
// Report results directly if not in interactive mode.
@@ -111,27 +139,58 @@
return;
}
- // We are in interactive mode and window is not shown yet; create
- // and show the window.
- window_ = CreateAuthWindow();
- window_->Show();
+ // We are in interactive mode and window is not shown yet; show the window.
+ ShowAuthFlowPopup();
}
-void WebAuthFlow::OnClose() {
- ReportResult(GURL());
+void WebAuthFlow::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case content::NOTIFICATION_LOAD_START: {
+ LoadNotificationDetails* load_details =
+ content::Details<LoadNotificationDetails>(details).ptr();
+ if (load_details != NULL)
+ BeforeUrlLoaded(load_details->url);
+ }
+ break;
+ case content::NOTIFICATION_LOAD_STOP: {
+ LoadNotificationDetails* load_details =
+ content::Details<LoadNotificationDetails>(details).ptr();
+ if (load_details != NULL)
+ AfterUrlLoaded();
+ }
+ break;
+ case content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: {
+ ResourceRedirectDetails* redirect_details =
+ content::Details<ResourceRedirectDetails>(details).ptr();
+ if (redirect_details != NULL)
+ BeforeUrlLoaded(redirect_details->new_url);
+ }
+ break;
+ case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
+ // User closed the auth flow window; report a failure.
+ ReportResult(GURL());
+ }
+ break;
+ default:
+ NOTREACHED() << "Got a notification that we did not register for: "
+ << type;
+ break;
+ }
}
-void WebAuthFlow::ReportResult(const GURL& result) {
+void WebAuthFlow::ReportResult(const GURL& url) {
if (!delegate_)
return;
- if (result.is_empty()) {
+ if (url.is_empty()) {
delegate_->OnAuthFlowFailure();
} else {
// TODO(munjal): Consider adding code to parse out access token
// from some common places (e.g. URL fragment) so the apps don't
// have to do that work.
- delegate_->OnAuthFlowSuccess(result.spec());
+ delegate_->OnAuthFlowSuccess(url.spec());
}
// IMPORTANT: Do not access any members after calling the delegate
@@ -139,6 +198,16 @@
// all data members are invalid after that.
}
+bool WebAuthFlow::IsValidRedirectUrl(const GURL& url) const {
+ std::vector<std::string>::const_iterator iter;
+ for (iter = valid_prefixes_.begin(); iter != valid_prefixes_.end(); ++iter) {
+ if (StartsWithASCII(url.spec(), *iter, false)) {
+ return true;
+ }
+ }
+ return false;
+}
+
void WebAuthFlow::InitValidRedirectUrlPrefixes(
const std::string& extension_id) {
valid_prefixes_.push_back(base::StringPrintf(
@@ -147,13 +216,4 @@
kChromiumDomainRedirectUrlPattern, extension_id.c_str()));
}
-bool WebAuthFlow::IsValidRedirectUrl(const GURL& url) const {
- std::vector<std::string>::const_iterator iter;
- for (iter = valid_prefixes_.begin(); iter != valid_prefixes_.end(); ++iter) {
- if (StartsWithASCII(url.spec(), *iter, false))
- return true;
- }
- return false;
-}
-
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698