permission_set_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
14a10645c70199c8d8567fbc46312158c419720abChris Lattner// Copyright (c) 2012 The Chromium Authors. All rights reserved.
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// Use of this source code is governed by a BSD-style license that can be
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// found in the LICENSE file.
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell
521c62da287237d39d0d95004881ea4baae3be6daChris Lattner#include "base/command_line.h"
621c62da287237d39d0d95004881ea4baae3be6daChris Lattner#include "base/json/json_file_value_serializer.h"
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman#include "base/logging.h"
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell#include "base/path_service.h"
94a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "base/utf_string_conversions.h"
104a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "chrome/common/chrome_paths.h"
118ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif#include "chrome/common/chrome_switches.h"
124a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "chrome/common/extensions/api/plugins/plugins_handler.h"
134a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "chrome/common/extensions/background_info.h"
144a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "chrome/common/extensions/extension.h"
154a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "chrome/common/extensions/features/feature.h"
16f1b20d8620b05abaa52f40ac6d21f839b265fb00Chris Lattner#include "chrome/common/extensions/incognito_handler.h"
17551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "chrome/common/extensions/manifest_handler.h"
18551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
19551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "chrome/common/extensions/permissions/permission_set.h"
20551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "chrome/common/extensions/permissions/permissions_info.h"
214a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "chrome/common/extensions/permissions/socket_permission.h"
22e31a9ccb9c7568e6f185f667b53c274c0be9e603Chris Lattner#include "extensions/common/error_utils.h"
2351ab5c8862466bbddcd5c4369779c472978ed309Reid Spencer#include "testing/gtest/include/gtest/gtest.h"
24d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace extensions {
264a10645c70199c8d8567fbc46312158c419720abChris Lattner
274a10645c70199c8d8567fbc46312158c419720abChris Lattnernamespace {
284a10645c70199c8d8567fbc46312158c419720abChris Lattner
294a10645c70199c8d8567fbc46312158c419720abChris Lattnerscoped_refptr<Extension> LoadManifest(const std::string& dir,
304a10645c70199c8d8567fbc46312158c419720abChris Lattner                                      const std::string& test_file,
319ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov                                      int extra_flags) {
324a10645c70199c8d8567fbc46312158c419720abChris Lattner  base::FilePath path;
334148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman  PathService::Get(chrome::DIR_TEST_DATA, &path);
34a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner  path = path.AppendASCII("extensions")
35a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner             .AppendASCII(dir)
36a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner             .AppendASCII(test_file);
37a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner
38a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner  JSONFileValueSerializer serializer(path);
39a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner  std::string error;
40a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner  scoped_ptr<Value> result(serializer.Deserialize(NULL, &error));
414a10645c70199c8d8567fbc46312158c419720abChris Lattner  if (!result.get()) {
4270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    EXPECT_EQ("", error);
43b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke    return NULL;
44b687d82b029ba448b978e2c9ed424ee5d1f9f093Misha Brukman  }
45b687d82b029ba448b978e2c9ed424ee5d1f9f093Misha Brukman
465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  scoped_refptr<Extension> extension = Extension::Create(
475073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman      path.DirName(), Manifest::INVALID_LOCATION,
485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman      *static_cast<DictionaryValue*>(result.get()), extra_flags, &error);
49c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner  EXPECT_TRUE(extension) << error;
50cd6f46e2ac4c1d64067237c0b28eccfae22bd9f4Chris Lattner  return extension;
519ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov}
529ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov
539ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikovscoped_refptr<Extension> LoadManifest(const std::string& dir,
544d143ee01988e1b52e106ffccbb313937ca5e886Chris Lattner                                      const std::string& test_file) {
55b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  return LoadManifest(dir, test_file, Extension::NO_FLAGS);
563c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner}
5770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
5870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohmanstatic void AddPattern(URLPatternSet* extent, const std::string& pattern) {
5970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  int schemes = URLPattern::SCHEME_ALL;
6070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extent->AddPattern(URLPattern(schemes, pattern));
6170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman}
6270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
6370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohmansize_t IndexOf(const std::vector<string16>& warnings,
6470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman               const std::string& warning) {
6570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  for (size_t i = 0; i < warnings.size(); ++i) {
6670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    if (warnings[i] == ASCIIToUTF16(warning))
6770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      return i;
6870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  }
6970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
7070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  return warnings.size();
7170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman}
7270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
73c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaekebool Contains(const std::vector<string16>& warnings,
745e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer              const std::string& warning) {
755e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer  return IndexOf(warnings, warning) != warnings.size();
765e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer}
775e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer
783c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner}  // namespace
793c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner
803c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattnerclass PermissionsTest : public testing::Test {
817dac658792425c10274594782d6fcf10208a16f0Chris Lattner protected:
827dac658792425c10274594782d6fcf10208a16f0Chris Lattner  virtual void SetUp() OVERRIDE {
837dac658792425c10274594782d6fcf10208a16f0Chris Lattner    testing::Test::SetUp();
847dac658792425c10274594782d6fcf10208a16f0Chris Lattner    (new BackgroundManifestHandler)->Register();
857dac658792425c10274594782d6fcf10208a16f0Chris Lattner    (new ContentScriptsHandler)->Register();
867d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner    (new PluginsHandler)->Register();
8751ab5c8862466bbddcd5c4369779c472978ed309Reid Spencer    (new IncognitoHandler)->Register();
889ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov  }
8951ab5c8862466bbddcd5c4369779c472978ed309Reid Spencer
909ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov  virtual void TearDown() OVERRIDE {
919ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov    ManifestHandler::ClearRegistryForTesting();
929ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov    testing::Test::TearDown();
939ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov  }
949ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov};
954a10645c70199c8d8567fbc46312158c419720abChris Lattner
964a10645c70199c8d8567fbc46312158c419720abChris Lattner// Tests GetByID.
97d0fde30ce850b78371fd1386338350591f9ff494Brian GaekeTEST_F(PermissionsTest, GetByID) {
98fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  PermissionsInfo* info = PermissionsInfo::GetInstance();
99fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  APIPermissionSet apis = info->GetAll();
100fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  for (APIPermissionSet::const_iterator i = apis.begin();
101fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner       i != apis.end(); ++i) {
10260083e2fc0f1165b7511757449f1ee3852b7229cChris Lattner    EXPECT_EQ(i->id(), i->info()->id());
10370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  }
104636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke}
10570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
106636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke// Tests that GetByName works with normal permission names and aliases.
107636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian GaekeTEST_F(PermissionsTest, GetByName) {
10860083e2fc0f1165b7511757449f1ee3852b7229cChris Lattner  PermissionsInfo* info = PermissionsInfo::GetInstance();
10970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
11070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_EQ(APIPermission::kManagement,
11170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            info->GetByName("management")->id());
11270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_FALSE(info->GetByName("alsdkfjasldkfj"));
11370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman}
114fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner
1159d679cbc6cb5c7dc8cca87a1e1548c480fb056b8Misha BrukmanTEST_F(PermissionsTest, GetAll) {
1164a10645c70199c8d8567fbc46312158c419720abChris Lattner  size_t count = 0;
1174a10645c70199c8d8567fbc46312158c419720abChris Lattner  PermissionsInfo* info = PermissionsInfo::GetInstance();
1184a10645c70199c8d8567fbc46312158c419720abChris Lattner  APIPermissionSet apis = info->GetAll();
1194a10645c70199c8d8567fbc46312158c419720abChris Lattner  for (APIPermissionSet::const_iterator api = apis.begin();
1204a10645c70199c8d8567fbc46312158c419720abChris Lattner       api != apis.end(); ++api) {
1214a10645c70199c8d8567fbc46312158c419720abChris Lattner    // Make sure only the valid permission IDs get returned.
1224a10645c70199c8d8567fbc46312158c419720abChris Lattner    EXPECT_NE(APIPermission::kInvalid, api->id());
1234a10645c70199c8d8567fbc46312158c419720abChris Lattner    EXPECT_NE(APIPermission::kUnknown, api->id());
1244a10645c70199c8d8567fbc46312158c419720abChris Lattner    count++;
1254a10645c70199c8d8567fbc46312158c419720abChris Lattner  }
1264148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman  EXPECT_EQ(count, info->get_permission_count());
1274148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman}
12870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
1294a10645c70199c8d8567fbc46312158c419720abChris LattnerTEST_F(PermissionsTest, GetAllByName) {
130636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke  std::set<std::string> names;
131cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner  names.insert("background");
132b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  names.insert("management");
133b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke
13470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  // This is an alias of kTab
13570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  names.insert("windows");
136b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke
137b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  // This unknown name should get dropped.
138636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke  names.insert("sdlkfjasdlkfj");
139636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke
140b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  APIPermissionSet expected;
141b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  expected.insert(APIPermission::kBackground);
142b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  expected.insert(APIPermission::kManagement);
143636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke  expected.insert(APIPermission::kTab);
144636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke
145b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  EXPECT_EQ(expected,
146b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke            PermissionsInfo::GetInstance()->GetAllByName(names));
147b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke}
148636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke
149636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke// Tests that the aliases are properly mapped.
150b5ee509be2ce78badc11fd649dda90ec78394d1aBrian GaekeTEST_F(PermissionsTest, Aliases) {
151b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  PermissionsInfo* info = PermissionsInfo::GetInstance();
152b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  // tabs: tabs, windows
153b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  std::string tabs_name = "tabs";
154b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  EXPECT_EQ(tabs_name, info->GetByID(APIPermission::kTab)->name());
155b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke  EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
156769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  EXPECT_EQ(APIPermission::kTab, info->GetByName("windows")->id());
157636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke
158636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke  // unlimitedStorage: unlimitedStorage, unlimited_storage
159769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  std::string storage_name = "unlimitedStorage";
160769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  EXPECT_EQ(storage_name, info->GetByID(
16170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      APIPermission::kUnlimitedStorage)->name());
162636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke  EXPECT_EQ(APIPermission::kUnlimitedStorage,
163636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke            info->GetByName("unlimitedStorage")->id());
164769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  EXPECT_EQ(APIPermission::kUnlimitedStorage,
165769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner            info->GetByName("unlimited_storage")->id());
166636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke}
167636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke
168769f1fe6728ffb5627ae0cedc392576d6e701a5aChris LattnerTEST_F(PermissionsTest, EffectiveHostPermissions) {
169769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  scoped_refptr<Extension> extension;
170c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner  scoped_refptr<const PermissionSet> permissions;
171c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner
172c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner  extension = LoadManifest("effective_host_permissions", "empty.json");
173769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  permissions = extension->GetActivePermissions();
1749ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov  EXPECT_EQ(0u, extension->GetEffectiveHostPermissions().patterns().size());
1759ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov  EXPECT_FALSE(permissions->HasEffectiveAccessToURL(
1769ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov      GURL("http://www.google.com")));
1779ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov  EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
178cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner
1794148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman  extension = LoadManifest("effective_host_permissions", "one_host.json");
180cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner  permissions = extension->GetActivePermissions();
1814a10645c70199c8d8567fbc46312158c419720abChris Lattner  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
182ad6996d74f60340d6139af8f345d93735661fbbaMatthijs Kooijman      GURL("http://www.google.com")));
183ad6996d74f60340d6139af8f345d93735661fbbaMatthijs Kooijman  EXPECT_FALSE(permissions->HasEffectiveAccessToURL(
184ad6996d74f60340d6139af8f345d93735661fbbaMatthijs Kooijman      GURL("https://www.google.com")));
185ad6996d74f60340d6139af8f345d93735661fbbaMatthijs Kooijman  EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
1864a10645c70199c8d8567fbc46312158c419720abChris Lattner
18770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extension = LoadManifest("effective_host_permissions",
18870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman                           "one_host_wildcard.json");
18970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  permissions = extension->GetActivePermissions();
19070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
19170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
19270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      GURL("http://foo.google.com")));
19370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
19470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
19570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extension = LoadManifest("effective_host_permissions", "two_hosts.json");
19670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  permissions = extension->GetActivePermissions();
19770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
19870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      GURL("http://www.google.com")));
19970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
20070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      GURL("http://www.reddit.com")));
20170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
20270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
20370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extension = LoadManifest("effective_host_permissions",
20470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman                           "https_not_considered.json");
20570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  permissions = extension->GetActivePermissions();
20670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
20770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://google.com")));
20870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
20970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
21070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extension = LoadManifest("effective_host_permissions",
21170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman                           "two_content_scripts.json");
21270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  permissions = extension->GetActivePermissions();
21370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
21470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
21570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      GURL("http://www.reddit.com")));
21670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
21770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      GURL("http://news.ycombinator.com")));
21870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
21970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
22070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extension = LoadManifest("effective_host_permissions", "all_hosts.json");
22170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  permissions = extension->GetActivePermissions();
22270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
22370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
22470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(
22570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
22670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
22770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
22870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
22970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  permissions = extension->GetActivePermissions();
23070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
23170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(
23270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
23370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
23470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
23570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
23670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  permissions = extension->GetActivePermissions();
23770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
23870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
23970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(
24070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
24170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
24270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman}
24370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
24470ef449741da8b1ef035e04a55958652a0200ba1Dan GohmanTEST_F(PermissionsTest, ExplicitAccessToOrigin) {
24570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  APIPermissionSet apis;
24670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  URLPatternSet explicit_hosts;
24770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  URLPatternSet scriptable_hosts;
24870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
24970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  AddPattern(&explicit_hosts, "http://*.google.com/*");
2507bb11547e497d7b8fc87f61c1089eee808e3a1eeChris Lattner  // The explicit host paths should get set to /*.
25170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  AddPattern(&explicit_hosts, "http://www.example.com/a/particular/path/*");
252c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner
253769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  scoped_refptr<PermissionSet> perm_set = new PermissionSet(
254a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman      apis, explicit_hosts, scriptable_hosts);
255a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
2564a10645c70199c8d8567fbc46312158c419720abChris Lattner      GURL("http://www.google.com/")));
2574a10645c70199c8d8567fbc46312158c419720abChris Lattner  ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
2584a10645c70199c8d8567fbc46312158c419720abChris Lattner      GURL("http://test.google.com/")));
2594a10645c70199c8d8567fbc46312158c419720abChris Lattner  ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
260ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner      GURL("http://www.example.com")));
261ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner  ASSERT_TRUE(perm_set->HasEffectiveAccessToURL(
262ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner      GURL("http://www.example.com")));
263ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner  ASSERT_FALSE(perm_set->HasExplicitAccessToOrigin(
264ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner      GURL("http://test.example.com")));
2658ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif}
2668ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
26751c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid SpencerTEST_F(PermissionsTest, CreateUnion) {
2688ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  APIPermission* permission = NULL;
26951c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer
27051c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  APIPermissionSet apis1;
27151c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  APIPermissionSet apis2;
27251c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  APIPermissionSet expected_apis;
2738ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
2748ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  URLPatternSet explicit_hosts1;
2758ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  URLPatternSet explicit_hosts2;
276ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner  URLPatternSet expected_explicit_hosts;
277ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner
278ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner  URLPatternSet scriptable_hosts1;
2798ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  URLPatternSet scriptable_hosts2;
2808ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  URLPatternSet expected_scriptable_hosts;
281ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner
282ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner  URLPatternSet effective_hosts;
2838ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
284ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner  scoped_refptr<PermissionSet> set1;
285ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner  scoped_refptr<PermissionSet> set2;
2864a10645c70199c8d8567fbc46312158c419720abChris Lattner  scoped_refptr<PermissionSet> union_set;
2874a10645c70199c8d8567fbc46312158c419720abChris Lattner
2884a10645c70199c8d8567fbc46312158c419720abChris Lattner  const APIPermissionInfo* permission_info =
2894a10645c70199c8d8567fbc46312158c419720abChris Lattner    PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
2904a10645c70199c8d8567fbc46312158c419720abChris Lattner  permission = permission_info->CreateAPIPermission();
2914a10645c70199c8d8567fbc46312158c419720abChris Lattner  {
2928ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif    scoped_ptr<ListValue> value(new ListValue());
293769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner    value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80"));
294c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke    value->Append(Value::CreateStringValue("udp-bind::8080"));
295c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke    value->Append(Value::CreateStringValue("udp-send-to::8888"));
296769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner    if (!permission->FromValue(value.get())) {
297769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner      NOTREACHED();
2988ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif    }
29951c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  }
3008ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
3018ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  // Union with an empty set.
30297182985d530dbef488696c95a39c14fe56c995bReid Spencer  apis1.insert(APIPermission::kTab);
30351c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  apis1.insert(APIPermission::kBackground);
30451c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  apis1.insert(permission->Clone());
30551c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  expected_apis.insert(APIPermission::kTab);
30651c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  expected_apis.insert(APIPermission::kBackground);
30751c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  expected_apis.insert(permission);
3088ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
3094a10645c70199c8d8567fbc46312158c419720abChris Lattner  AddPattern(&explicit_hosts1, "http://*.google.com/*");
3108ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
3118ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  AddPattern(&effective_hosts, "http://*.google.com/*");
3128ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
3134a10645c70199c8d8567fbc46312158c419720abChris Lattner  set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1);
3144a10645c70199c8d8567fbc46312158c419720abChris Lattner  set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2);
3158ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
3164a10645c70199c8d8567fbc46312158c419720abChris Lattner  EXPECT_TRUE(set1->Contains(*set2));
3174a10645c70199c8d8567fbc46312158c419720abChris Lattner  EXPECT_TRUE(set1->Contains(*union_set));
3188ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  EXPECT_FALSE(set2->Contains(*set1));
3198ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  EXPECT_FALSE(set2->Contains(*union_set));
3208ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  EXPECT_TRUE(union_set->Contains(*set1));
3219709272675feaca030cce14d0f5eb7f342b3fc1dChris Lattner  EXPECT_TRUE(union_set->Contains(*set2));
3224a10645c70199c8d8567fbc46312158c419720abChris Lattner
3235073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  EXPECT_FALSE(union_set->HasEffectiveFullAccess());
3244a10645c70199c8d8567fbc46312158c419720abChris Lattner  EXPECT_EQ(expected_apis, union_set->apis());
32597182985d530dbef488696c95a39c14fe56c995bReid Spencer  EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
32651c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
32751c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts());
32851c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer
32951c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  // Now use a real second set.
33051c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer  apis2.insert(APIPermission::kTab);
33197182985d530dbef488696c95a39c14fe56c995bReid Spencer  apis2.insert(APIPermission::kProxy);
3324a10645c70199c8d8567fbc46312158c419720abChris Lattner  apis2.insert(APIPermission::kClipboardWrite);
333769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  apis2.insert(APIPermission::kPlugin);
3347dac658792425c10274594782d6fcf10208a16f0Chris Lattner
335769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  permission = permission_info->CreateAPIPermission();
336769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner  {
337769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner    scoped_ptr<ListValue> value(new ListValue());
33870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80"));
33970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    value->Append(Value::CreateStringValue("udp-send-to::8899"));
34070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    if (!permission->FromValue(value.get())) {
3417d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner      NOTREACHED();
3427d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner    }
3437d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  }
3447d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  apis2.insert(permission);
3457d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner
3467d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  expected_apis.insert(APIPermission::kTab);
3477d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  expected_apis.insert(APIPermission::kProxy);
3487d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  expected_apis.insert(APIPermission::kClipboardWrite);
3497d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  expected_apis.insert(APIPermission::kPlugin);
3507d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner
3517d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  permission = permission_info->CreateAPIPermission();
3527d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner  {
3537d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner    scoped_ptr<ListValue> value(new ListValue());
354769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner    value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80"));
3555e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    value->Append(Value::CreateStringValue("udp-bind::8080"));
3565e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    value->Append(Value::CreateStringValue("udp-send-to::8888"));
3575e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    value->Append(Value::CreateStringValue("udp-send-to::8899"));
3585e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    if (!permission->FromValue(value.get())) {
3595e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer      NOTREACHED();
3605e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    }
361c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke  }
362c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke  // Insert a new permission socket permisssion which will replace the old one.
3634a10645c70199c8d8567fbc46312158c419720abChris Lattner  expected_apis.insert(permission);
3644a10645c70199c8d8567fbc46312158c419720abChris Lattner
3654a10645c70199c8d8567fbc46312158c419720abChris Lattner  AddPattern(&explicit_hosts2, "http://*.example.com/*");
3664a10645c70199c8d8567fbc46312158c419720abChris Lattner  AddPattern(&scriptable_hosts2, "http://*.google.com/*");
3674a10645c70199c8d8567fbc46312158c419720abChris Lattner  AddPattern(&expected_explicit_hosts, "http://*.example.com/*");
36870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  AddPattern(&expected_scriptable_hosts, "http://*.google.com/*");
369c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke
370c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke  URLPatternSet::CreateUnion(
37170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman      explicit_hosts2, scriptable_hosts2, &effective_hosts);
372c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke
37370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2);
374c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke  union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
375c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke
376c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke  EXPECT_FALSE(set1->Contains(*set2));
3775073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  EXPECT_FALSE(set1->Contains(*union_set));
3788ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  EXPECT_FALSE(set2->Contains(*set1));
3795073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  EXPECT_FALSE(set2->Contains(*union_set));
380c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner  EXPECT_TRUE(union_set->Contains(*set1));
3815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  EXPECT_TRUE(union_set->Contains(*set2));
38270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
38370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  EXPECT_TRUE(union_set->HasEffectiveFullAccess());
3845073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts());
385a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner  EXPECT_EQ(expected_apis, union_set->apis());
386c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner  EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
387130e2a361147a31ae631d3648afdd95a5c0d40f2Chris Lattner  EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
388a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner  EXPECT_EQ(effective_hosts, union_set->effective_hosts());
3895073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman}
3905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
391c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris LattnerTEST_F(PermissionsTest, CreateIntersection) {
3925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  APIPermission* permission = NULL;
3936ebe44d22f6dd1ab9f7aa1f3cfd02be52145d535Chris Lattner
3945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  APIPermissionSet apis1;
3955073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  APIPermissionSet apis2;
3966a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  APIPermissionSet expected_apis;
3976a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins
3986a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  URLPatternSet explicit_hosts1;
3996a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  URLPatternSet explicit_hosts2;
4006a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  URLPatternSet expected_explicit_hosts;
401c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner
4026a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  URLPatternSet scriptable_hosts1;
4036a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  URLPatternSet scriptable_hosts2;
404d41b30def3181bce4bf87e8bde664d15663165d0Jeff Cohen  URLPatternSet expected_scriptable_hosts;
4056a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins
4066a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  URLPatternSet effective_hosts;
4076a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins
40870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  scoped_refptr<PermissionSet> set1;
4096a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  scoped_refptr<PermissionSet> set2;
4106a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  scoped_refptr<PermissionSet> new_set;
4116a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins
41270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  const APIPermissionInfo* permission_info =
41370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
41470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
41570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  // Intersection with an empty set.
41670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman  apis1.insert(APIPermission::kTab);
4176a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  apis1.insert(APIPermission::kBackground);
4186a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  permission = permission_info->CreateAPIPermission();
4196a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins  {
4206a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    scoped_ptr<ListValue> value(new ListValue());
4216a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80"));
4225073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    value->Append(Value::CreateStringValue("udp-bind::8080"));
4236a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    value->Append(Value::CreateStringValue("udp-send-to::8888"));
4246a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    if (!permission->FromValue(value.get())) {
4256a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins      NOTREACHED();
4266a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    }
4274a10645c70199c8d8567fbc46312158c419720abChris Lattner  }
4288ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  apis1.insert(permission);
4295073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
4308ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  AddPattern(&explicit_hosts1, "http://*.google.com/*");
431c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke  AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
432c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke
4334a10645c70199c8d8567fbc46312158c419720abChris Lattner  set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1);
4348ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2);
4355f76760c880e6d61c229d2058c5699b033caeae1Reid Spencer  new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
436c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke  EXPECT_TRUE(set1->Contains(*new_set));
43765f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner  EXPECT_TRUE(set2->Contains(*new_set));
4384a10645c70199c8d8567fbc46312158c419720abChris Lattner  EXPECT_TRUE(set1->Contains(*set2));
439a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner  EXPECT_FALSE(set2->Contains(*set1));
440a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner  EXPECT_FALSE(new_set->Contains(*set1));
441a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner  EXPECT_TRUE(new_set->Contains(*set2));
442a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner
443eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman  EXPECT_TRUE(new_set->IsEmpty());
44465f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner  EXPECT_FALSE(new_set->HasEffectiveFullAccess());
44565f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner  EXPECT_EQ(expected_apis, new_set->apis());
44665f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner  EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
44765f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner  EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
4483da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman  EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts());
4491a28a2b76d16913fe38f47032d31620a55dcce2eChris Lattner
450a229c5cce75209047db32c6039aa0b0fd481f049Reid Spencer  // Now use a real second set.
4514a10645c70199c8d8567fbc46312158c419720abChris Lattner  apis2.insert(APIPermission::kTab);
4528ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  apis2.insert(APIPermission::kProxy);
4538ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  apis2.insert(APIPermission::kClipboardWrite);
4548ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif  apis2.insert(APIPermission::kPlugin);
4554a10645c70199c8d8567fbc46312158c419720abChris Lattner  permission = permission_info->CreateAPIPermission();
4564a10645c70199c8d8567fbc46312158c419720abChris Lattner  {
45791eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman    scoped_ptr<ListValue> value(new ListValue());
45891eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman    value->Append(Value::CreateStringValue("udp-bind::8080"));
45991eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman    value->Append(Value::CreateStringValue("udp-send-to::8888"));
46091eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman    value->Append(Value::CreateStringValue("udp-send-to::8899"));
461d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke    if (!permission->FromValue(value.get())) {
462      NOTREACHED();
463    }
464  }
465  apis2.insert(permission);
466
467  expected_apis.insert(APIPermission::kTab);
468  permission = permission_info->CreateAPIPermission();
469  {
470    scoped_ptr<ListValue> value(new ListValue());
471    value->Append(Value::CreateStringValue("udp-bind::8080"));
472    value->Append(Value::CreateStringValue("udp-send-to::8888"));
473    if (!permission->FromValue(value.get())) {
474      NOTREACHED();
475    }
476  }
477  expected_apis.insert(permission);
478
479  AddPattern(&explicit_hosts2, "http://*.example.com/*");
480  AddPattern(&explicit_hosts2, "http://*.google.com/*");
481  AddPattern(&scriptable_hosts2, "http://*.google.com/*");
482  AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
483
484  effective_hosts.ClearPatterns();
485  AddPattern(&effective_hosts, "http://*.google.com/*");
486
487  set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2);
488  new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
489
490  EXPECT_TRUE(set1->Contains(*new_set));
491  EXPECT_TRUE(set2->Contains(*new_set));
492  EXPECT_FALSE(set1->Contains(*set2));
493  EXPECT_FALSE(set2->Contains(*set1));
494  EXPECT_FALSE(new_set->Contains(*set1));
495  EXPECT_FALSE(new_set->Contains(*set2));
496
497  EXPECT_FALSE(new_set->HasEffectiveFullAccess());
498  EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
499  EXPECT_EQ(expected_apis, new_set->apis());
500  EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
501  EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
502  EXPECT_EQ(effective_hosts, new_set->effective_hosts());
503}
504
505TEST_F(PermissionsTest, CreateDifference) {
506  APIPermission* permission = NULL;
507
508  APIPermissionSet apis1;
509  APIPermissionSet apis2;
510  APIPermissionSet expected_apis;
511
512  URLPatternSet explicit_hosts1;
513  URLPatternSet explicit_hosts2;
514  URLPatternSet expected_explicit_hosts;
515
516  URLPatternSet scriptable_hosts1;
517  URLPatternSet scriptable_hosts2;
518  URLPatternSet expected_scriptable_hosts;
519
520  URLPatternSet effective_hosts;
521
522  scoped_refptr<PermissionSet> set1;
523  scoped_refptr<PermissionSet> set2;
524  scoped_refptr<PermissionSet> new_set;
525
526  const APIPermissionInfo* permission_info =
527    PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
528
529  // Difference with an empty set.
530  apis1.insert(APIPermission::kTab);
531  apis1.insert(APIPermission::kBackground);
532  permission = permission_info->CreateAPIPermission();
533  {
534    scoped_ptr<ListValue> value(new ListValue());
535    value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80"));
536    value->Append(Value::CreateStringValue("udp-bind::8080"));
537    value->Append(Value::CreateStringValue("udp-send-to::8888"));
538    if (!permission->FromValue(value.get())) {
539      NOTREACHED();
540    }
541  }
542  apis1.insert(permission);
543
544  AddPattern(&explicit_hosts1, "http://*.google.com/*");
545  AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
546
547  set1 = new PermissionSet(apis1, explicit_hosts1, scriptable_hosts1);
548  set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2);
549  new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
550  EXPECT_EQ(*set1, *new_set);
551
552  // Now use a real second set.
553  apis2.insert(APIPermission::kTab);
554  apis2.insert(APIPermission::kProxy);
555  apis2.insert(APIPermission::kClipboardWrite);
556  apis2.insert(APIPermission::kPlugin);
557  permission = permission_info->CreateAPIPermission();
558  {
559    scoped_ptr<ListValue> value(new ListValue());
560    value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80"));
561    value->Append(Value::CreateStringValue("udp-send-to::8899"));
562    if (!permission->FromValue(value.get())) {
563      NOTREACHED();
564    }
565  }
566  apis2.insert(permission);
567
568  expected_apis.insert(APIPermission::kBackground);
569  permission = permission_info->CreateAPIPermission();
570  {
571    scoped_ptr<ListValue> value(new ListValue());
572    value->Append(Value::CreateStringValue("udp-bind::8080"));
573    value->Append(Value::CreateStringValue("udp-send-to::8888"));
574    if (!permission->FromValue(value.get())) {
575      NOTREACHED();
576    }
577  }
578  expected_apis.insert(permission);
579
580  AddPattern(&explicit_hosts2, "http://*.example.com/*");
581  AddPattern(&explicit_hosts2, "http://*.google.com/*");
582  AddPattern(&scriptable_hosts2, "http://*.google.com/*");
583  AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*");
584
585  effective_hosts.ClearPatterns();
586  AddPattern(&effective_hosts, "http://www.reddit.com/*");
587
588  set2 = new PermissionSet(apis2, explicit_hosts2, scriptable_hosts2);
589  new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
590
591  EXPECT_TRUE(set1->Contains(*new_set));
592  EXPECT_FALSE(set2->Contains(*new_set));
593
594  EXPECT_FALSE(new_set->HasEffectiveFullAccess());
595  EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
596  EXPECT_EQ(expected_apis, new_set->apis());
597  EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
598  EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
599  EXPECT_EQ(effective_hosts, new_set->effective_hosts());
600
601  // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set
602  set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get());
603  EXPECT_TRUE(set1->IsEmpty());
604}
605
606TEST_F(PermissionsTest, HasLessPrivilegesThan) {
607  const struct {
608    const char* base_name;
609    bool expect_increase;
610  } kTests[] = {
611    { "allhosts1", false },  // all -> all
612    { "allhosts2", false },  // all -> one
613    { "allhosts3", true },  // one -> all
614    { "hosts1", false },  // http://a,http://b -> http://a,http://b
615    { "hosts2", true },  // http://a,http://b -> https://a,http://*.b
616    { "hosts3", false },  // http://a,http://b -> http://a
617    { "hosts4", true },  // http://a -> http://a,http://b
618    { "hosts5", false },  // http://a,b,c -> http://a,b,c + https://a,b,c
619    { "hosts6", false },  // http://a.com -> http://a.com + http://a.co.uk
620    { "permissions1", false },  // tabs -> tabs
621    { "permissions2", true },  // tabs -> tabs,bookmarks
622    { "permissions3", true },  // http://a -> http://a,tabs
623    { "permissions5", true },  // bookmarks -> bookmarks,history
624    { "equivalent_warnings", false },  // tabs --> tabs, webNavigation
625#if !defined(OS_CHROMEOS)  // plugins aren't allowed in ChromeOS
626    { "permissions4", false },  // plugin -> plugin,tabs
627    { "plugin1", false },  // plugin -> plugin
628    { "plugin2", false },  // plugin -> none
629    { "plugin3", true },  // none -> plugin
630#endif
631    { "storage", false },  // none -> storage
632    { "notifications", false },  // none -> notifications
633  };
634
635  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
636    scoped_refptr<Extension> old_extension(
637        LoadManifest("allow_silent_upgrade",
638                     std::string(kTests[i].base_name) + "_old.json"));
639    scoped_refptr<Extension> new_extension(
640        LoadManifest("allow_silent_upgrade",
641                     std::string(kTests[i].base_name) + "_new.json"));
642
643    EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json";
644    if (!new_extension.get())
645      continue;
646
647    scoped_refptr<const PermissionSet> old_p(
648        old_extension->GetActivePermissions());
649    scoped_refptr<const PermissionSet> new_p(
650        new_extension->GetActivePermissions());
651
652    EXPECT_EQ(kTests[i].expect_increase,
653              old_p->HasLessPrivilegesThan(new_p)) << kTests[i].base_name;
654  }
655}
656
657TEST_F(PermissionsTest, PermissionMessages) {
658  // Ensure that all permissions that needs to show install UI actually have
659  // strings associated with them.
660  APIPermissionSet skip;
661
662  // These are considered "nuisance" or "trivial" permissions that don't need
663  // a prompt.
664  skip.insert(APIPermission::kActiveTab);
665  skip.insert(APIPermission::kAdView);
666  skip.insert(APIPermission::kAlarms);
667  skip.insert(APIPermission::kAppCurrentWindowInternal);
668  skip.insert(APIPermission::kAppRuntime);
669  skip.insert(APIPermission::kAppWindow);
670  skip.insert(APIPermission::kBrowsingData);
671  skip.insert(APIPermission::kContextMenus);
672  skip.insert(APIPermission::kFontSettings);
673  skip.insert(APIPermission::kFullscreen);
674  skip.insert(APIPermission::kIdle);
675  skip.insert(APIPermission::kNotification);
676  skip.insert(APIPermission::kPointerLock);
677  skip.insert(APIPermission::kPower);
678  skip.insert(APIPermission::kPushMessaging);
679  skip.insert(APIPermission::kSessionRestore);
680  skip.insert(APIPermission::kScreensaver);
681  skip.insert(APIPermission::kStorage);
682  skip.insert(APIPermission::kSystemInfoDisplay);
683  skip.insert(APIPermission::kTts);
684  skip.insert(APIPermission::kUnlimitedStorage);
685  skip.insert(APIPermission::kWebView);
686
687  // TODO(erikkay) add a string for this permission.
688  skip.insert(APIPermission::kBackground);
689
690  skip.insert(APIPermission::kClipboardWrite);
691
692  // The cookie permission does nothing unless you have associated host
693  // permissions.
694  skip.insert(APIPermission::kCookie);
695
696  // These are warned as part of host permission checks.
697  skip.insert(APIPermission::kDeclarativeContent);
698  skip.insert(APIPermission::kDeclarativeWebRequest);
699  skip.insert(APIPermission::kNativeMessaging);
700  skip.insert(APIPermission::kPageCapture);
701  skip.insert(APIPermission::kProxy);
702  skip.insert(APIPermission::kTabCapture);
703  skip.insert(APIPermission::kWebRequest);
704  skip.insert(APIPermission::kWebRequestBlocking);
705
706  // This permission requires explicit user action (context menu handler)
707  // so we won't prompt for it for now.
708  skip.insert(APIPermission::kFileBrowserHandler);
709
710  // These permissions require explicit user action (configuration dialog)
711  // so we don't prompt for them at install time.
712  skip.insert(APIPermission::kMediaGalleries);
713
714  // If you've turned on the experimental command-line flag, we don't need
715  // to warn you further.
716  skip.insert(APIPermission::kExperimental);
717
718  // These are private.
719  skip.insert(APIPermission::kAutoTestPrivate);
720  skip.insert(APIPermission::kBookmarkManagerPrivate);
721  skip.insert(APIPermission::kChromeosInfoPrivate);
722  skip.insert(APIPermission::kCloudPrintPrivate);
723  skip.insert(APIPermission::kDeveloperPrivate);
724  skip.insert(APIPermission::kDial);
725  skip.insert(APIPermission::kDownloadsInternal);
726  skip.insert(APIPermission::kEchoPrivate);
727  skip.insert(APIPermission::kFileBrowserHandlerInternal);
728  skip.insert(APIPermission::kFileBrowserPrivate);
729  skip.insert(APIPermission::kInputMethodPrivate);
730  skip.insert(APIPermission::kManagedModePrivate);
731  skip.insert(APIPermission::kMediaGalleriesPrivate);
732  skip.insert(APIPermission::kMediaPlayerPrivate);
733  skip.insert(APIPermission::kMetricsPrivate);
734  skip.insert(APIPermission::kNetworkingPrivate);
735  skip.insert(APIPermission::kRtcPrivate);
736  skip.insert(APIPermission::kStreamsPrivate);
737  skip.insert(APIPermission::kSystemPrivate);
738  skip.insert(APIPermission::kTerminalPrivate);
739  skip.insert(APIPermission::kWallpaperPrivate);
740  skip.insert(APIPermission::kWebRequestInternal);
741  skip.insert(APIPermission::kWebSocketProxyPrivate);
742  skip.insert(APIPermission::kWebstorePrivate);
743
744  // Warned as part of host permissions.
745  skip.insert(APIPermission::kDevtools);
746
747  // Platform apps.
748  skip.insert(APIPermission::kFileSystem);
749  skip.insert(APIPermission::kSocket);
750  skip.insert(APIPermission::kUsbDevice);
751
752  PermissionsInfo* info = PermissionsInfo::GetInstance();
753  APIPermissionSet permissions = info->GetAll();
754  for (APIPermissionSet::const_iterator i = permissions.begin();
755       i != permissions.end(); ++i) {
756    const APIPermissionInfo* permission_info = i->info();
757    EXPECT_TRUE(permission_info != NULL);
758
759    // Always skip permissions that cannot be in the manifest.
760    scoped_ptr<const APIPermission> permission(
761        permission_info->CreateAPIPermission());
762    if (permission->ManifestEntryForbidden())
763      continue;
764
765    if (skip.count(i->id())) {
766      EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id())
767          << "unexpected message_id for " << permission_info->name();
768    } else {
769      EXPECT_NE(PermissionMessage::kNone, permission_info->message_id())
770          << "missing message_id for " << permission_info->name();
771    }
772  }
773}
774
775// Tests the default permissions (empty API permission set).
776TEST_F(PermissionsTest, DefaultFunctionAccess) {
777  const struct {
778    const char* permission_name;
779    bool expect_success;
780  } kTests[] = {
781    // Negative test.
782    { "non_existing_permission", false },
783    // Test default module/package permission.
784    { "browserAction",  true },
785    { "devtools",       true },
786    { "extension",      true },
787    { "i18n",           true },
788    { "pageAction",     true },
789    { "pageActions",    true },
790    { "test",           true },
791    // Some negative tests.
792    { "bookmarks",      false },
793    { "cookies",        false },
794    { "history",        false },
795    // Make sure we find the module name after stripping '.' and '/'.
796    { "browserAction/abcd/onClick",  true },
797    { "browserAction.abcd.onClick",  true },
798    // Test Tabs functions.
799    { "tabs.create",      true},
800    { "tabs.duplicate",   true},
801    { "tabs.update",      true},
802    { "tabs.getSelected", true},
803    { "tabs.onUpdated",   true },
804  };
805
806  scoped_refptr<PermissionSet> empty = new PermissionSet();
807  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
808    EXPECT_EQ(kTests[i].expect_success,
809              empty->HasAccessToFunction(kTests[i].permission_name, true))
810                  << "Permission being tested: " << kTests[i].permission_name;
811  }
812}
813
814// Tests the default permissions (empty API permission set).
815TEST_F(PermissionsTest, DefaultAnyAPIAccess) {
816  const struct {
817    const char* api_name;
818    bool expect_success;
819  } kTests[] = {
820    // Negative test.
821    { "non_existing_permission", false },
822    // Test default module/package permission.
823    { "browserAction",  true },
824    { "devtools",       true },
825    { "extension",      true },
826    { "i18n",           true },
827    { "pageAction",     true },
828    { "pageActions",    true },
829    { "test",           true },
830    // Some negative tests.
831    { "bookmarks",      false },
832    { "cookies",        false },
833    { "history",        false },
834    // Negative APIs that have positive individual functions.
835    { "management",     true},
836    { "tabs",           true},
837  };
838
839  scoped_refptr<PermissionSet> empty = new PermissionSet();
840  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
841    EXPECT_EQ(kTests[i].expect_success,
842              empty->HasAnyAccessToAPI(kTests[i].api_name));
843  }
844}
845
846TEST_F(PermissionsTest, GetWarningMessages_ManyHosts) {
847  scoped_refptr<Extension> extension;
848
849  extension = LoadManifest("permissions", "many-hosts.json");
850  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
851  ASSERT_EQ(1u, warnings.size());
852  EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
853            UTF16ToUTF8(warnings[0]));
854}
855
856TEST_F(PermissionsTest, GetWarningMessages_Plugins) {
857  scoped_refptr<Extension> extension;
858  scoped_refptr<PermissionSet> permissions;
859
860  extension = LoadManifest("permissions", "plugins.json");
861  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
862  // We don't parse the plugins key on Chrome OS, so it should not ask for any
863  // permissions.
864#if defined(OS_CHROMEOS)
865  ASSERT_EQ(0u, warnings.size());
866#else
867  ASSERT_EQ(1u, warnings.size());
868  EXPECT_EQ("Access all data on your computer and the websites you visit",
869            UTF16ToUTF8(warnings[0]));
870#endif
871}
872
873TEST_F(PermissionsTest, GetWarningMessages_AudioVideo) {
874  // Both audio and video present.
875  scoped_refptr<Extension> extension =
876      LoadManifest("permissions", "audio-video.json");
877  PermissionSet* set =
878      const_cast<PermissionSet*>(
879          extension->GetActivePermissions().get());
880  std::vector<string16> warnings =
881      set->GetWarningMessages(extension->GetType());
882  EXPECT_FALSE(Contains(warnings, "Use your microphone"));
883  EXPECT_FALSE(Contains(warnings, "Use your camera"));
884  EXPECT_TRUE(Contains(warnings, "Use your microphone and camera"));
885  size_t combined_index = IndexOf(warnings, "Use your microphone and camera");
886  size_t combined_size = warnings.size();
887
888  // Just audio present.
889  set->apis_.erase(APIPermission::kVideoCapture);
890  warnings = set->GetWarningMessages(extension->GetType());
891  EXPECT_EQ(combined_size, warnings.size());
892  EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone"));
893  EXPECT_FALSE(Contains(warnings, "Use your camera"));
894  EXPECT_FALSE(Contains(warnings, "Use your microphone and camera"));
895
896  // Just video present.
897  set->apis_.erase(APIPermission::kAudioCapture);
898  set->apis_.insert(APIPermission::kVideoCapture);
899  warnings = set->GetWarningMessages(extension->GetType());
900  EXPECT_EQ(combined_size, warnings.size());
901  EXPECT_FALSE(Contains(warnings, "Use your microphone"));
902  EXPECT_FALSE(Contains(warnings, "Use your microphone and camera"));
903  EXPECT_TRUE(Contains(warnings, "Use your camera"));
904}
905
906TEST_F(PermissionsTest, GetWarningMessages_Serial) {
907  scoped_refptr<Extension> extension =
908      LoadManifest("permissions", "serial.json");
909
910  EXPECT_TRUE(extension->is_platform_app());
911  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSerial));
912  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
913  EXPECT_TRUE(Contains(warnings,
914                       "Use serial devices attached to your computer"));
915  ASSERT_EQ(1u, warnings.size());
916}
917
918TEST_F(PermissionsTest, GetWarningMessages_Socket_AnyHost) {
919  Feature::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
920
921  scoped_refptr<Extension> extension =
922      LoadManifest("permissions", "socket_any_host.json");
923  EXPECT_TRUE(extension->is_platform_app());
924  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
925  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
926  EXPECT_EQ(1u, warnings.size());
927  EXPECT_TRUE(Contains(warnings, "Exchange data with any computer "
928                                 "on the local network or internet"));
929}
930
931TEST_F(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) {
932  Feature::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
933
934  scoped_refptr<Extension> extension =
935      LoadManifest("permissions", "socket_one_domain_two_hostnames.json");
936  EXPECT_TRUE(extension->is_platform_app());
937  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
938  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
939
940  // Verify the warnings, including support for unicode characters, the fact
941  // that domain host warnings come before specific host warnings, and the fact
942  // that domains and hostnames are in alphabetical order regardless of the
943  // order in the manifest file.
944  EXPECT_EQ(2u, warnings.size());
945  if (warnings.size() > 0)
946    EXPECT_EQ(warnings[0],
947              UTF8ToUTF16("Exchange data with any computer in the domain "
948                          "example.org"));
949  if (warnings.size() > 1)
950    EXPECT_EQ(warnings[1],
951              UTF8ToUTF16("Exchange data with the computers named: "
952                          "b\xC3\xA5r.example.com foo.example.com"));
953                          // "\xC3\xA5" = UTF-8 for lowercase A with ring above
954}
955
956TEST_F(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) {
957  Feature::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
958
959  scoped_refptr<Extension> extension =
960      LoadManifest("permissions", "socket_two_domains_one_hostname.json");
961  EXPECT_TRUE(extension->is_platform_app());
962  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
963  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
964
965  // Verify the warnings, including the fact that domain host warnings come
966  // before specific host warnings and the fact that domains and hostnames are
967  // in alphabetical order regardless of the order in the manifest file.
968  EXPECT_EQ(2u, warnings.size());
969  if (warnings.size() > 0)
970    EXPECT_EQ(warnings[0],
971              UTF8ToUTF16("Exchange data with any computer in the domains: "
972                           "example.com foo.example.org"));
973  if (warnings.size() > 1)
974    EXPECT_EQ(warnings[1],
975              UTF8ToUTF16("Exchange data with the computer named "
976                           "bar.example.org"));
977}
978
979TEST_F(PermissionsTest, GetWarningMessages_PlatformApppHosts) {
980  scoped_refptr<Extension> extension;
981
982  extension = LoadManifest("permissions", "platform_app_hosts.json");
983  EXPECT_TRUE(extension->is_platform_app());
984  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
985  ASSERT_EQ(0u, warnings.size());
986
987  extension = LoadManifest("permissions", "platform_app_all_urls.json");
988  EXPECT_TRUE(extension->is_platform_app());
989  warnings = extension->GetPermissionMessageStrings();
990  ASSERT_EQ(0u, warnings.size());
991}
992
993TEST_F(PermissionsTest, GetDistinctHostsForDisplay) {
994  scoped_refptr<PermissionSet> perm_set;
995  APIPermissionSet empty_perms;
996  std::set<std::string> expected;
997  expected.insert("www.foo.com");
998  expected.insert("www.bar.com");
999  expected.insert("www.baz.com");
1000  URLPatternSet explicit_hosts;
1001  URLPatternSet scriptable_hosts;
1002
1003  {
1004    SCOPED_TRACE("no dupes");
1005
1006    // Simple list with no dupes.
1007    explicit_hosts.AddPattern(
1008        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1009    explicit_hosts.AddPattern(
1010        URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path"));
1011    explicit_hosts.AddPattern(
1012        URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
1013    perm_set = new PermissionSet(
1014        empty_perms, explicit_hosts, scriptable_hosts);
1015    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1016  }
1017
1018  {
1019    SCOPED_TRACE("two dupes");
1020
1021    // Add some dupes.
1022    explicit_hosts.AddPattern(
1023        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1024    explicit_hosts.AddPattern(
1025        URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
1026    perm_set = new PermissionSet(
1027        empty_perms, explicit_hosts, scriptable_hosts);
1028    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1029  }
1030
1031  {
1032    SCOPED_TRACE("schemes differ");
1033
1034    // Add a pattern that differs only by scheme. This should be filtered out.
1035    explicit_hosts.AddPattern(
1036        URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path"));
1037    perm_set = new PermissionSet(
1038        empty_perms, explicit_hosts, scriptable_hosts);
1039    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1040  }
1041
1042  {
1043    SCOPED_TRACE("paths differ");
1044
1045    // Add some dupes by path.
1046    explicit_hosts.AddPattern(
1047        URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath"));
1048    perm_set = new PermissionSet(
1049        empty_perms, explicit_hosts, scriptable_hosts);
1050    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1051  }
1052
1053  {
1054    SCOPED_TRACE("subdomains differ");
1055
1056    // We don't do anything special for subdomains.
1057    explicit_hosts.AddPattern(
1058        URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path"));
1059    explicit_hosts.AddPattern(
1060        URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path"));
1061
1062    expected.insert("monkey.www.bar.com");
1063    expected.insert("bar.com");
1064
1065    perm_set = new PermissionSet(
1066        empty_perms, explicit_hosts, scriptable_hosts);
1067    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1068  }
1069
1070  {
1071    SCOPED_TRACE("RCDs differ");
1072
1073    // Now test for RCD uniquing.
1074    explicit_hosts.AddPattern(
1075        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1076    explicit_hosts.AddPattern(
1077        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1078    explicit_hosts.AddPattern(
1079        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path"));
1080    explicit_hosts.AddPattern(
1081        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path"));
1082    explicit_hosts.AddPattern(
1083        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1084    explicit_hosts.AddPattern(
1085        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path"));
1086
1087    // This is an unknown RCD, which shouldn't be uniqued out.
1088    explicit_hosts.AddPattern(
1089        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
1090    // But it should only occur once.
1091    explicit_hosts.AddPattern(
1092        URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
1093
1094    expected.insert("www.foo.xyzzy");
1095
1096    perm_set = new PermissionSet(
1097        empty_perms, explicit_hosts, scriptable_hosts);
1098    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1099  }
1100
1101  {
1102    SCOPED_TRACE("wildcards");
1103
1104    explicit_hosts.AddPattern(
1105        URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
1106
1107    expected.insert("*.google.com");
1108
1109    perm_set = new PermissionSet(
1110        empty_perms, explicit_hosts, scriptable_hosts);
1111    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1112  }
1113
1114  {
1115    SCOPED_TRACE("scriptable hosts");
1116    explicit_hosts.ClearPatterns();
1117    scriptable_hosts.ClearPatterns();
1118    expected.clear();
1119
1120    explicit_hosts.AddPattern(
1121        URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
1122    scriptable_hosts.AddPattern(
1123        URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*"));
1124
1125    expected.insert("*.google.com");
1126    expected.insert("*.example.com");
1127
1128    perm_set = new PermissionSet(
1129        empty_perms, explicit_hosts, scriptable_hosts);
1130    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1131  }
1132
1133  {
1134    // We don't display warnings for file URLs because they are off by default.
1135    SCOPED_TRACE("file urls");
1136    explicit_hosts.ClearPatterns();
1137    scriptable_hosts.ClearPatterns();
1138    expected.clear();
1139
1140    explicit_hosts.AddPattern(
1141        URLPattern(URLPattern::SCHEME_FILE, "file:///*"));
1142
1143    perm_set = new PermissionSet(
1144        empty_perms, explicit_hosts, scriptable_hosts);
1145    EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1146  }
1147}
1148
1149TEST_F(PermissionsTest, GetDistinctHostsForDisplay_ComIsBestRcd) {
1150  scoped_refptr<PermissionSet> perm_set;
1151  APIPermissionSet empty_perms;
1152  URLPatternSet explicit_hosts;
1153  URLPatternSet scriptable_hosts;
1154  explicit_hosts.AddPattern(
1155      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1156  explicit_hosts.AddPattern(
1157      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1158  explicit_hosts.AddPattern(
1159      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1160  explicit_hosts.AddPattern(
1161      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1162  explicit_hosts.AddPattern(
1163      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1164  explicit_hosts.AddPattern(
1165      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
1166
1167  std::set<std::string> expected;
1168  expected.insert("www.foo.com");
1169  perm_set = new PermissionSet(
1170      empty_perms, explicit_hosts, scriptable_hosts);
1171  EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1172}
1173
1174TEST_F(PermissionsTest, GetDistinctHostsForDisplay_NetIs2ndBestRcd) {
1175  scoped_refptr<PermissionSet> perm_set;
1176  APIPermissionSet empty_perms;
1177  URLPatternSet explicit_hosts;
1178  URLPatternSet scriptable_hosts;
1179  explicit_hosts.AddPattern(
1180      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1181  explicit_hosts.AddPattern(
1182      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1183  explicit_hosts.AddPattern(
1184      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1185  explicit_hosts.AddPattern(
1186      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
1187  explicit_hosts.AddPattern(
1188      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1189  // No http://www.foo.com/path
1190
1191  std::set<std::string> expected;
1192  expected.insert("www.foo.net");
1193  perm_set = new PermissionSet(
1194      empty_perms, explicit_hosts, scriptable_hosts);
1195  EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1196}
1197
1198TEST_F(PermissionsTest,
1199     GetDistinctHostsForDisplay_OrgIs3rdBestRcd) {
1200  scoped_refptr<PermissionSet> perm_set;
1201  APIPermissionSet empty_perms;
1202  URLPatternSet explicit_hosts;
1203  URLPatternSet scriptable_hosts;
1204  explicit_hosts.AddPattern(
1205      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1206  explicit_hosts.AddPattern(
1207      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
1208  explicit_hosts.AddPattern(
1209      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1210  // No http://www.foo.net/path
1211  explicit_hosts.AddPattern(
1212      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1213  // No http://www.foo.com/path
1214
1215  std::set<std::string> expected;
1216  expected.insert("www.foo.org");
1217  perm_set = new PermissionSet(
1218      empty_perms, explicit_hosts, scriptable_hosts);
1219  EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1220}
1221
1222TEST_F(PermissionsTest,
1223     GetDistinctHostsForDisplay_FirstInListIs4thBestRcd) {
1224  scoped_refptr<PermissionSet> perm_set;
1225  APIPermissionSet empty_perms;
1226  URLPatternSet explicit_hosts;
1227  URLPatternSet scriptable_hosts;
1228  explicit_hosts.AddPattern(
1229      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
1230  // No http://www.foo.org/path
1231  explicit_hosts.AddPattern(
1232      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
1233  // No http://www.foo.net/path
1234  explicit_hosts.AddPattern(
1235      URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
1236  // No http://www.foo.com/path
1237
1238  std::set<std::string> expected;
1239  expected.insert("www.foo.ca");
1240  perm_set = new PermissionSet(
1241      empty_perms, explicit_hosts, scriptable_hosts);
1242  EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay());
1243}
1244
1245TEST_F(PermissionsTest, HasLessHostPrivilegesThan) {
1246  URLPatternSet elist1;
1247  URLPatternSet elist2;
1248  URLPatternSet slist1;
1249  URLPatternSet slist2;
1250  scoped_refptr<PermissionSet> set1;
1251  scoped_refptr<PermissionSet> set2;
1252  APIPermissionSet empty_perms;
1253  elist1.AddPattern(
1254      URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
1255  elist1.AddPattern(
1256      URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1257
1258  // Test that the host order does not matter.
1259  elist2.AddPattern(
1260      URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1261  elist2.AddPattern(
1262      URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
1263
1264  set1 = new PermissionSet(empty_perms, elist1, slist1);
1265  set2 = new PermissionSet(empty_perms, elist2, slist2);
1266
1267  EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get()));
1268  EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get()));
1269
1270  // Test that paths are ignored.
1271  elist2.ClearPatterns();
1272  elist2.AddPattern(
1273      URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*"));
1274  set2 = new PermissionSet(empty_perms, elist2, slist2);
1275  EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get()));
1276  EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get()));
1277
1278  // Test that RCDs are ignored.
1279  elist2.ClearPatterns();
1280  elist2.AddPattern(
1281      URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*"));
1282  set2 = new PermissionSet(empty_perms, elist2, slist2);
1283  EXPECT_FALSE(set1->HasLessHostPrivilegesThan(set2.get()));
1284  EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get()));
1285
1286  // Test that subdomain wildcards are handled properly.
1287  elist2.ClearPatterns();
1288  elist2.AddPattern(
1289      URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*"));
1290  set2 = new PermissionSet(empty_perms, elist2, slist2);
1291  EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get()));
1292  // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337
1293  // EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get()));
1294
1295  // Test that different domains count as different hosts.
1296  elist2.ClearPatterns();
1297  elist2.AddPattern(
1298      URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
1299  elist2.AddPattern(
1300      URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path"));
1301  set2 = new PermissionSet(empty_perms, elist2, slist2);
1302  EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get()));
1303  EXPECT_FALSE(set2->HasLessHostPrivilegesThan(set1.get()));
1304
1305  // Test that different subdomains count as different hosts.
1306  elist2.ClearPatterns();
1307  elist2.AddPattern(
1308      URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*"));
1309  set2 = new PermissionSet(empty_perms, elist2, slist2);
1310  EXPECT_TRUE(set1->HasLessHostPrivilegesThan(set2.get()));
1311  EXPECT_TRUE(set2->HasLessHostPrivilegesThan(set1.get()));
1312}
1313
1314TEST_F(PermissionsTest, GetAPIsAsStrings) {
1315  APIPermissionSet apis;
1316  URLPatternSet empty_set;
1317
1318  apis.insert(APIPermission::kProxy);
1319  apis.insert(APIPermission::kBackground);
1320  apis.insert(APIPermission::kNotification);
1321  apis.insert(APIPermission::kTab);
1322
1323  scoped_refptr<PermissionSet> perm_set = new PermissionSet(
1324      apis, empty_set, empty_set);
1325  std::set<std::string> api_names = perm_set->GetAPIsAsStrings();
1326
1327  // The result is correct if it has the same number of elements
1328  // and we can convert it back to the id set.
1329  EXPECT_EQ(4u, api_names.size());
1330  EXPECT_EQ(apis,
1331            PermissionsInfo::GetInstance()->GetAllByName(api_names));
1332}
1333
1334TEST_F(PermissionsTest, IsEmpty) {
1335  APIPermissionSet empty_apis;
1336  URLPatternSet empty_extent;
1337
1338  scoped_refptr<PermissionSet> empty = new PermissionSet();
1339  EXPECT_TRUE(empty->IsEmpty());
1340  scoped_refptr<PermissionSet> perm_set;
1341
1342  perm_set = new PermissionSet(empty_apis, empty_extent, empty_extent);
1343  EXPECT_TRUE(perm_set->IsEmpty());
1344
1345  APIPermissionSet non_empty_apis;
1346  non_empty_apis.insert(APIPermission::kBackground);
1347  perm_set = new PermissionSet(
1348      non_empty_apis, empty_extent, empty_extent);
1349  EXPECT_FALSE(perm_set->IsEmpty());
1350
1351  // Try non standard host
1352  URLPatternSet non_empty_extent;
1353  AddPattern(&non_empty_extent, "http://www.google.com/*");
1354
1355  perm_set = new PermissionSet(
1356      empty_apis, non_empty_extent, empty_extent);
1357  EXPECT_FALSE(perm_set->IsEmpty());
1358
1359  perm_set = new PermissionSet(
1360      empty_apis, empty_extent, non_empty_extent);
1361  EXPECT_FALSE(perm_set->IsEmpty());
1362}
1363
1364TEST_F(PermissionsTest, ImpliedPermissions) {
1365  URLPatternSet empty_extent;
1366  APIPermissionSet apis;
1367  apis.insert(APIPermission::kWebRequest);
1368  apis.insert(APIPermission::kFileBrowserHandler);
1369  EXPECT_EQ(2U, apis.size());
1370
1371  scoped_refptr<PermissionSet> perm_set;
1372  perm_set = new PermissionSet(apis, empty_extent, empty_extent);
1373  EXPECT_EQ(4U, perm_set->apis().size());
1374}
1375
1376TEST_F(PermissionsTest, SyncFileSystemPermission) {
1377  scoped_refptr<Extension> extension = LoadManifest(
1378      "permissions", "sync_file_system.json");
1379  APIPermissionSet apis;
1380  apis.insert(APIPermission::kSyncFileSystem);
1381  EXPECT_TRUE(extension->is_platform_app());
1382  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSyncFileSystem));
1383  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
1384  EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account"));
1385  ASSERT_EQ(1u, warnings.size());
1386}
1387
1388}  // namespace extensions
1389