Commit 6b15d66d authored by aboxhall@chromium.org's avatar aboxhall@chromium.org

Create a ManifestPermission implementation for Automation.

BUG=

Review URL: https://codereview.chromium.org/377553003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284761 0039d316-1c4b-4281-b951-d872f2087c98
parent c29eda4a
...@@ -96,7 +96,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, TestRendererAccessibilityEnabled) { ...@@ -96,7 +96,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, TestRendererAccessibilityEnabled) {
} }
#if defined(ADDRESS_SANITIZER) #if defined(ADDRESS_SANITIZER)
#define Maybe_SanityCheck DISABLED_SanityCheck #define Maybe_SanityCheck SanityCheck
#else #else
#define Maybe_SanityCheck SanityCheck #define Maybe_SanityCheck SanityCheck
#endif #endif
...@@ -112,7 +112,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, Unit) { ...@@ -112,7 +112,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, Unit) {
} }
// Test is failing on ASAN bots, crbug.com/379927 // Test is failing on ASAN bots, crbug.com/379927
IN_PROC_BROWSER_TEST_F(AutomationApiTest, DISABLED_GetTreeByTabId) { IN_PROC_BROWSER_TEST_F(AutomationApiTest, GetTreeByTabId) {
StartEmbeddedTestServer(); StartEmbeddedTestServer();
ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", "tab_id.html")) ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", "tab_id.html"))
<< message_; << message_;
...@@ -120,7 +120,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, DISABLED_GetTreeByTabId) { ...@@ -120,7 +120,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, DISABLED_GetTreeByTabId) {
#if defined(OS_LINUX) && defined(ADDRESS_SANITIZER) #if defined(OS_LINUX) && defined(ADDRESS_SANITIZER)
// Failing on Linux ASan bot: http://crbug.com/391279 // Failing on Linux ASan bot: http://crbug.com/391279
#define MAYBE_Events DISABLED_Events #define MAYBE_Events Events
#else #else
#define MAYBE_Events Events #define MAYBE_Events Events
#endif #endif
...@@ -133,7 +133,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, MAYBE_Events) { ...@@ -133,7 +133,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, MAYBE_Events) {
#if defined(OS_LINUX) && defined(ADDRESS_SANITIZER) #if defined(OS_LINUX) && defined(ADDRESS_SANITIZER)
// Timing out on linux ASan bot: http://crbug.com/385701 // Timing out on linux ASan bot: http://crbug.com/385701
#define MAYBE_Actions DISABLED_Actions #define MAYBE_Actions Actions
#else #else
#define MAYBE_Actions Actions #define MAYBE_Actions Actions
#endif #endif
...@@ -145,7 +145,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, MAYBE_Actions) { ...@@ -145,7 +145,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, MAYBE_Actions) {
} }
#if defined(ADDRESS_SANITIZER) #if defined(ADDRESS_SANITIZER)
#define Maybe_Location DISABLED_Location #define Maybe_Location Location
#else #else
#define Maybe_Location Location #define Maybe_Location Location
#endif #endif
...@@ -164,7 +164,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, TabsAutomationBooleanPermissions) { ...@@ -164,7 +164,7 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, TabsAutomationBooleanPermissions) {
// See crbug.com/384673 // See crbug.com/384673
#if defined(ADDRESS_SANITIZER) || defined(OS_CHROMEOS) || defined(OS_LINUX) #if defined(ADDRESS_SANITIZER) || defined(OS_CHROMEOS) || defined(OS_LINUX)
#define Maybe_TabsAutomationBooleanActions DISABLED_TabsAutomationBooleanActions #define Maybe_TabsAutomationBooleanActions TabsAutomationBooleanActions
#else #else
#define Maybe_TabsAutomationBooleanActions TabsAutomationBooleanActions #define Maybe_TabsAutomationBooleanActions TabsAutomationBooleanActions
#endif #endif
......
...@@ -4,14 +4,21 @@ ...@@ -4,14 +4,21 @@
#include "chrome/common/extensions/manifest_handlers/automation.h" #include "chrome/common/extensions/manifest_handlers/automation.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/common/extensions/api/manifest_types.h" #include "chrome/common/extensions/api/manifest_types.h"
#include "extensions/common/error_utils.h" #include "extensions/common/error_utils.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/api_permission_set.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/permissions/permissions_data.h"
#include "extensions/common/url_pattern.h" #include "extensions/common/url_pattern.h"
#include "grit/generated_resources.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_utils.h"
#include "ui/base/l10n/l10n_util.h"
namespace extensions { namespace extensions {
...@@ -30,6 +37,133 @@ namespace errors = manifest_errors; ...@@ -30,6 +37,133 @@ namespace errors = manifest_errors;
namespace keys = extensions::manifest_keys; namespace keys = extensions::manifest_keys;
using api::manifest_types::Automation; 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, &regular_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() { AutomationHandler::AutomationHandler() {
} }
...@@ -58,6 +192,22 @@ const std::vector<std::string> AutomationHandler::Keys() const { ...@@ -58,6 +192,22 @@ const std::vector<std::string> AutomationHandler::Keys() const {
return SingleKey(keys::kAutomation); 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 // static
const AutomationInfo* AutomationInfo::Get(const Extension* extension) { const AutomationInfo* AutomationInfo::Get(const Extension* extension) {
return static_cast<AutomationInfo*>( return static_cast<AutomationInfo*>(
...@@ -102,6 +252,7 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue( ...@@ -102,6 +252,7 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue(
InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified)); InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified));
} else { } else {
specified_matches = true; specified_matches = true;
for (std::vector<std::string>::iterator it = for (std::vector<std::string>::iterator it =
automation_object.matches->begin(); automation_object.matches->begin();
it != automation_object.matches->end(); it != automation_object.matches->end();
...@@ -112,6 +263,7 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue( ...@@ -112,6 +263,7 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue(
URLPattern pattern(URLPattern::SCHEME_ALL & URLPattern pattern(URLPattern::SCHEME_ALL &
~URLPattern::SCHEME_CHROMEUI); ~URLPattern::SCHEME_CHROMEUI);
URLPattern::ParseResult parse_result = pattern.Parse(*it); URLPattern::ParseResult parse_result = pattern.Parse(*it);
if (parse_result != URLPattern::PARSE_SUCCESS) { if (parse_result != URLPattern::PARSE_SUCCESS) {
install_warnings->push_back( install_warnings->push_back(
InstallWarning(ErrorUtils::FormatErrorMessage( InstallWarning(ErrorUtils::FormatErrorMessage(
...@@ -125,25 +277,45 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue( ...@@ -125,25 +277,45 @@ scoped_ptr<AutomationInfo> AutomationInfo::FromValue(
} }
} }
} }
if (specified_matches && matches.is_empty()) if (specified_matches && matches.is_empty()) {
install_warnings->push_back( install_warnings->push_back(
InstallWarning(automation_errors::kErrorNoMatchesProvided)); 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( // static
new AutomationInfo(desktop, matches, interact, specified_matches)); 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() AutomationInfo::AutomationInfo() : desktop(false), interact(false) {
: desktop(false), interact(false), specified_matches(false) {
} }
AutomationInfo::AutomationInfo(bool desktop, AutomationInfo::AutomationInfo(bool desktop,
const URLPatternSet& matches, const URLPatternSet matches,
bool interact, bool interact)
bool specified_matches) : desktop(desktop), matches(matches), interact(interact) {
: desktop(desktop),
matches(matches),
interact(interact),
specified_matches(specified_matches) {
} }
AutomationInfo::~AutomationInfo() { AutomationInfo::~AutomationInfo() {
......
...@@ -15,7 +15,14 @@ ...@@ -15,7 +15,14 @@
namespace extensions { namespace extensions {
namespace api {
namespace manifest_types {
struct Automation;
}
}
class URLPatternSet; class URLPatternSet;
class AutomationManifestPermission;
namespace automation_errors { namespace automation_errors {
extern const char kErrorInvalidMatchPattern[]; extern const char kErrorInvalidMatchPattern[];
...@@ -26,20 +33,6 @@ extern const char kErrorInvalidMatch[]; ...@@ -26,20 +33,6 @@ extern const char kErrorInvalidMatch[];
extern const char kErrorNoMatchesProvided[]; extern const char kErrorNoMatchesProvided[];
} }
// Parses the automation manifest entry.
class AutomationHandler : public ManifestHandler {
public:
AutomationHandler();
virtual ~AutomationHandler();
virtual bool Parse(Extension* extensions, base::string16* error) OVERRIDE;
private:
virtual const std::vector<std::string> Keys() const OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(AutomationHandler);
};
// The parsed form of the automation manifest entry. // The parsed form of the automation manifest entry.
struct AutomationInfo : public Extension::ManifestData { struct AutomationInfo : public Extension::ManifestData {
public: public:
...@@ -49,6 +42,7 @@ struct AutomationInfo : public Extension::ManifestData { ...@@ -49,6 +42,7 @@ struct AutomationInfo : public Extension::ManifestData {
std::vector<InstallWarning>* install_warnings, std::vector<InstallWarning>* install_warnings,
base::string16* error); base::string16* error);
static scoped_ptr<base::Value> ToValue(const AutomationInfo& info);
virtual ~AutomationInfo(); virtual ~AutomationInfo();
// true if the extension has requested 'desktop' permission. // true if the extension has requested 'desktop' permission.
...@@ -62,17 +56,34 @@ struct AutomationInfo : public Extension::ManifestData { ...@@ -62,17 +56,34 @@ struct AutomationInfo : public Extension::ManifestData {
// access (false) to the automation tree. // access (false) to the automation tree.
const bool interact; const bool interact;
// Whether any matches were specified (false if automation was specified as a
// boolean, or no matches key was provided.
const bool specified_matches;
private: private:
AutomationInfo(); AutomationInfo();
AutomationInfo(bool desktop, AutomationInfo(bool desktop, URLPatternSet matches, bool interact);
const URLPatternSet& matches,
bool interact, static scoped_ptr<api::manifest_types::Automation> AsManifestType(
bool specified_matches); const AutomationInfo& info);
DISALLOW_COPY_AND_ASSIGN(AutomationInfo); DISALLOW_COPY_AND_ASSIGN(AutomationInfo);
friend class AutomationManifestPermission;
friend class AutomationHandler;
};
// Parses the automation manifest entry.
class AutomationHandler : public ManifestHandler {
public:
AutomationHandler();
virtual ~AutomationHandler();
private:
// ManifestHandler implementation.
virtual bool Parse(Extension* extensions, base::string16* error) OVERRIDE;
virtual ManifestPermission* CreatePermission() OVERRIDE;
virtual ManifestPermission* CreateInitialRequiredPermission(
const Extension* extension) OVERRIDE;
virtual const std::vector<std::string> Keys() const OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(AutomationHandler);
}; };
} // namespace extensions } // namespace extensions
......
...@@ -7,7 +7,11 @@ ...@@ -7,7 +7,11 @@
#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h" #include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "extensions/common/error_utils.h" #include "extensions/common/error_utils.h"
#include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/permissions_data.h"
#include "grit/extensions_strings.h"
#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
namespace extensions { namespace extensions {
...@@ -30,6 +34,10 @@ TEST_F(AutomationManifestTest, AsBooleanFalse) { ...@@ -30,6 +34,10 @@ TEST_F(AutomationManifestTest, AsBooleanFalse) {
LoadAndExpectSuccess("automation_boolean_false.json"); LoadAndExpectSuccess("automation_boolean_false.json");
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
EXPECT_EQ(0u, warnings.size());
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_FALSE(info); ASSERT_FALSE(info);
} }
...@@ -39,12 +47,17 @@ TEST_F(AutomationManifestTest, AsBooleanTrue) { ...@@ -39,12 +47,17 @@ TEST_F(AutomationManifestTest, AsBooleanTrue) {
LoadAndExpectSuccess("automation_boolean_true.json"); LoadAndExpectSuccess("automation_boolean_true.json");
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ("Read and modify your data on www.google.com",
base::UTF16ToUTF8(warnings[0]));
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_FALSE(info->desktop); EXPECT_FALSE(info->desktop);
EXPECT_FALSE(info->interact); EXPECT_FALSE(info->interact);
EXPECT_FALSE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -53,12 +66,17 @@ TEST_F(AutomationManifestTest, InteractTrue) { ...@@ -53,12 +66,17 @@ TEST_F(AutomationManifestTest, InteractTrue) {
LoadAndExpectSuccess("automation_interact_true.json"); LoadAndExpectSuccess("automation_interact_true.json");
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ("Read and modify your data on www.google.com",
base::UTF16ToUTF8(warnings[0]));
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_FALSE(info->desktop); EXPECT_FALSE(info->desktop);
EXPECT_TRUE(info->interact); EXPECT_TRUE(info->interact);
EXPECT_FALSE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -72,12 +90,17 @@ TEST_F(AutomationManifestTest, Matches) { ...@@ -72,12 +90,17 @@ TEST_F(AutomationManifestTest, Matches) {
URLPattern::PARSE_ERROR_MISSING_SCHEME_SEPARATOR))); URLPattern::PARSE_ERROR_MISSING_SCHEME_SEPARATOR)));
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ("Read and modify your data on www.google.com and www.twitter.com",
base::UTF16ToUTF8(warnings[0]));
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_FALSE(info->desktop); EXPECT_FALSE(info->desktop);
EXPECT_FALSE(info->interact); EXPECT_FALSE(info->interact);
EXPECT_TRUE(info->specified_matches);
EXPECT_FALSE(info->matches.is_empty()); EXPECT_FALSE(info->matches.is_empty());
EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/"))); EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
...@@ -89,18 +112,45 @@ TEST_F(AutomationManifestTest, Matches) { ...@@ -89,18 +112,45 @@ TEST_F(AutomationManifestTest, Matches) {
EXPECT_FALSE(info->matches.MatchesURL(GURL("http://www.bing.com"))); EXPECT_FALSE(info->matches.MatchesURL(GURL("http://www.bing.com")));
} }
TEST_F(AutomationManifestTest, MatchesAndPermissions) {
scoped_refptr<Extension> extension =
LoadAndExpectSuccess("automation_matches_and_permissions.json");
ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(2u, warnings.size());
EXPECT_EQ("Read and modify your data on www.google.com",
base::UTF16ToUTF8(warnings[0]));
EXPECT_EQ("Read and modify your data on www.twitter.com",
base::UTF16ToUTF8(warnings[1]));
const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info);
EXPECT_FALSE(info->desktop);
EXPECT_FALSE(info->interact);
EXPECT_FALSE(info->matches.is_empty());
EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.twitter.com/")));
EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.twitter.com")));
}
TEST_F(AutomationManifestTest, EmptyMatches) { TEST_F(AutomationManifestTest, EmptyMatches) {
scoped_refptr<Extension> extension = scoped_refptr<Extension> extension =
LoadAndExpectWarning("automation_empty_matches.json", LoadAndExpectWarning("automation_empty_matches.json",
automation_errors::kErrorNoMatchesProvided); automation_errors::kErrorNoMatchesProvided);
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
EXPECT_EQ(0u, warnings.size());
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_FALSE(info->desktop); EXPECT_FALSE(info->desktop);
EXPECT_FALSE(info->interact); EXPECT_FALSE(info->interact);
EXPECT_TRUE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -120,12 +170,15 @@ TEST_F(AutomationManifestTest, NoValidMatches) { ...@@ -120,12 +170,15 @@ TEST_F(AutomationManifestTest, NoValidMatches) {
EXPECT_EQ(automation_errors::kErrorNoMatchesProvided, EXPECT_EQ(automation_errors::kErrorNoMatchesProvided,
extension->install_warnings()[1].message); extension->install_warnings()[1].message);
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(0u, warnings.size());
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_FALSE(info->desktop); EXPECT_FALSE(info->desktop);
EXPECT_FALSE(info->interact); EXPECT_FALSE(info->interact);
EXPECT_TRUE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -134,12 +187,17 @@ TEST_F(AutomationManifestTest, DesktopFalse) { ...@@ -134,12 +187,17 @@ TEST_F(AutomationManifestTest, DesktopFalse) {
LoadAndExpectSuccess("automation_desktop_false.json"); LoadAndExpectSuccess("automation_desktop_false.json");
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ("Read and modify your data on www.google.com",
base::UTF16ToUTF8(warnings[0]));
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_FALSE(info->desktop); EXPECT_FALSE(info->desktop);
EXPECT_FALSE(info->interact); EXPECT_FALSE(info->interact);
EXPECT_FALSE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -148,12 +206,17 @@ TEST_F(AutomationManifestTest, DesktopTrue) { ...@@ -148,12 +206,17 @@ TEST_F(AutomationManifestTest, DesktopTrue) {
LoadAndExpectSuccess("automation_desktop_true.json"); LoadAndExpectSuccess("automation_desktop_true.json");
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS),
warnings[0]);
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_TRUE(info->desktop); EXPECT_TRUE(info->desktop);
EXPECT_TRUE(info->interact); EXPECT_TRUE(info->interact);
EXPECT_FALSE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -161,13 +224,17 @@ TEST_F(AutomationManifestTest, Desktop_InteractTrue) { ...@@ -161,13 +224,17 @@ TEST_F(AutomationManifestTest, Desktop_InteractTrue) {
scoped_refptr<Extension> extension = scoped_refptr<Extension> extension =
LoadAndExpectSuccess("automation_desktop_interact_true.json"); LoadAndExpectSuccess("automation_desktop_interact_true.json");
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS),
warnings[0]);
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_TRUE(info->desktop); EXPECT_TRUE(info->desktop);
EXPECT_TRUE(info->interact); EXPECT_TRUE(info->interact);
EXPECT_FALSE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -177,12 +244,17 @@ TEST_F(AutomationManifestTest, Desktop_InteractFalse) { ...@@ -177,12 +244,17 @@ TEST_F(AutomationManifestTest, Desktop_InteractFalse) {
automation_errors::kErrorDesktopTrueInteractFalse); automation_errors::kErrorDesktopTrueInteractFalse);
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS),
warnings[0]);
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_TRUE(info->desktop); EXPECT_TRUE(info->desktop);
EXPECT_TRUE(info->interact); EXPECT_TRUE(info->interact);
EXPECT_FALSE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
...@@ -192,12 +264,17 @@ TEST_F(AutomationManifestTest, Desktop_MatchesSpecified) { ...@@ -192,12 +264,17 @@ TEST_F(AutomationManifestTest, Desktop_MatchesSpecified) {
automation_errors::kErrorDesktopTrueMatchesSpecified); automation_errors::kErrorDesktopTrueMatchesSpecified);
ASSERT_TRUE(extension.get()); ASSERT_TRUE(extension.get());
std::vector<base::string16> warnings =
extension->permissions_data()->GetPermissionMessageStrings();
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS),
warnings[0]);
const AutomationInfo* info = AutomationInfo::Get(extension.get()); const AutomationInfo* info = AutomationInfo::Get(extension.get());
ASSERT_TRUE(info); ASSERT_TRUE(info);
EXPECT_TRUE(info->desktop); EXPECT_TRUE(info->desktop);
EXPECT_TRUE(info->interact); EXPECT_TRUE(info->interact);
EXPECT_FALSE(info->specified_matches);
EXPECT_TRUE(info->matches.is_empty()); EXPECT_TRUE(info->matches.is_empty());
} }
......
...@@ -2,5 +2,8 @@ ...@@ -2,5 +2,8 @@
"name": "unit_tests --gtest_filter=AutomationManifestTest.AsBooleanTrue", "name": "unit_tests --gtest_filter=AutomationManifestTest.AsBooleanTrue",
"version": "1", "version": "1",
"manifest_version": 2, "manifest_version": 2,
"permissions": [
"http://www.google.com/"
],
"automation": true "automation": true
} }
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
"name": "unit_tests --gtest_filter=AutomationManifestTest.DesktopFalse", "name": "unit_tests --gtest_filter=AutomationManifestTest.DesktopFalse",
"version": "1", "version": "1",
"manifest_version": 2, "manifest_version": 2,
"permissions": [
"http://www.google.com/"
],
"automation": { "automation": {
"desktop": false "desktop": false
} }
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
"name": "unit_tests --gtest_filter=AutomationManifestTest.InteractTrue", "name": "unit_tests --gtest_filter=AutomationManifestTest.InteractTrue",
"version": "1", "version": "1",
"manifest_version": 2, "manifest_version": 2,
"permissions": [
"http://www.google.com/"
],
"automation": { "automation": {
"interact": true "interact": true
} }
......
{
"name": "unit_tests --gtest_filter=AutomationManifestTest.Matches",
"version": "1",
"manifest_version": 2,
"permissions": [
"http://www.google.com/"
],
"automation": {
"matches": [ "http://www.twitter.com/" ]
}
}
...@@ -214,12 +214,8 @@ bool PermissionSet::HasEffectiveAccessToAllHosts() const { ...@@ -214,12 +214,8 @@ bool PermissionSet::HasEffectiveAccessToAllHosts() const {
// There are two ways this set can have effective access to all hosts: // There are two ways this set can have effective access to all hosts:
// 1) it has an <all_urls> URL pattern. // 1) it has an <all_urls> URL pattern.
// 2) it has a named permission with implied full URL access. // 2) it has a named permission with implied full URL access.
for (URLPatternSet::const_iterator host = effective_hosts().begin(); if (effective_hosts().MatchesAllURLs())
host != effective_hosts().end(); ++host) { return true;
if (host->match_all_urls() ||
(host->match_subdomains() && host->host().empty()))
return true;
}
for (APIPermissionSet::const_iterator i = apis().begin(); for (APIPermissionSet::const_iterator i = apis().begin();
i != apis().end(); ++i) { i != apis().end(); ++i) {
......
...@@ -171,6 +171,15 @@ bool URLPatternSet::MatchesURL(const GURL& url) const { ...@@ -171,6 +171,15 @@ bool URLPatternSet::MatchesURL(const GURL& url) const {
return false; return false;
} }
bool URLPatternSet::MatchesAllURLs() const {
for (URLPatternSet::const_iterator host = begin(); host != end(); ++host) {
if (host->match_all_urls() ||
(host->match_subdomains() && host->host().empty()))
return true;
}
return false;
}
bool URLPatternSet::MatchesSecurityOrigin(const GURL& origin) const { bool URLPatternSet::MatchesSecurityOrigin(const GURL& origin) const {
for (URLPatternSet::const_iterator pattern = patterns_.begin(); for (URLPatternSet::const_iterator pattern = patterns_.begin();
pattern != patterns_.end(); ++pattern) { pattern != patterns_.end(); ++pattern) {
...@@ -229,6 +238,17 @@ bool URLPatternSet::Populate(const std::vector<std::string>& patterns, ...@@ -229,6 +238,17 @@ bool URLPatternSet::Populate(const std::vector<std::string>& patterns,
return true; return true;
} }
scoped_ptr<std::vector<std::string> > URLPatternSet::ToStringVector() const {
scoped_ptr<std::vector<std::string> > value(new std::vector<std::string>);
for (URLPatternSet::const_iterator i = patterns_.begin();
i != patterns_.end();
++i) {
value->push_back(i->GetAsString());
}
std::unique(value->begin(), value->end());
return value.Pass();
}
bool URLPatternSet::Populate(const base::ListValue& value, bool URLPatternSet::Populate(const base::ListValue& value,
int valid_schemes, int valid_schemes,
bool allow_file_access, bool allow_file_access,
......
...@@ -79,6 +79,9 @@ class URLPatternSet { ...@@ -79,6 +79,9 @@ class URLPatternSet {
// Test if the extent contains a URL. // Test if the extent contains a URL.
bool MatchesURL(const GURL& url) const; bool MatchesURL(const GURL& url) const;
// Test if the extent matches all URLs (for example, <all_urls>).
bool MatchesAllURLs() const;
bool MatchesSecurityOrigin(const GURL& origin) const; bool MatchesSecurityOrigin(const GURL& origin) const;
// Returns true if there is a single URL that would be in two extents. // Returns true if there is a single URL that would be in two extents.
...@@ -91,6 +94,8 @@ class URLPatternSet { ...@@ -91,6 +94,8 @@ class URLPatternSet {
bool allow_file_access, bool allow_file_access,
std::string* error); std::string* error);
// Converts to and from a vector of strings.
scoped_ptr<std::vector<std::string> > ToStringVector() const;
bool Populate(const std::vector<std::string>& patterns, bool Populate(const std::vector<std::string>& patterns,
int valid_schemes, int valid_schemes,
bool allow_file_access, bool allow_file_access,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment