Remove unused field from extension_sorting.cc
[chromium-blink-merge.git] / chrome / browser / extensions / webstore_inline_installer.cc
blobabc53417cd863e510446a0aeda8ff5505f94160e
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.
5 #include "chrome/browser/extensions/webstore_inline_installer.h"
7 #include "base/strings/stringprintf.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "content/public/browser/web_contents.h"
11 using content::WebContents;
13 namespace extensions {
15 const char kVerifiedSiteKey[] = "verified_site";
16 const char kVerifiedSitesKey[] = "verified_sites";
17 const char kInlineInstallNotSupportedKey[] = "inline_install_not_supported";
18 const char kRedirectUrlKey[] = "redirect_url";
20 const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse";
21 const char kNoVerifiedSitesError[] =
22 "Inline installs can only be initiated for Chrome Web Store items that "
23 "have one or more verified sites";
24 const char kNotFromVerifiedSitesError[] =
25 "Installs can only be initiated by one of the Chrome Web Store item's "
26 "verified sites";
27 const char kInlineInstallSupportedError[] =
28 "Inline installation is not supported for this item. The user will be "
29 "redirected to the Chrome Web Store.";
31 WebstoreInlineInstaller::WebstoreInlineInstaller(
32 content::WebContents* web_contents,
33 const std::string& webstore_item_id,
34 const GURL& requestor_url,
35 const Callback& callback)
36 : WebstoreStandaloneInstaller(
37 webstore_item_id,
38 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
39 callback),
40 content::WebContentsObserver(web_contents),
41 requestor_url_(requestor_url) {
44 WebstoreInlineInstaller::~WebstoreInlineInstaller() {}
46 bool WebstoreInlineInstaller::CheckRequestorAlive() const {
47 // The tab may have gone away - cancel installation in that case.
48 return web_contents() != NULL;
51 const GURL& WebstoreInlineInstaller::GetRequestorURL() const {
52 return requestor_url_;
55 scoped_ptr<ExtensionInstallPrompt::Prompt>
56 WebstoreInlineInstaller::CreateInstallPrompt() const {
57 scoped_ptr<ExtensionInstallPrompt::Prompt> prompt(
58 new ExtensionInstallPrompt::Prompt(
59 ExtensionInstallPrompt::INLINE_INSTALL_PROMPT));
60 prompt->SetInlineInstallWebstoreData(localized_user_count(),
61 average_rating(),
62 rating_count());
63 return prompt.Pass();
66 bool WebstoreInlineInstaller::ShouldShowPostInstallUI() const {
67 return true;
70 bool WebstoreInlineInstaller::ShouldShowAppInstalledBubble() const {
71 return true;
74 WebContents* WebstoreInlineInstaller::GetWebContents() const {
75 return web_contents();
78 bool WebstoreInlineInstaller::CheckInlineInstallPermitted(
79 const base::DictionaryValue& webstore_data,
80 std::string* error) const {
81 // The store may not support inline installs for this item, in which case
82 // we open the store-provided redirect URL in a new tab and abort the
83 // installation process.
84 bool inline_install_not_supported = false;
85 if (webstore_data.HasKey(kInlineInstallNotSupportedKey)
86 && !webstore_data.GetBoolean(kInlineInstallNotSupportedKey,
87 &inline_install_not_supported)) {
88 *error = kInvalidWebstoreResponseError;
89 return false;
91 if (inline_install_not_supported) {
92 std::string redirect_url;
93 if (!webstore_data.GetString(kRedirectUrlKey, &redirect_url)) {
94 *error = kInvalidWebstoreResponseError;
95 return false;
97 web_contents()->OpenURL(
98 content::OpenURLParams(
99 GURL(redirect_url),
100 content::Referrer(web_contents()->GetURL(),
101 WebKit::WebReferrerPolicyDefault),
102 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_AUTO_BOOKMARK, false));
103 *error = kInlineInstallSupportedError;
104 return false;
107 *error = "";
108 return true;
111 bool WebstoreInlineInstaller::CheckRequestorPermitted(
112 const base::DictionaryValue& webstore_data,
113 std::string* error) const {
114 // Ensure that there is at least one verified site present.
115 const bool data_has_single_site = webstore_data.HasKey(kVerifiedSiteKey);
116 const bool data_has_site_list = webstore_data.HasKey(kVerifiedSitesKey);
117 if (!data_has_single_site && !data_has_site_list) {
118 *error = kNoVerifiedSitesError;
119 return false;
121 bool requestor_is_ok = false;
122 // Handle the deprecated single-site case.
123 if (!data_has_site_list) {
124 std::string verified_site;
125 if (!webstore_data.GetString(kVerifiedSiteKey, &verified_site)) {
126 *error = kInvalidWebstoreResponseError;
127 return false;
129 requestor_is_ok = IsRequestorURLInVerifiedSite(requestor_url_,
130 verified_site);
131 } else {
132 const base::ListValue* verified_sites = NULL;
133 if (!webstore_data.GetList(kVerifiedSitesKey, &verified_sites)) {
134 *error = kInvalidWebstoreResponseError;
135 return false;
137 for (base::ListValue::const_iterator it = verified_sites->begin();
138 it != verified_sites->end() && !requestor_is_ok; ++it) {
139 std::string verified_site;
140 if (!(*it)->GetAsString(&verified_site)) {
141 *error = kInvalidWebstoreResponseError;
142 return false;
144 if (IsRequestorURLInVerifiedSite(requestor_url_, verified_site)) {
145 requestor_is_ok = true;
149 if (!requestor_is_ok) {
150 *error = kNotFromVerifiedSitesError;
151 return false;
153 *error = "";
154 return true;
158 // Private implementation.
161 void WebstoreInlineInstaller::WebContentsDestroyed(
162 content::WebContents* web_contents) {
163 AbortInstall();
166 // static
167 bool WebstoreInlineInstaller::IsRequestorURLInVerifiedSite(
168 const GURL& requestor_url,
169 const std::string& verified_site) {
170 // Turn the verified site into a URL that can be parsed by URLPattern.
171 // |verified_site| must follow the format:
173 // [scheme://]host[:port][/path/specifier]
175 // If scheme is omitted, URLPattern will match against either an
176 // HTTP or HTTPS requestor. If scheme is specified, it must be either HTTP
177 // or HTTPS, and URLPattern will only match the scheme specified.
178 GURL verified_site_url(verified_site);
179 int valid_schemes = URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS;
180 if (!verified_site_url.is_valid() || !verified_site_url.IsStandard())
181 // If no scheme is specified, GURL will fail to parse the string correctly.
182 // It will either determine that the URL is invalid, or parse a
183 // host:port/path as scheme:host/path.
184 verified_site_url = GURL("http://" + verified_site);
185 else if (verified_site_url.SchemeIs("http"))
186 valid_schemes = URLPattern::SCHEME_HTTP;
187 else if (verified_site_url.SchemeIs("https"))
188 valid_schemes = URLPattern::SCHEME_HTTPS;
189 else
190 return false;
192 std::string port_spec =
193 verified_site_url.has_port() ? ":" + verified_site_url.port() : "";
194 std::string path_spec = verified_site_url.path() + "*";
195 std::string verified_site_pattern_spec =
196 base::StringPrintf(
197 "%s://*.%s%s%s",
198 verified_site_url.scheme().c_str(),
199 verified_site_url.host().c_str(),
200 port_spec.c_str(),
201 path_spec.c_str());
203 URLPattern verified_site_pattern(valid_schemes);
204 URLPattern::ParseResult parse_result =
205 verified_site_pattern.Parse(verified_site_pattern_spec);
206 if (parse_result != URLPattern::PARSE_SUCCESS) {
207 DLOG(WARNING) << "Could not parse " << verified_site_pattern_spec <<
208 " as URL pattern " << parse_result;
209 return false;
211 verified_site_pattern.SetScheme("*");
213 return verified_site_pattern.MatchesURL(requestor_url);
216 } // namespace extensions