OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/identity/web_auth_flow.h" | 5 #include "chrome/browser/extensions/api/identity/web_auth_flow.h" |
6 | 6 |
7 #include "apps/shell_window.h" | 7 #include "apps/app_window.h" |
8 #include "base/base64.h" | 8 #include "base/base64.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/browser/extensions/component_loader.h" | 13 #include "chrome/browser/extensions/component_loader.h" |
14 #include "chrome/browser/extensions/extension_service.h" | 14 #include "chrome/browser/extensions/extension_service.h" |
15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/common/extensions/api/identity_private.h" | 16 #include "chrome/common/extensions/api/identity_private.h" |
17 #include "chrome/common/extensions/extension_constants.h" | 17 #include "chrome/common/extensions/extension_constants.h" |
18 #include "content/public/browser/navigation_details.h" | 18 #include "content/public/browser/navigation_details.h" |
19 #include "content/public/browser/navigation_entry.h" | 19 #include "content/public/browser/navigation_entry.h" |
20 #include "content/public/browser/notification_details.h" | 20 #include "content/public/browser/notification_details.h" |
21 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
22 #include "content/public/browser/notification_source.h" | 22 #include "content/public/browser/notification_source.h" |
23 #include "content/public/browser/notification_types.h" | 23 #include "content/public/browser/notification_types.h" |
24 #include "content/public/browser/render_view_host.h" | 24 #include "content/public/browser/render_view_host.h" |
25 #include "content/public/browser/resource_request_details.h" | 25 #include "content/public/browser/resource_request_details.h" |
26 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
27 #include "crypto/random.h" | 27 #include "crypto/random.h" |
28 #include "extensions/browser/event_router.h" | 28 #include "extensions/browser/event_router.h" |
29 #include "extensions/browser/extension_system.h" | 29 #include "extensions/browser/extension_system.h" |
30 #include "grit/browser_resources.h" | 30 #include "grit/browser_resources.h" |
31 #include "url/gurl.h" | 31 #include "url/gurl.h" |
32 | 32 |
33 using apps::ShellWindow; | 33 using apps::AppWindow; |
34 using content::RenderViewHost; | 34 using content::RenderViewHost; |
35 using content::ResourceRedirectDetails; | 35 using content::ResourceRedirectDetails; |
36 using content::WebContents; | 36 using content::WebContents; |
37 using content::WebContentsObserver; | 37 using content::WebContentsObserver; |
38 | 38 |
39 namespace extensions { | 39 namespace extensions { |
40 | 40 |
41 namespace identity_private = api::identity_private; | 41 namespace identity_private = api::identity_private; |
42 | 42 |
43 WebAuthFlow::WebAuthFlow( | 43 WebAuthFlow::WebAuthFlow( |
44 Delegate* delegate, | 44 Delegate* delegate, |
45 Profile* profile, | 45 Profile* profile, |
46 const GURL& provider_url, | 46 const GURL& provider_url, |
47 Mode mode) | 47 Mode mode) |
48 : delegate_(delegate), | 48 : delegate_(delegate), |
49 profile_(profile), | 49 profile_(profile), |
50 provider_url_(provider_url), | 50 provider_url_(provider_url), |
51 mode_(mode), | 51 mode_(mode), |
52 embedded_window_created_(false) { | 52 embedded_window_created_(false) { |
53 } | 53 } |
54 | 54 |
55 WebAuthFlow::~WebAuthFlow() { | 55 WebAuthFlow::~WebAuthFlow() { |
56 DCHECK(delegate_ == NULL); | 56 DCHECK(delegate_ == NULL); |
57 | 57 |
58 // Stop listening to notifications first since some of the code | 58 // Stop listening to notifications first since some of the code |
59 // below may generate notifications. | 59 // below may generate notifications. |
60 registrar_.RemoveAll(); | 60 registrar_.RemoveAll(); |
61 WebContentsObserver::Observe(NULL); | 61 WebContentsObserver::Observe(NULL); |
62 | 62 |
63 if (!shell_window_key_.empty()) { | 63 if (!app_window_key_.empty()) { |
64 apps::ShellWindowRegistry::Get(profile_)->RemoveObserver(this); | 64 apps::AppWindowRegistry::Get(profile_)->RemoveObserver(this); |
65 | 65 |
66 if (shell_window_ && shell_window_->web_contents()) | 66 if (app_window_ && app_window_->web_contents()) |
67 shell_window_->web_contents()->Close(); | 67 app_window_->web_contents()->Close(); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 void WebAuthFlow::Start() { | 71 void WebAuthFlow::Start() { |
72 apps::ShellWindowRegistry::Get(profile_)->AddObserver(this); | 72 apps::AppWindowRegistry::Get(profile_)->AddObserver(this); |
73 | 73 |
74 // Attach a random ID string to the window so we can recoginize it | 74 // Attach a random ID string to the window so we can recoginize it |
75 // in OnShellWindowAdded. | 75 // in OnAppWindowAdded. |
76 std::string random_bytes; | 76 std::string random_bytes; |
77 crypto::RandBytes(WriteInto(&random_bytes, 33), 32); | 77 crypto::RandBytes(WriteInto(&random_bytes, 33), 32); |
78 base::Base64Encode(random_bytes, &shell_window_key_); | 78 base::Base64Encode(random_bytes, &app_window_key_); |
79 | 79 |
80 // identityPrivate.onWebFlowRequest(shell_window_key, provider_url_, mode_) | 80 // identityPrivate.onWebFlowRequest(shell_window_key, provider_url_, mode_) |
81 scoped_ptr<base::ListValue> args(new base::ListValue()); | 81 scoped_ptr<base::ListValue> args(new base::ListValue()); |
82 args->AppendString(shell_window_key_); | 82 args->AppendString(app_window_key_); |
83 args->AppendString(provider_url_.spec()); | 83 args->AppendString(provider_url_.spec()); |
84 if (mode_ == WebAuthFlow::INTERACTIVE) | 84 if (mode_ == WebAuthFlow::INTERACTIVE) |
85 args->AppendString("interactive"); | 85 args->AppendString("interactive"); |
86 else | 86 else |
87 args->AppendString("silent"); | 87 args->AppendString("silent"); |
88 | 88 |
89 scoped_ptr<Event> event( | 89 scoped_ptr<Event> event( |
90 new Event(identity_private::OnWebFlowRequest::kEventName, args.Pass())); | 90 new Event(identity_private::OnWebFlowRequest::kEventName, args.Pass())); |
91 event->restrict_to_browser_context = profile_; | 91 event->restrict_to_browser_context = profile_; |
92 ExtensionSystem* system = ExtensionSystem::Get(profile_); | 92 ExtensionSystem* system = ExtensionSystem::Get(profile_); |
93 | 93 |
94 extensions::ComponentLoader* component_loader = | 94 extensions::ComponentLoader* component_loader = |
95 system->extension_service()->component_loader(); | 95 system->extension_service()->component_loader(); |
96 if (!component_loader->Exists(extension_misc::kIdentityApiUiAppId)) { | 96 if (!component_loader->Exists(extension_misc::kIdentityApiUiAppId)) { |
97 component_loader->Add( | 97 component_loader->Add( |
98 IDR_IDENTITY_API_SCOPE_APPROVAL_MANIFEST, | 98 IDR_IDENTITY_API_SCOPE_APPROVAL_MANIFEST, |
99 base::FilePath(FILE_PATH_LITERAL("identity_scope_approval_dialog"))); | 99 base::FilePath(FILE_PATH_LITERAL("identity_scope_approval_dialog"))); |
100 } | 100 } |
101 | 101 |
102 system->event_router()->DispatchEventWithLazyListener( | 102 system->event_router()->DispatchEventWithLazyListener( |
103 extension_misc::kIdentityApiUiAppId, event.Pass()); | 103 extension_misc::kIdentityApiUiAppId, event.Pass()); |
104 } | 104 } |
105 | 105 |
106 void WebAuthFlow::DetachDelegateAndDelete() { | 106 void WebAuthFlow::DetachDelegateAndDelete() { |
107 delegate_ = NULL; | 107 delegate_ = NULL; |
108 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 108 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
109 } | 109 } |
110 | 110 |
111 void WebAuthFlow::OnShellWindowAdded(ShellWindow* shell_window) { | 111 void WebAuthFlow::OnAppWindowAdded(AppWindow* app_window) { |
112 if (shell_window->window_key() == shell_window_key_ && | 112 if (app_window->window_key() == app_window_key_ && |
113 shell_window->extension()->id() == extension_misc::kIdentityApiUiAppId) { | 113 app_window->extension()->id() == extension_misc::kIdentityApiUiAppId) { |
114 shell_window_ = shell_window; | 114 app_window_ = app_window; |
115 WebContentsObserver::Observe(shell_window->web_contents()); | 115 WebContentsObserver::Observe(app_window->web_contents()); |
116 | 116 |
117 registrar_.Add( | 117 registrar_.Add( |
118 this, | 118 this, |
119 content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, | 119 content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, |
120 content::NotificationService::AllBrowserContextsAndSources()); | 120 content::NotificationService::AllBrowserContextsAndSources()); |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
124 void WebAuthFlow::OnShellWindowIconChanged(ShellWindow* shell_window) {} | 124 void WebAuthFlow::OnAppWindowIconChanged(AppWindow* app_window) {} |
125 | 125 |
126 void WebAuthFlow::OnShellWindowRemoved(ShellWindow* shell_window) { | 126 void WebAuthFlow::OnAppWindowRemoved(AppWindow* app_window) { |
127 if (shell_window->window_key() == shell_window_key_ && | 127 if (app_window->window_key() == app_window_key_ && |
128 shell_window->extension()->id() == extension_misc::kIdentityApiUiAppId) { | 128 app_window->extension()->id() == extension_misc::kIdentityApiUiAppId) { |
129 shell_window_ = NULL; | 129 app_window_ = NULL; |
130 registrar_.RemoveAll(); | 130 registrar_.RemoveAll(); |
131 | 131 |
132 if (delegate_) | 132 if (delegate_) |
133 delegate_->OnAuthFlowFailure(WebAuthFlow::WINDOW_CLOSED); | 133 delegate_->OnAuthFlowFailure(WebAuthFlow::WINDOW_CLOSED); |
134 } | 134 } |
135 } | 135 } |
136 | 136 |
137 void WebAuthFlow::BeforeUrlLoaded(const GURL& url) { | 137 void WebAuthFlow::BeforeUrlLoaded(const GURL& url) { |
138 if (delegate_ && embedded_window_created_) | 138 if (delegate_ && embedded_window_created_) |
139 delegate_->OnAuthFlowURLChange(url); | 139 delegate_->OnAuthFlowURLChange(url); |
140 } | 140 } |
141 | 141 |
142 void WebAuthFlow::AfterUrlLoaded() { | 142 void WebAuthFlow::AfterUrlLoaded() { |
143 if (delegate_ && embedded_window_created_ && mode_ == WebAuthFlow::SILENT) | 143 if (delegate_ && embedded_window_created_ && mode_ == WebAuthFlow::SILENT) |
144 delegate_->OnAuthFlowFailure(WebAuthFlow::INTERACTION_REQUIRED); | 144 delegate_->OnAuthFlowFailure(WebAuthFlow::INTERACTION_REQUIRED); |
145 } | 145 } |
146 | 146 |
147 void WebAuthFlow::Observe(int type, | 147 void WebAuthFlow::Observe(int type, |
148 const content::NotificationSource& source, | 148 const content::NotificationSource& source, |
149 const content::NotificationDetails& details) { | 149 const content::NotificationDetails& details) { |
150 DCHECK(shell_window_); | 150 DCHECK(app_window_); |
151 | 151 |
152 if (!delegate_) | 152 if (!delegate_) |
153 return; | 153 return; |
154 | 154 |
155 if (!embedded_window_created_) { | 155 if (!embedded_window_created_) { |
156 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED); | 156 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED); |
157 | 157 |
158 RenderViewHost* render_view( | 158 RenderViewHost* render_view( |
159 content::Details<RenderViewHost>(details).ptr()); | 159 content::Details<RenderViewHost>(details).ptr()); |
160 WebContents* web_contents = WebContents::FromRenderViewHost(render_view); | 160 WebContents* web_contents = WebContents::FromRenderViewHost(render_view); |
161 | 161 |
162 if (web_contents && | 162 if (web_contents && |
163 (web_contents->GetEmbedderWebContents() == | 163 (web_contents->GetEmbedderWebContents() == |
164 WebContentsObserver::web_contents())) { | 164 WebContentsObserver::web_contents())) { |
165 // Switch from watching the shell window to the guest inside it. | 165 // Switch from watching the app window to the guest inside it. |
166 embedded_window_created_ = true; | 166 embedded_window_created_ = true; |
167 WebContentsObserver::Observe(web_contents); | 167 WebContentsObserver::Observe(web_contents); |
168 | 168 |
169 registrar_.RemoveAll(); | 169 registrar_.RemoveAll(); |
170 registrar_.Add(this, | 170 registrar_.Add(this, |
171 content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, | 171 content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, |
172 content::Source<WebContents>(web_contents)); | 172 content::Source<WebContents>(web_contents)); |
173 registrar_.Add(this, | 173 registrar_.Add(this, |
174 content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, | 174 content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, |
175 content::Source<WebContents>(web_contents)); | 175 content::Source<WebContents>(web_contents)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 } | 237 } |
238 | 238 |
239 void WebAuthFlow::DidNavigateMainFrame( | 239 void WebAuthFlow::DidNavigateMainFrame( |
240 const content::LoadCommittedDetails& details, | 240 const content::LoadCommittedDetails& details, |
241 const content::FrameNavigateParams& params) { | 241 const content::FrameNavigateParams& params) { |
242 if (delegate_ && details.http_status_code >= 400) | 242 if (delegate_ && details.http_status_code >= 400) |
243 delegate_->OnAuthFlowFailure(LOAD_FAILED); | 243 delegate_->OnAuthFlowFailure(LOAD_FAILED); |
244 } | 244 } |
245 | 245 |
246 } // namespace extensions | 246 } // namespace extensions |
OLD | NEW |