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" |
12 #include "chrome/browser/extensions/webstore_data_fetcher.h" | 13 #include "chrome/browser/extensions/webstore_data_fetcher.h" |
13 #include "chrome/browser/profiles/profile.h" | 14 #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" |
14 #include "chrome/browser/ui/browser_finder.h" | 17 #include "chrome/browser/ui/browser_finder.h" |
15 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" | 18 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" |
16 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
17 #include "components/prefs/pref_service.h" | 20 #include "components/prefs/pref_service.h" |
18 #include "content/public/browser/navigation_entry.h" | 21 #include "content/public/browser/navigation_entry.h" |
19 #include "content/public/browser/navigation_handle.h" | 22 #include "content/public/browser/navigation_handle.h" |
20 #include "content/public/browser/web_contents.h" | 23 #include "content/public/browser/web_contents.h" |
21 | 24 |
22 using content::WebContents; | 25 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 } |
23 | 34 |
24 namespace extensions { | 35 namespace extensions { |
25 | 36 |
26 const char kInvalidWebstoreResponseError[] = | 37 const char kInvalidWebstoreResponseError[] = |
27 "Invalid Chrome Web Store response."; | 38 "Invalid Chrome Web Store response."; |
28 const char kNoVerifiedSitesError[] = | 39 const char kNoVerifiedSitesError[] = |
29 "Inline installs can only be initiated for Chrome Web Store items that " | 40 "Inline installs can only be initiated for Chrome Web Store items that " |
30 "have one or more verified sites."; | 41 "have one or more verified sites."; |
31 const char kNotFromVerifiedSitesError[] = | 42 const char kNotFromVerifiedSitesError[] = |
32 "Installs can only be initiated by one of the Chrome Web Store item's " | 43 "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... |
96 } | 107 } |
97 } | 108 } |
98 if (!requestor_is_ok) { | 109 if (!requestor_is_ok) { |
99 *error = kNotFromVerifiedSitesError; | 110 *error = kNotFromVerifiedSitesError; |
100 return false; | 111 return false; |
101 } | 112 } |
102 *error = ""; | 113 *error = ""; |
103 return true; | 114 return true; |
104 } | 115 } |
105 | 116 |
| 117 bool WebstoreInlineInstaller::SafeBrowsingNavigationEventsEnabled() const { |
| 118 return SafeBrowsingNavigationObserverManager::IsEnabledAndReady(profile()); |
| 119 } |
| 120 |
106 std::string WebstoreInlineInstaller::GetJsonPostData() { | 121 std::string WebstoreInlineInstaller::GetJsonPostData() { |
107 // web_contents() might return null during tab destruction. This object would | 122 // web_contents() might return null during tab destruction. This object would |
108 // also be destroyed shortly thereafter but check to be on the safe side. | 123 // also be destroyed shortly thereafter but check to be on the safe side. |
109 if (!web_contents()) | 124 if (!web_contents()) |
110 return std::string(); | 125 return std::string(); |
111 | 126 |
112 // Report extra data only when SafeBrowsing is enabled for the current | 127 // Report extra data only when SafeBrowsing is enabled for the current |
113 // profile. | 128 // profile. |
114 if (!profile()->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) | 129 if (!profile()->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) |
115 return std::string(); | 130 return std::string(); |
116 | 131 |
117 content::NavigationController& navigation_controller = | 132 auto redirect_chain = base::MakeUnique<base::ListValue>(); |
118 web_contents()->GetController(); | |
119 content::NavigationEntry* navigation_entry = | |
120 navigation_controller.GetLastCommittedEntry(); | |
121 | 133 |
122 if (navigation_entry) { | 134 if (SafeBrowsingNavigationEventsEnabled()) { |
123 const std::vector<GURL>& redirect_urls = | 135 // If we have it, use the new referrer checker. |
124 navigation_entry->GetRedirectChain(); | 136 safe_browsing::SafeBrowsingService* safe_browsing_service = |
| 137 g_browser_process->safe_browsing_service(); |
| 138 // May be null in some tests. |
| 139 if (!safe_browsing_service) |
| 140 return std::string(); |
125 | 141 |
126 if (!redirect_urls.empty()) { | 142 scoped_refptr<SafeBrowsingNavigationObserverManager> |
127 base::DictionaryValue dictionary; | 143 navigation_observer_manager = |
128 dictionary.SetString("id", id()); | 144 safe_browsing_service->navigation_observer_manager(); |
129 dictionary.SetString("referrer", requestor_url_.spec()); | 145 // This may be null if the navigation observer manager feature is |
130 std::unique_ptr<base::ListValue> redirect_chain = | 146 // disabled by experiment. |
131 base::MakeUnique<base::ListValue>(); | 147 if (!navigation_observer_manager) |
| 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(); |
132 for (const GURL& url : redirect_urls) { | 180 for (const GURL& url : redirect_urls) { |
133 redirect_chain->AppendString(url.spec()); | 181 redirect_chain->AppendString(url.spec()); |
134 } | 182 } |
135 dictionary.Set("redirect_chain", std::move(redirect_chain)); | 183 } |
| 184 } |
136 | 185 |
137 std::string json; | 186 if (!redirect_chain->empty()) { |
138 base::JSONWriter::Write(dictionary, &json); | 187 base::DictionaryValue dictionary; |
139 return json; | 188 dictionary.SetString("id", id()); |
140 } | 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; |
141 } | 195 } |
142 | 196 |
143 return std::string(); | 197 return std::string(); |
144 } | 198 } |
145 | 199 |
146 bool WebstoreInlineInstaller::CheckRequestorAlive() const { | 200 bool WebstoreInlineInstaller::CheckRequestorAlive() const { |
147 // The frame or tab may have gone away - cancel installation in that case. | 201 // The frame or tab may have gone away - cancel installation in that case. |
148 return host_ != nullptr && web_contents() != nullptr && | 202 return host_ != nullptr && web_contents() != nullptr && |
149 chrome::FindBrowserWithWebContents(web_contents()) != nullptr; | 203 chrome::FindBrowserWithWebContents(web_contents()) != nullptr; |
150 } | 204 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 DLOG(WARNING) << "Could not parse " << verified_site_pattern_spec << | 349 DLOG(WARNING) << "Could not parse " << verified_site_pattern_spec << |
296 " as URL pattern " << parse_result; | 350 " as URL pattern " << parse_result; |
297 return false; | 351 return false; |
298 } | 352 } |
299 verified_site_pattern.SetScheme("*"); | 353 verified_site_pattern.SetScheme("*"); |
300 | 354 |
301 return verified_site_pattern.MatchesURL(requestor_url); | 355 return verified_site_pattern.MatchesURL(requestor_url); |
302 } | 356 } |
303 | 357 |
304 } // namespace extensions | 358 } // namespace extensions |
OLD | NEW |