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 "extensions/common/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::kFileBrowserHandler);
     34   // Note: kFileBrowserHandler implies kFileBrowserHandlerInternal.
     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, ManifestPermissionSet(), 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", "fileBrowserHandler",
     54                                  "fileBrowserHandlerInternal"};
     55   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_apis); ++i) {
     56     scoped_ptr<base::Value> value(new base::StringValue(expected_apis[i]));
     57     EXPECT_NE(api_list->end(), api_list->Find(*value));
     58   }
     59 
     60   std::string expected_origins[] = { "http://a.com/*", "http://b.com/*" };
     61   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_origins); ++i) {
     62     scoped_ptr<base::Value> value(new base::StringValue(expected_origins[i]));
     63     EXPECT_NE(origin_list->end(), origin_list->Find(*value));
     64   }
     65 
     66   // Unpack the value back to a permission set and make sure its equal to the
     67   // original one.
     68   scoped_refptr<PermissionSet> from_value;
     69   std::string error;
     70   Permissions permissions_object;
     71   EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
     72   from_value = UnpackPermissionSet(permissions_object, true, &error);
     73   EXPECT_TRUE(error.empty());
     74 
     75   EXPECT_EQ(*permission_set.get(), *from_value.get());
     76 }
     77 
     78 // Tests various error conditions and edge cases when unpacking values
     79 // into PermissionSets.
     80 TEST(ExtensionPermissionsAPIHelpers, Unpack) {
     81   scoped_ptr<base::ListValue> apis(new base::ListValue());
     82   apis->Append(new base::StringValue("tabs"));
     83   scoped_ptr<base::ListValue> origins(new base::ListValue());
     84   origins->Append(new base::StringValue("http://a.com/*"));
     85 
     86   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
     87   scoped_refptr<PermissionSet> permissions;
     88   std::string error;
     89 
     90   // Origins shouldn't have to be present.
     91   {
     92     Permissions permissions_object;
     93     value->Set("permissions", apis->DeepCopy());
     94     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
     95     permissions = UnpackPermissionSet(permissions_object, true, &error);
     96     EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kTab));
     97     EXPECT_TRUE(permissions.get());
     98     EXPECT_TRUE(error.empty());
     99   }
    100 
    101   // The api permissions don't need to be present either.
    102   {
    103     Permissions permissions_object;
    104     value->Clear();
    105     value->Set("origins", origins->DeepCopy());
    106     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    107     permissions = UnpackPermissionSet(permissions_object, true, &error);
    108     EXPECT_TRUE(permissions.get());
    109     EXPECT_TRUE(error.empty());
    110     EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
    111   }
    112 
    113   // Throw errors for non-string API permissions.
    114   {
    115     Permissions permissions_object;
    116     value->Clear();
    117     scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    118     invalid_apis->Append(new base::FundamentalValue(3));
    119     value->Set("permissions", invalid_apis->DeepCopy());
    120     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    121   }
    122 
    123   // Throw errors for non-string origins.
    124   {
    125     Permissions permissions_object;
    126     value->Clear();
    127     scoped_ptr<base::ListValue> invalid_origins(origins->DeepCopy());
    128     invalid_origins->Append(new base::FundamentalValue(3));
    129     value->Set("origins", invalid_origins->DeepCopy());
    130     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    131   }
    132 
    133   // Throw errors when "origins" or "permissions" are not list values.
    134   {
    135     Permissions permissions_object;
    136     value->Clear();
    137     value->Set("origins", new base::FundamentalValue(2));
    138     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    139   }
    140 
    141   {
    142     Permissions permissions_object;
    143     value->Clear();
    144     value->Set("permissions", new base::FundamentalValue(2));
    145     EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
    146   }
    147 
    148   // Additional fields should be allowed.
    149   {
    150     Permissions permissions_object;
    151     value->Clear();
    152     value->Set("origins", origins->DeepCopy());
    153     value->Set("random", new base::FundamentalValue(3));
    154     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    155     permissions = UnpackPermissionSet(permissions_object, true, &error);
    156     EXPECT_TRUE(permissions.get());
    157     EXPECT_TRUE(error.empty());
    158     EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
    159   }
    160 
    161   // Unknown permissions should throw an error.
    162   {
    163     Permissions permissions_object;
    164     value->Clear();
    165     scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    166     invalid_apis->Append(new base::StringValue("unknown_permission"));
    167     value->Set("permissions", invalid_apis->DeepCopy());
    168     EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    169     permissions = UnpackPermissionSet(permissions_object, true, &error);
    170     EXPECT_FALSE(permissions.get());
    171     EXPECT_FALSE(error.empty());
    172     EXPECT_EQ(error, "'unknown_permission' is not a recognized permission.");
    173   }
    174 }
    175 
    176 }  // namespace extensions
    177