#include "chrome/common/extensions/manifest_handlers/automation.h"
-#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/extensions/api/manifest_types.h"
+#include "chrome/grit/generated_resources.h"
#include "extensions/common/error_utils.h"
+#include "extensions/common/extensions_client.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/api_permission_set.h"
+#include "extensions/common/permissions/manifest_permission.h"
+#include "extensions/common/permissions/permission_message.h"
+#include "extensions/common/permissions/permission_message_util.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/url_pattern.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_utils.h"
+#include "ui/base/l10n/l10n_util.h"
namespace extensions {
namespace keys = extensions::manifest_keys;
using api::manifest_types::Automation;
+class AutomationManifestPermission : public ManifestPermission {
+ public:
+ explicit AutomationManifestPermission(
+ scoped_ptr<const AutomationInfo> automation_info)
+ : automation_info_(automation_info.Pass()) {}
+
+ // extensions::ManifestPermission overrides.
+ virtual std::string name() const OVERRIDE;
+
+ virtual std::string id() const OVERRIDE;
+
+ virtual bool HasMessages() const OVERRIDE;
+
+ virtual PermissionMessages GetMessages() const OVERRIDE;
+
+ virtual bool FromValue(const base::Value* value) OVERRIDE;
+
+ virtual scoped_ptr<base::Value> ToValue() const OVERRIDE;
+
+ virtual ManifestPermission* Diff(
+ const ManifestPermission* rhs) const OVERRIDE;
+
+ virtual ManifestPermission* Union(
+ const ManifestPermission* rhs) const OVERRIDE;
+
+ virtual ManifestPermission* Intersect(
+ const ManifestPermission* rhs) const OVERRIDE;
+
+ private:
+ scoped_ptr<const AutomationInfo> automation_info_;
+};
+
+std::string AutomationManifestPermission::name() const {
+ return keys::kAutomation;
+}
+
+std::string AutomationManifestPermission::id() const {
+ return keys::kAutomation;
+}
+
+bool AutomationManifestPermission::HasMessages() const {
+ return GetMessages().size() > 0;
+}
+
+PermissionMessages AutomationManifestPermission::GetMessages() const {
+ PermissionMessages messages;
+ if (automation_info_->desktop) {
+ messages.push_back(PermissionMessage(
+ PermissionMessage::kFullAccess,
+ l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS)));
+ } else if (automation_info_->matches.MatchesAllURLs()) {
+ messages.push_back(PermissionMessage(
+ PermissionMessage::kHostsAll,
+ l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
+ } else {
+ URLPatternSet regular_hosts;
+ std::set<PermissionMessage> message_set;
+ ExtensionsClient::Get()->FilterHostPermissions(
+ automation_info_->matches, ®ular_hosts, &message_set);
+ messages.insert(messages.end(), message_set.begin(), message_set.end());
+
+ std::set<std::string> hosts =
+ permission_message_util::GetDistinctHosts(regular_hosts, true, true);
+ if (!hosts.empty())
+ messages.push_back(permission_message_util::CreateFromHostList(hosts));
+ }
+
+ return messages;
+}
+
+bool AutomationManifestPermission::FromValue(const base::Value* value) {
+ base::string16 error;
+ automation_info_.reset(AutomationInfo::FromValue(*value,
+ NULL /* install_warnings */,
+ &error).release());
+ return error.empty();
+}
+
+scoped_ptr<base::Value> AutomationManifestPermission::ToValue() const {
+ return AutomationInfo::ToValue(*automation_info_).Pass();
+}
+
+ManifestPermission* AutomationManifestPermission::Diff(
+ const ManifestPermission* rhs) const {
+ const AutomationManifestPermission* other =
+ static_cast<const AutomationManifestPermission*>(rhs);
+
+ bool desktop = automation_info_->desktop && !other->automation_info_->desktop;
+ bool interact =
+ automation_info_->interact && !other->automation_info_->interact;
+ URLPatternSet matches;
+ URLPatternSet::CreateDifference(
+ automation_info_->matches, other->automation_info_->matches, &matches);
+ return new AutomationManifestPermission(
+ make_scoped_ptr(new const AutomationInfo(desktop, matches, interact)));
+}
+
+ManifestPermission* AutomationManifestPermission::Union(
+ const ManifestPermission* rhs) const {
+ const AutomationManifestPermission* other =
+ static_cast<const AutomationManifestPermission*>(rhs);
+
+ bool desktop = automation_info_->desktop || other->automation_info_->desktop;
+ bool interact =
+ automation_info_->interact || other->automation_info_->interact;
+ URLPatternSet matches;
+ URLPatternSet::CreateUnion(
+ automation_info_->matches, other->automation_info_->matches, &matches);
+ return new AutomationManifestPermission(
+ make_scoped_ptr(new const AutomationInfo(desktop, matches, interact)));
+}
+
+ManifestPermission* AutomationManifestPermission::Intersect(
+ const ManifestPermission* rhs) const {
+ const AutomationManifestPermission* other =
+ static_cast<const AutomationManifestPermission*>(rhs);
+
+ bool desktop = automation_info_->desktop && other->automation_info_->desktop;
+ bool interact =
+ automation_info_->interact && other->automation_info_->interact;
+ URLPatternSet matches;
+ URLPatternSet::CreateIntersection(
+ automation_info_->matches, other->automation_info_->matches, &matches);
+ return new AutomationManifestPermission(
+ make_scoped_ptr(new const AutomationInfo(desktop, matches, interact)));
+}
+
AutomationHandler::AutomationHandler() {
}
return SingleKey(keys::kAutomation);
}
+ManifestPermission* AutomationHandler::CreatePermission() {
+ return new AutomationManifestPermission(
+ make_scoped_ptr(new const AutomationInfo));
+}
+
+ManifestPermission* AutomationHandler::CreateInitialRequiredPermission(
+ const Extension* extension) {
+ const AutomationInfo* info = AutomationInfo::Get(extension);
+ if (info) {
+ return new AutomationManifestPermission(
+ make_scoped_ptr(new const AutomationInfo(
+ info->desktop, info->matches, info->interact)));
+ }
+ return NULL;
+}
+
// static
const AutomationInfo* AutomationInfo::Get(const Extension* extension) {
return static_cast<AutomationInfo*>(
InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified));
} else {
specified_matches = true;
+
for (std::vector<std::string>::iterator it =
automation_object.matches->begin();
it != automation_object.matches->end();
URLPattern pattern(URLPattern::SCHEME_ALL &
~URLPattern::SCHEME_CHROMEUI);
URLPattern::ParseResult parse_result = pattern.Parse(*it);
+
if (parse_result != URLPattern::PARSE_SUCCESS) {
install_warnings->push_back(
InstallWarning(ErrorUtils::FormatErrorMessage(
}
}
}
- if (specified_matches && matches.is_empty())
+ if (specified_matches && matches.is_empty()) {
install_warnings->push_back(
InstallWarning(automation_errors::kErrorNoMatchesProvided));
+ }
+
+ return make_scoped_ptr(new AutomationInfo(desktop, matches, interact));
+}
+
+// static
+scoped_ptr<base::Value> AutomationInfo::ToValue(const AutomationInfo& info) {
+ return AsManifestType(info)->ToValue().Pass();
+}
- return make_scoped_ptr(
- new AutomationInfo(desktop, matches, interact, specified_matches));
+// static
+scoped_ptr<Automation> AutomationInfo::AsManifestType(
+ const AutomationInfo& info) {
+ scoped_ptr<Automation> automation(new Automation);
+ if (!info.desktop && !info.interact && info.matches.size() == 0) {
+ automation->as_boolean.reset(new bool(true));
+ return automation.Pass();
+ }
+
+ Automation::Object* as_object = new Automation::Object;
+ as_object->desktop.reset(new bool(info.desktop));
+ as_object->interact.reset(new bool(info.interact));
+ if (info.matches.size() > 0) {
+ as_object->matches.reset(info.matches.ToStringVector().release());
+ }
+ automation->as_object.reset(as_object);
+ return automation.Pass();
}
-AutomationInfo::AutomationInfo()
- : desktop(false), interact(false), specified_matches(false) {
+AutomationInfo::AutomationInfo() : desktop(false), interact(false) {
}
+
AutomationInfo::AutomationInfo(bool desktop,
- const URLPatternSet& matches,
- bool interact,
- bool specified_matches)
- : desktop(desktop),
- matches(matches),
- interact(interact),
- specified_matches(specified_matches) {
+ const URLPatternSet matches,
+ bool interact)
+ : desktop(desktop), matches(matches), interact(interact) {
}
AutomationInfo::~AutomationInfo() {