Home | History | Annotate | Download | only in permissions
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/scoped_ptr.h"
      6 #include "base/values.h"
      7 #include "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
      8 #include "chrome/common/extensions/api/permissions.h"
      9 #include "chrome/common/extensions/permissions/permission_set.h"
     10 #include "extensions/common/url_pattern_set.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "url/gurl.h"
     13 
     14 using extensions::api::permissions::Permissions;
     15 using extensions::permissions_api_helpers::PackPermissionSet;
     16 using extensions::permissions_api_helpers::UnpackPermissionSet;
     17 
     18 namespace extensions {
     19 
     20 namespace {
     21 
     22 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
     23   int schemes = URLPattern::SCHEME_ALL;
     24   extent->AddPattern(URLPattern(schemes, pattern));
     25 }
     26 
     27 }  // namespace
     28 
     29 // Tests that we can convert PermissionSets to and from values.
     30 TEST(ExtensionPermissionsAPIHelpers, Pack) {
     31   APIPermissionSet apis;
     32   apis.insert(APIPermission::kTab);
     33   apis.insert(APIPermission::kWebRequest);
     34   // Note: kWebRequest implies also kWebRequestInternal.
     35   URLPatternSet hosts;
     36   AddPattern(&hosts, "http://a.com/*");
     37   AddPattern(&hosts, "http://b.com/*");
     38 
     39   scoped_refptr<PermissionSet> permission_set =
     40       new PermissionSet(apis, hosts, URLPatternSet());
     41 
     42   // Pack the permission set to value and verify its contents.
     43   scoped_ptr<Permissions> permissions(PackPermissionSet(permission_set.get()));
     44   scoped_ptr<base::DictionaryValue> value(permissions->ToValue());
     45   base::ListValue* api_list = NULL;
     46   base::ListValue* origin_list = NULL;
     47   EXPECT_TRUE(value->GetList("permissions", &api_list));
     48   EXPECT_TRUE(value->GetList("origins", &origin_list));
     49 
     50   EXPECT_EQ(3u, api_list->GetSize());
     51   EXPECT_EQ(2u, origin_list->GetSize());
     52 
     53   std::string expected_apis[] = { "tabs", "webRequest" };
     54   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_apis); ++i) {
     55     scoped_ptr<Value> value(Value::CreateStringValue(expected_apis[i]));
     56     EXPECT_NE(api_list->end(), api_list->Find(*value));
     57   }
     58 
     59   std::string expected_origins[] = { "http://a.com/*", "http://b.com/*" };
     60   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_origins); ++i) {
     61     scoped_ptr<Value> value(Value::CreateStringValue(expected_origins[i]));
     62     EXPECT_NE(origin_list->end(), origin_list->Find(*value));
     63   }
     64 
     65   // Unpack the value back to a permission set and make sure its equal to the
     66   // original one.
     67   scoped_refptr<PermissionSet> from_value;
     68   std::string error;
     69   Permissions permissions_object;
     70   EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
     71   from_value = UnpackPermissionSet(permissions_object, true, &error);
     72   EXPECT_TRUE(error.empty());
     73 
     74   EXPECT_EQ(*permission_set.get(), *from_value.get());
     75 }
     76 
     77 // Tests various error conditions and edge cases when unpacking values
     78 // into PermissionSets.
     79 TEST(ExtensionPermissionsAPIHelpers, Unpack) {
     80   scoped_ptr<base::ListValue> apis(new base::ListValue());
     81   apis->Append(Value::CreateStringValue("tabs"));
     82   scoped_ptr<base::ListValue> origins(new base::ListValue());
     83   origins->Append(Value::CreateStringValue("http://a.com/*"));
     84 
     85   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
     86   scoped_refptr<PermissionSet> permissions;
     87   std::string error;
     88 
     89   // Origins shouldn't have to be present.
     90   {
     91     Permissions permissions_object;
     92     value->Set("permissions", apis->DeepCopy());
     93     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
     94     permissions = UnpackPermissionSet(permissions_object, true, &error);
     95     EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kTab));
     96     EXPECT_TRUE(permissions.get());
     97     EXPECT_TRUE(error.empty());
     98   }
     99 
    100   // The api permissions don't need to be present either.
    101   {
    102     Permissions permissions_object;
    103     value->Clear();
    104     value->Set("origins", origins->DeepCopy());
    105     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    106     permissions = UnpackPermissionSet(permissions_object, true, &error);
    107     EXPECT_TRUE(permissions.get());
    108     EXPECT_TRUE(error.empty());
    109     EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
    110   }
    111 
    112   // Throw errors for non-string API permissions.
    113   {
    114     Permissions permissions_object;
    115     value->Clear();
    116     scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    117     invalid_apis->Append(Value::CreateIntegerValue(3));
    118     value->Set("permissions", invalid_apis->DeepCopy());
    119     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    120   }
    121 
    122   // Throw errors for non-string origins.
    123   {
    124     Permissions permissions_object;
    125     value->Clear();
    126     scoped_ptr<base::ListValue> invalid_origins(origins->DeepCopy());
    127     invalid_origins->Append(Value::CreateIntegerValue(3));
    128     value->Set("origins", invalid_origins->DeepCopy());
    129     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    130   }
    131 
    132   // Throw errors when "origins" or "permissions" are not list values.
    133   {
    134     Permissions permissions_object;
    135     value->Clear();
    136     value->Set("origins", Value::CreateIntegerValue(2));
    137     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    138   }
    139 
    140   {
    141     Permissions permissions_object;
    142     value->Clear();
    143     value->Set("permissions", Value::CreateIntegerValue(2));
    144     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    145   }
    146 
    147   // Additional fields should be allowed.
    148   {
    149     Permissions permissions_object;
    150     value->Clear();
    151     value->Set("origins", origins->DeepCopy());
    152     value->Set("random", Value::CreateIntegerValue(3));
    153     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    154     permissions = UnpackPermissionSet(permissions_object, true, &error);
    155     EXPECT_TRUE(permissions.get());
    156     EXPECT_TRUE(error.empty());
    157     EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
    158   }
    159 
    160   // Unknown permissions should throw an error.
    161   {
    162     Permissions permissions_object;
    163     value->Clear();
    164     scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    165     invalid_apis->Append(Value::CreateStringValue("unknown_permission"));
    166     value->Set("permissions", invalid_apis->DeepCopy());
    167     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    168     permissions = UnpackPermissionSet(permissions_object, true, &error);
    169     EXPECT_FALSE(permissions.get());
    170     EXPECT_FALSE(error.empty());
    171     EXPECT_EQ(error, "'unknown_permission' is not a recognized permission.");
    172   }
    173 }
    174 
    175 }  // namespace extensions
    176