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/webstore_inline_installer.h" | 5 #include "chrome/browser/extensions/webstore_inline_installer.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "chrome/browser/browser_process.h" | |
13 #include "chrome/browser/extensions/webstore_data_fetcher.h" | 12 #include "chrome/browser/extensions/webstore_data_fetcher.h" |
14 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager
.h" | |
16 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | |
17 #include "chrome/browser/ui/browser_finder.h" | 14 #include "chrome/browser/ui/browser_finder.h" |
18 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" | 15 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" |
19 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
20 #include "components/prefs/pref_service.h" | 17 #include "components/prefs/pref_service.h" |
21 #include "content/public/browser/navigation_entry.h" | 18 #include "content/public/browser/navigation_entry.h" |
22 #include "content/public/browser/navigation_handle.h" | 19 #include "content/public/browser/navigation_handle.h" |
23 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
24 | 21 |
25 using content::WebContents; | 22 using content::WebContents; |
26 using safe_browsing::SafeBrowsingNavigationObserverManager; | |
27 using safe_browsing::ReferrerChain; | |
28 | |
29 namespace { | |
30 | |
31 // The number of user gestures to trace back for CWS pings. | |
32 const int kExtensionReferrerUserGestureLimit = 2; | |
33 } | |
34 | 23 |
35 namespace extensions { | 24 namespace extensions { |
36 | 25 |
37 const char kInvalidWebstoreResponseError[] = | 26 const char kInvalidWebstoreResponseError[] = |
38 "Invalid Chrome Web Store response."; | 27 "Invalid Chrome Web Store response."; |
39 const char kNoVerifiedSitesError[] = | 28 const char kNoVerifiedSitesError[] = |
40 "Inline installs can only be initiated for Chrome Web Store items that " | 29 "Inline installs can only be initiated for Chrome Web Store items that " |
41 "have one or more verified sites."; | 30 "have one or more verified sites."; |
42 const char kNotFromVerifiedSitesError[] = | 31 const char kNotFromVerifiedSitesError[] = |
43 "Installs can only be initiated by one of the Chrome Web Store item's " | 32 "Installs can only be initiated by one of the Chrome Web Store item's " |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } | 96 } |
108 } | 97 } |
109 if (!requestor_is_ok) { | 98 if (!requestor_is_ok) { |
110 *error = kNotFromVerifiedSitesError; | 99 *error = kNotFromVerifiedSitesError; |
111 return false; | 100 return false; |
112 } | 101 } |
113 *error = ""; | 102 *error = ""; |
114 return true; | 103 return true; |
115 } | 104 } |
116 | 105 |
117 bool WebstoreInlineInstaller::SafeBrowsingNavigationEventsEnabled() const { | |
118 return SafeBrowsingNavigationObserverManager::IsEnabledAndReady(profile()); | |
119 } | |
120 | |
121 std::string WebstoreInlineInstaller::GetJsonPostData() { | 106 std::string WebstoreInlineInstaller::GetJsonPostData() { |
122 // web_contents() might return null during tab destruction. This object would | 107 // web_contents() might return null during tab destruction. This object would |
123 // also be destroyed shortly thereafter but check to be on the safe side. | 108 // also be destroyed shortly thereafter but check to be on the safe side. |
124 if (!web_contents()) | 109 if (!web_contents()) |
125 return std::string(); | 110 return std::string(); |
126 | 111 |
127 // Report extra data only when SafeBrowsing is enabled for the current | 112 // Report extra data only when SafeBrowsing is enabled for the current |
128 // profile. | 113 // profile. |
129 if (!profile()->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) | 114 if (!profile()->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) |
130 return std::string(); | 115 return std::string(); |
131 | 116 |
132 auto redirect_chain = base::MakeUnique<base::ListValue>(); | 117 content::NavigationController& navigation_controller = |
| 118 web_contents()->GetController(); |
| 119 content::NavigationEntry* navigation_entry = |
| 120 navigation_controller.GetLastCommittedEntry(); |
133 | 121 |
134 if (SafeBrowsingNavigationEventsEnabled()) { | 122 if (navigation_entry) { |
135 // If we have it, use the new referrer checker. | 123 const std::vector<GURL>& redirect_urls = |
136 safe_browsing::SafeBrowsingService* safe_browsing_service = | 124 navigation_entry->GetRedirectChain(); |
137 g_browser_process->safe_browsing_service(); | |
138 // May be null in some tests. | |
139 if (!safe_browsing_service) | |
140 return std::string(); | |
141 | 125 |
142 scoped_refptr<SafeBrowsingNavigationObserverManager> | 126 if (!redirect_urls.empty()) { |
143 navigation_observer_manager = | 127 base::DictionaryValue dictionary; |
144 safe_browsing_service->navigation_observer_manager(); | 128 dictionary.SetString("id", id()); |
145 // This may be null if the navigation observer manager feature is | 129 dictionary.SetString("referrer", requestor_url_.spec()); |
146 // disabled by experiment. | 130 std::unique_ptr<base::ListValue> redirect_chain = |
147 if (!navigation_observer_manager) | 131 base::MakeUnique<base::ListValue>(); |
148 return std::string(); | |
149 | |
150 ReferrerChain referrer_chain; | |
151 SafeBrowsingNavigationObserverManager::AttributionResult result = | |
152 navigation_observer_manager->IdentifyReferrerChainByWebContents( | |
153 web_contents(), kExtensionReferrerUserGestureLimit, | |
154 &referrer_chain); | |
155 if (result != | |
156 SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND) { | |
157 // For now the CWS post data is JSON encoded. Consider moving it to a | |
158 // proto. | |
159 for (const auto& referrer_chain_entry : referrer_chain) { | |
160 // Referrer chain entries are a list of URLs in reverse chronological | |
161 // order, so the final URL is the last thing in the list and the initial | |
162 // landing page is the first thing in the list. | |
163 // Furthermore each entry may contain a series of server redirects | |
164 // stored in the same order. | |
165 redirect_chain->AppendString(referrer_chain_entry.url()); | |
166 for (const auto& server_side_redirect : | |
167 referrer_chain_entry.server_redirect_chain()) { | |
168 redirect_chain->AppendString(server_side_redirect.url()); | |
169 } | |
170 } | |
171 } | |
172 } else { | |
173 content::NavigationController& navigation_controller = | |
174 web_contents()->GetController(); | |
175 content::NavigationEntry* navigation_entry = | |
176 navigation_controller.GetLastCommittedEntry(); | |
177 if (navigation_entry) { | |
178 const std::vector<GURL>& redirect_urls = | |
179 navigation_entry->GetRedirectChain(); | |
180 for (const GURL& url : redirect_urls) { | 132 for (const GURL& url : redirect_urls) { |
181 redirect_chain->AppendString(url.spec()); | 133 redirect_chain->AppendString(url.spec()); |
182 } | 134 } |
| 135 dictionary.Set("redirect_chain", std::move(redirect_chain)); |
| 136 |
| 137 std::string json; |
| 138 base::JSONWriter::Write(dictionary, &json); |
| 139 return json; |
183 } | 140 } |
184 } | 141 } |
185 | 142 |
186 if (!redirect_chain->empty()) { | |
187 base::DictionaryValue dictionary; | |
188 dictionary.SetString("id", id()); | |
189 dictionary.SetString("referrer", requestor_url_.spec()); | |
190 dictionary.Set("redirect_chain", std::move(redirect_chain)); | |
191 | |
192 std::string json; | |
193 base::JSONWriter::Write(dictionary, &json); | |
194 return json; | |
195 } | |
196 | |
197 return std::string(); | 143 return std::string(); |
198 } | 144 } |
199 | 145 |
200 bool WebstoreInlineInstaller::CheckRequestorAlive() const { | 146 bool WebstoreInlineInstaller::CheckRequestorAlive() const { |
201 // The frame or tab may have gone away - cancel installation in that case. | 147 // The frame or tab may have gone away - cancel installation in that case. |
202 return host_ != nullptr && web_contents() != nullptr && | 148 return host_ != nullptr && web_contents() != nullptr && |
203 chrome::FindBrowserWithWebContents(web_contents()) != nullptr; | 149 chrome::FindBrowserWithWebContents(web_contents()) != nullptr; |
204 } | 150 } |
205 | 151 |
206 const GURL& WebstoreInlineInstaller::GetRequestorURL() const { | 152 const GURL& WebstoreInlineInstaller::GetRequestorURL() const { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 DLOG(WARNING) << "Could not parse " << verified_site_pattern_spec << | 295 DLOG(WARNING) << "Could not parse " << verified_site_pattern_spec << |
350 " as URL pattern " << parse_result; | 296 " as URL pattern " << parse_result; |
351 return false; | 297 return false; |
352 } | 298 } |
353 verified_site_pattern.SetScheme("*"); | 299 verified_site_pattern.SetScheme("*"); |
354 | 300 |
355 return verified_site_pattern.MatchesURL(requestor_url); | 301 return verified_site_pattern.MatchesURL(requestor_url); |
356 } | 302 } |
357 | 303 |
358 } // namespace extensions | 304 } // namespace extensions |
OLD | NEW |