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

Side by Side Diff: chrome/browser/extensions/api/identity/extension_auth_flow.cc

Issue 10178020: Start implementing an auth flow for platform apps to be able to do auth (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/identity/extension_auth_flow.h"
6
7 #include "base/location.h"
8 #include "base/message_loop.h"
9 #include "base/stringprintf.h"
10 #include "base/string_util.h"
11 #include "content/public/browser/invalidate_type.h"
12 #include "content/public/browser/navigation_controller.h"
13 #include "ipc/ipc_message.h"
14
15 using content::BrowserContext;
16 using content::WebContents;
17 using content::WebContentsDelegate;
18 using views::View;
19 using views::WebView;
20 using views::Widget;
21 using views::WidgetDelegate;
22
23 namespace {
24
25 static const char kChromeExtensionSchemeUrlPattern[] =
26 "chrome-extension://%s/";
27 static const char kChromiumDomainRedirectUrlPattern[] =
28 "https://%s.ext.chromium.org/";
Mihai Parparita -not on Chrome 2012/05/04 22:37:18 I would prefer not use chromium.org, since it's st
Munjal (Google) 2012/05/08 19:26:35 Done.
29
30 static void PopulateValidRedirectUrlPrefixes(
Mihai Parparita -not on Chrome 2012/05/04 22:37:18 Not sure I see the benefit of making this into a s
Munjal (Google) 2012/05/08 19:26:35 Done.
31 const std::string& extension_id,
32 std::vector<std::string>* list) {
33 CHECK(list);
34 list->push_back(base::StringPrintf(kChromeExtensionSchemeUrlPattern,
35 extension_id.c_str()));
36 list->push_back(base::StringPrintf(kChromiumDomainRedirectUrlPattern,
37 extension_id.c_str()));
38 }
39
40 } // namespace
41
42 namespace extensions {
43
44 ExtensionAuthFlow::ExtensionAuthFlow(
45 Delegate* delegate,
46 content::BrowserContext* browser_context,
47 const std::string& extension_id,
48 const GURL& provider_url)
49 : delegate_(delegate),
50 browser_context_(browser_context),
51 extension_id_(extension_id),
Mihai Parparita -not on Chrome 2012/05/04 22:37:18 The extension_id_ member is otherwise unused, you
Munjal (Google) 2012/05/08 19:26:35 Done.
Munjal (Google) 2012/05/08 19:26:35 Done.
52 provider_url_(provider_url),
53 contents_(NULL),
54 widget_(NULL),
55 web_view_(NULL) {
56 PopulateValidRedirectUrlPrefixes(extension_id_, &valid_prefixes_);
57 }
58
59 ExtensionAuthFlow::~ExtensionAuthFlow() {
60 if (widget_)
61 widget_->Close(); // Close() deletes the widget also.
62 if (contents_) {
63 contents_->SetDelegate(NULL);
64 contents_->Stop();
65 // Tell message loop to delete contents_ instead of deleting it
66 // directly since destructor can run in response to a callback from
67 // contents_.
68 MessageLoop::current()->DeleteSoon(FROM_HERE, contents_);
69 }
70 }
71
72 void ExtensionAuthFlow::Start() {
73 contents_ = WebContents::Create(
74 browser_context_, NULL, MSG_ROUTING_NONE, NULL, NULL);
75 contents_->SetDelegate(this);
76 contents_->GetController().LoadURL(
77 provider_url_,
78 content::Referrer(),
79 content::PAGE_TRANSITION_START_PAGE,
80 std::string());
81 }
82
83 void ExtensionAuthFlow::LoadingStateChanged(WebContents* source) {
84 if (source->IsLoading())
85 return;
86 OnUrlLoaded();
87 }
88
89 void ExtensionAuthFlow::NavigationStateChanged(
90 const WebContents* source, unsigned changed_flags) {
91 // If the URL has not changed, do not perform the check again (for
92 // efficiency).
93 if ((changed_flags & content::INVALIDATE_TYPE_URL) == 0)
94 return;
95
96 const GURL& url = source->GetURL();
97
98 // If the URL being loaded is not from the provider host, then
99 // we are done with the flow.
Mihai Parparita -not on Chrome 2012/05/04 22:37:18 I don't think this is quite true. If I'm not signe
Munjal (Google) 2012/05/08 19:26:35 I put in some thought into this but not enough to
100 if (url.host() != provider_url_.host()) {
101 // The URL is either a valid extension redirect URL or an
102 // invalid URL.
103 if (IsValidExtensionRedirectUrl(url))
104 result_ = url;
Mihai Parparita -not on Chrome 2012/05/04 22:37:18 I don't think result_ should be a member, instead
Munjal (Google) 2012/05/08 19:26:35 Done.
105
106 ReportResult();
107 return;
108 }
109 }
110
111 void ExtensionAuthFlow::OnUrlLoaded() {
112 const GURL& url = contents_->GetURL();
113 CHECK_EQ(url.host(), provider_url_.host());
114
115 if (!widget_) {
116 web_view_ = new WebView(browser_context_);
117 web_view_->SetWebContents(contents_);
118 widget_ = Widget::CreateWindow(this);
Avi (use Gerrit) 2012/05/07 23:31:13 This is just a floating window, popup-like without
Munjal (Google) 2012/05/08 19:26:35 I am not aware of what is the difference between a
119 widget_->CenterWindow(gfx::Size(1024, 768));
Mihai Parparita -not on Chrome 2012/05/04 22:37:18 TODO about making this configurable?
Munjal (Google) 2012/05/08 19:26:35 Done. I suppose you meant the size of the window.
120 widget_->Show();
Mihai Parparita -not on Chrome 2012/05/04 22:37:18 So we only show the window once the initial URL ha
Munjal (Google) 2012/05/08 19:26:35 Yes, this is actually intentional. We will not sho
121 }
122 }
123
124 View* ExtensionAuthFlow::GetContentsView() {
125 CHECK(web_view_);
126 return web_view_;
127 }
128
129 Widget* ExtensionAuthFlow::GetWidget() {
130 CHECK(widget_);
131 return widget_;
132 }
133
134 const Widget* ExtensionAuthFlow::GetWidget() const {
135 CHECK(widget_);
136 return widget_;
137 }
138
139 View* ExtensionAuthFlow::GetInitiallyFocusedView() {
140 CHECK(web_view_);
141 return web_view_;
142 }
143
144 void ExtensionAuthFlow::DeleteDelegate() {
145 ReportResult();
146 }
147
148 void ExtensionAuthFlow::ReportResult() {
149 if (!delegate_)
150 return;
151
152 if (result_.is_empty()) {
153 delegate_->OnAuthFlowFailed();
154 } else {
155 // TODO(munjal): Consider adding code to parse out access token
156 // from some common places (e.g. URL fragment) so the apps don't
157 // have to do that work.
158 delegate_->OnAuthFlowCompleted(result_.spec());
159 }
160
161 // IMPORTANT: Do not access any members after calling the delegate
162 // since the delegate can destroy |this| in the callback and hence
163 // all data members are invalid after that.
164 }
165
166 bool ExtensionAuthFlow::IsValidExtensionRedirectUrl(const GURL& url) const {
167 std::vector<std::string>::const_iterator iter;
168 for (iter = valid_prefixes_.begin(); iter != valid_prefixes_.end(); ++iter) {
169 if (StartsWithASCII(url.spec(), *iter, false))
170 return true;
171 }
172 return false;
173 }
174
175 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698