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

Side by Side Diff: chrome/common/extensions/manifest_handlers/automation.cc

Issue 377553003: Create a ManifestPermission implementation for Automation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: More review comments Created 6 years, 5 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/common/extensions/manifest_handlers/automation.h" 5 #include "chrome/common/extensions/manifest_handlers/automation.h"
6 6
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/common/extensions/api/manifest_types.h" 8 #include "chrome/common/extensions/api/manifest_types.h"
10 #include "extensions/common/error_utils.h" 9 #include "extensions/common/error_utils.h"
10 #include "extensions/common/extensions_client.h"
11 #include "extensions/common/manifest_constants.h" 11 #include "extensions/common/manifest_constants.h"
12 #include "extensions/common/permissions/api_permission_set.h" 12 #include "extensions/common/permissions/api_permission_set.h"
13 #include "extensions/common/permissions/manifest_permission.h"
14 #include "extensions/common/permissions/permission_message.h"
15 #include "extensions/common/permissions/permission_message_util.h"
13 #include "extensions/common/permissions/permissions_data.h" 16 #include "extensions/common/permissions/permissions_data.h"
14 #include "extensions/common/url_pattern.h" 17 #include "extensions/common/url_pattern.h"
18 #include "grit/generated_resources.h"
19 #include "ipc/ipc_message.h"
20 #include "ipc/ipc_message_utils.h"
21 #include "ui/base/l10n/l10n_util.h"
15 22
16 namespace extensions { 23 namespace extensions {
17 24
18 namespace automation_errors { 25 namespace automation_errors {
19 const char kErrorDesktopTrueInteractFalse[] = 26 const char kErrorDesktopTrueInteractFalse[] =
20 "Cannot specify interactive=false if desktop=true is specified; " 27 "Cannot specify interactive=false if desktop=true is specified; "
21 "interactive=false will be ignored."; 28 "interactive=false will be ignored.";
22 const char kErrorDesktopTrueMatchesSpecified[] = 29 const char kErrorDesktopTrueMatchesSpecified[] =
23 "Cannot specify matches for Automation if desktop=true is specified; " 30 "Cannot specify matches for Automation if desktop=true is specified; "
24 "matches will be ignored."; 31 "matches will be ignored.";
25 const char kErrorInvalidMatch[] = "Invalid match pattern '*': *"; 32 const char kErrorInvalidMatch[] = "Invalid match pattern '*': *";
26 const char kErrorNoMatchesProvided[] = "No valid match patterns provided."; 33 const char kErrorNoMatchesProvided[] = "No valid match patterns provided.";
27 } 34 }
28 35
29 namespace errors = manifest_errors; 36 namespace errors = manifest_errors;
30 namespace keys = extensions::manifest_keys; 37 namespace keys = extensions::manifest_keys;
31 using api::manifest_types::Automation; 38 using api::manifest_types::Automation;
32 39
40 class AutomationManifestPermission : public ManifestPermission {
41 public:
42 explicit AutomationManifestPermission(
43 scoped_ptr<const AutomationInfo> automation_info)
44 : automation_info_(automation_info.Pass()) {}
45
46 // extensions::ManifestPermission overrides.
47 virtual std::string name() const OVERRIDE;
48
Devlin 2014/07/22 17:36:02 nit: we can take out these newlines between all th
49 virtual std::string id() const OVERRIDE;
50
51 virtual bool HasMessages() const OVERRIDE;
52
53 virtual PermissionMessages GetMessages() const OVERRIDE;
54
55 virtual bool FromValue(const base::Value* value) OVERRIDE;
56
57 virtual scoped_ptr<base::Value> ToValue() const OVERRIDE;
58
59 virtual ManifestPermission* Diff(
60 const ManifestPermission* rhs) const OVERRIDE;
61
62 virtual ManifestPermission* Union(
63 const ManifestPermission* rhs) const OVERRIDE;
64
65 virtual ManifestPermission* Intersect(
66 const ManifestPermission* rhs) const OVERRIDE;
67
68 private:
69 scoped_ptr<const AutomationInfo> automation_info_;
70 };
71
72 std::string AutomationManifestPermission::name() const {
73 return keys::kAutomation;
74 }
75
76 std::string AutomationManifestPermission::id() const {
77 return keys::kAutomation;
78 }
79
80 bool AutomationManifestPermission::HasMessages() const {
81 return GetMessages().size() > 0;
82 }
83
84 PermissionMessages AutomationManifestPermission::GetMessages() const {
85 PermissionMessages messages;
86 if (automation_info_->desktop) {
87 messages.push_back(PermissionMessage(
88 PermissionMessage::kFullAccess,
89 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS)));
90 } else if (automation_info_->matches.MatchesAllURLs()) {
91 messages.push_back(PermissionMessage(
92 PermissionMessage::kHostsAll,
93 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
94 } else {
95 URLPatternSet regular_hosts;
96 std::set<PermissionMessage> message_set;
97 ExtensionsClient::Get()->FilterHostPermissions(
98 automation_info_->matches, &regular_hosts, &message_set);
99 messages.insert(messages.end(), message_set.begin(), message_set.end());
100
101 std::set<std::string> hosts =
102 permission_message_util::GetDistinctHosts(regular_hosts, true, true);
103 if (!hosts.empty())
104 messages.push_back(permission_message_util::CreateFromHostList(hosts));
105 }
106
107 return messages;
108 }
109
110 bool AutomationManifestPermission::FromValue(const base::Value* value) {
111 base::string16 error;
112 automation_info_.reset(AutomationInfo::FromValue(*value,
113 NULL /* install_warnings */,
114 &error).release());
115 return error.empty();
116 }
117
118 scoped_ptr<base::Value> AutomationManifestPermission::ToValue() const {
119 return AutomationInfo::ToValue(*automation_info_).Pass();
120 }
121
122 ManifestPermission* AutomationManifestPermission::Diff(
123 const ManifestPermission* rhs) const {
124 const AutomationManifestPermission* other =
125 static_cast<const AutomationManifestPermission*>(rhs);
126
127 bool desktop = automation_info_->desktop && !other->automation_info_->desktop;
128 bool interact =
129 automation_info_->interact && !other->automation_info_->interact;
130 URLPatternSet matches;
131 URLPatternSet::CreateDifference(
132 automation_info_->matches, other->automation_info_->matches, &matches);
133 return new AutomationManifestPermission(
134 make_scoped_ptr(new const AutomationInfo(desktop, matches, interact)));
135 }
136
137 ManifestPermission* AutomationManifestPermission::Union(
138 const ManifestPermission* rhs) const {
139 const AutomationManifestPermission* other =
140 static_cast<const AutomationManifestPermission*>(rhs);
141
142 bool desktop = automation_info_->desktop || other->automation_info_->desktop;
143 bool interact =
144 automation_info_->interact || other->automation_info_->interact;
145 URLPatternSet matches;
146 URLPatternSet::CreateUnion(
147 automation_info_->matches, other->automation_info_->matches, &matches);
148 return new AutomationManifestPermission(
149 make_scoped_ptr(new const AutomationInfo(desktop, matches, interact)));
150 }
151
152 ManifestPermission* AutomationManifestPermission::Intersect(
153 const ManifestPermission* rhs) const {
154 const AutomationManifestPermission* other =
155 static_cast<const AutomationManifestPermission*>(rhs);
156
157 bool desktop = automation_info_->desktop && other->automation_info_->desktop;
158 bool interact =
159 automation_info_->interact && other->automation_info_->interact;
160 URLPatternSet matches;
161 URLPatternSet::CreateIntersection(
162 automation_info_->matches, other->automation_info_->matches, &matches);
163 return new AutomationManifestPermission(
164 make_scoped_ptr(new const AutomationInfo(desktop, matches, interact)));
165 }
166
33 AutomationHandler::AutomationHandler() { 167 AutomationHandler::AutomationHandler() {
34 } 168 }
35 169
36 AutomationHandler::~AutomationHandler() { 170 AutomationHandler::~AutomationHandler() {
37 } 171 }
38 172
39 bool AutomationHandler::Parse(Extension* extension, base::string16* error) { 173 bool AutomationHandler::Parse(Extension* extension, base::string16* error) {
40 const base::Value* automation = NULL; 174 const base::Value* automation = NULL;
41 CHECK(extension->manifest()->Get(keys::kAutomation, &automation)); 175 CHECK(extension->manifest()->Get(keys::kAutomation, &automation));
42 std::vector<InstallWarning> install_warnings; 176 std::vector<InstallWarning> install_warnings;
43 scoped_ptr<AutomationInfo> info = 177 scoped_ptr<AutomationInfo> info =
44 AutomationInfo::FromValue(*automation, &install_warnings, error); 178 AutomationInfo::FromValue(*automation, &install_warnings, error);
45 if (!error->empty()) 179 if (!error->empty())
46 return false; 180 return false;
47 181
48 extension->AddInstallWarnings(install_warnings); 182 extension->AddInstallWarnings(install_warnings);
49 183
50 if (!info) 184 if (!info)
51 return true; 185 return true;
52 186
53 extension->SetManifestData(keys::kAutomation, info.release()); 187 extension->SetManifestData(keys::kAutomation, info.release());
54 return true; 188 return true;
55 } 189 }
56 190
57 const std::vector<std::string> AutomationHandler::Keys() const { 191 const std::vector<std::string> AutomationHandler::Keys() const {
58 return SingleKey(keys::kAutomation); 192 return SingleKey(keys::kAutomation);
59 } 193 }
60 194
195 ManifestPermission* AutomationHandler::CreatePermission() {
196 return new AutomationManifestPermission(
197 make_scoped_ptr(new const AutomationInfo));
198 }
199
200 ManifestPermission* AutomationHandler::CreateInitialRequiredPermission(
201 const Extension* extension) {
202 const AutomationInfo* info = AutomationInfo::Get(extension);
203 if (info) {
204 return new AutomationManifestPermission(
205 make_scoped_ptr(new const AutomationInfo(
206 info->desktop, info->matches, info->interact)));
207 }
208 return NULL;
209 }
210
61 // static 211 // static
62 const AutomationInfo* AutomationInfo::Get(const Extension* extension) { 212 const AutomationInfo* AutomationInfo::Get(const Extension* extension) {
63 return static_cast<AutomationInfo*>( 213 return static_cast<AutomationInfo*>(
64 extension->GetManifestData(keys::kAutomation)); 214 extension->GetManifestData(keys::kAutomation));
65 } 215 }
66 216
67 // static 217 // static
68 scoped_ptr<AutomationInfo> AutomationInfo::FromValue( 218 scoped_ptr<AutomationInfo> AutomationInfo::FromValue(
69 const base::Value& value, 219 const base::Value& value,
70 std::vector<InstallWarning>* install_warnings, 220 std::vector<InstallWarning>* install_warnings,
71 base::string16* error) { 221 base::string16* error) {
72 scoped_ptr<Automation> automation = Automation::FromValue(value, error); 222 scoped_ptr<Automation> automation = Automation::FromValue(value, error);
73 if (!automation) 223 if (!automation)
74 return scoped_ptr<AutomationInfo>(); 224 return scoped_ptr<AutomationInfo>();
75 225
76 if (automation->as_boolean) { 226 if (automation->as_boolean) {
77 if (*automation->as_boolean) 227 if (*automation->as_boolean)
78 return make_scoped_ptr(new AutomationInfo()); 228 return make_scoped_ptr(new AutomationInfo());
79 return scoped_ptr<AutomationInfo>(); 229 return scoped_ptr<AutomationInfo>();
80 } 230 }
81 const Automation::Object& automation_object = *automation->as_object; 231 Automation::Object& automation_object = *automation->as_object;
Devlin 2014/07/22 17:36:02 nit: Can't this still be const?
aboxhall 2014/07/22 17:47:52 Literally no idea what happened there. Fixed.
82 232
83 bool desktop = false; 233 bool desktop = false;
84 bool interact = false; 234 bool interact = false;
85 if (automation_object.desktop && *automation_object.desktop) { 235 if (automation_object.desktop && *automation_object.desktop) {
86 desktop = true; 236 desktop = true;
87 interact = true; 237 interact = true;
88 if (automation_object.interact && !*automation_object.interact) { 238 if (automation_object.interact && !*automation_object.interact) {
89 // TODO(aboxhall): Do we want to allow this? 239 // TODO(aboxhall): Do we want to allow this?
90 install_warnings->push_back( 240 install_warnings->push_back(
91 InstallWarning(automation_errors::kErrorDesktopTrueInteractFalse)); 241 InstallWarning(automation_errors::kErrorDesktopTrueInteractFalse));
92 } 242 }
93 } else if (automation_object.interact && *automation_object.interact) { 243 } else if (automation_object.interact && *automation_object.interact) {
94 interact = true; 244 interact = true;
95 } 245 }
96 246
97 URLPatternSet matches; 247 URLPatternSet matches;
98 bool specified_matches = false; 248 bool specified_matches = false;
99 if (automation_object.matches) { 249 if (automation_object.matches) {
100 if (desktop) { 250 if (desktop) {
101 install_warnings->push_back( 251 install_warnings->push_back(
102 InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified)); 252 InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified));
103 } else { 253 } else {
104 specified_matches = true; 254 specified_matches = true;
255
105 for (std::vector<std::string>::iterator it = 256 for (std::vector<std::string>::iterator it =
106 automation_object.matches->begin(); 257 automation_object.matches->begin();
107 it != automation_object.matches->end(); 258 it != automation_object.matches->end();
108 ++it) { 259 ++it) {
109 // TODO(aboxhall): Refactor common logic from content_scripts_handler, 260 // TODO(aboxhall): Refactor common logic from content_scripts_handler,
110 // manifest_url_handler and user_script.cc into a single location and 261 // manifest_url_handler and user_script.cc into a single location and
111 // re-use here. 262 // re-use here.
112 URLPattern pattern(URLPattern::SCHEME_ALL & 263 URLPattern pattern(URLPattern::SCHEME_ALL &
113 ~URLPattern::SCHEME_CHROMEUI); 264 ~URLPattern::SCHEME_CHROMEUI);
114 URLPattern::ParseResult parse_result = pattern.Parse(*it); 265 URLPattern::ParseResult parse_result = pattern.Parse(*it);
266
115 if (parse_result != URLPattern::PARSE_SUCCESS) { 267 if (parse_result != URLPattern::PARSE_SUCCESS) {
116 install_warnings->push_back( 268 install_warnings->push_back(
117 InstallWarning(ErrorUtils::FormatErrorMessage( 269 InstallWarning(ErrorUtils::FormatErrorMessage(
118 automation_errors::kErrorInvalidMatch, 270 automation_errors::kErrorInvalidMatch,
119 *it, 271 *it,
120 URLPattern::GetParseResultString(parse_result)))); 272 URLPattern::GetParseResultString(parse_result))));
121 continue; 273 continue;
122 } 274 }
123 275
124 matches.AddPattern(pattern); 276 matches.AddPattern(pattern);
125 } 277 }
126 } 278 }
127 } 279 }
128 if (specified_matches && matches.is_empty()) 280 if (specified_matches && matches.is_empty()) {
129 install_warnings->push_back( 281 install_warnings->push_back(
130 InstallWarning(automation_errors::kErrorNoMatchesProvided)); 282 InstallWarning(automation_errors::kErrorNoMatchesProvided));
283 }
131 284
132 return make_scoped_ptr( 285 return make_scoped_ptr(new AutomationInfo(desktop, matches, interact));
133 new AutomationInfo(desktop, matches, interact, specified_matches));
134 } 286 }
135 287
136 AutomationInfo::AutomationInfo() 288 // static
137 : desktop(false), interact(false), specified_matches(false) { 289 scoped_ptr<base::Value> AutomationInfo::ToValue(const AutomationInfo& info) {
290 return AsManifestType(info)->ToValue().Pass();
138 } 291 }
292
293 // static
294 scoped_ptr<Automation> AutomationInfo::AsManifestType(
295 const AutomationInfo& info) {
296 scoped_ptr<Automation> automation(new Automation);
297 if (!info.desktop && !info.interact && info.matches.size() == 0) {
298 automation->as_boolean.reset(new bool(true));
299 return automation.Pass();
300 }
301
302 Automation::Object* as_object = new Automation::Object;
303 as_object->desktop.reset(new bool(info.desktop));
304 as_object->interact.reset(new bool(info.interact));
305 if (info.matches.size() > 0) {
306 as_object->matches.reset(info.matches.ToStringVector().release());
307 }
308 automation->as_object.reset(as_object);
309 return automation.Pass();
310 }
311
312 AutomationInfo::AutomationInfo() : desktop(false), interact(false) {
313 }
314
139 AutomationInfo::AutomationInfo(bool desktop, 315 AutomationInfo::AutomationInfo(bool desktop,
140 const URLPatternSet& matches, 316 const URLPatternSet matches,
141 bool interact, 317 bool interact)
142 bool specified_matches) 318 : desktop(desktop), matches(matches), interact(interact) {
143 : desktop(desktop),
144 matches(matches),
145 interact(interact),
146 specified_matches(specified_matches) {
147 } 319 }
148 320
149 AutomationInfo::~AutomationInfo() { 321 AutomationInfo::~AutomationInfo() {
150 } 322 }
151 323
152 } // namespace extensions 324 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698