summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
blob: 4ac1b8118741963108bd560f0a4d683e1258f40e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
#include "chrome/common/extensions/api/permissions.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/url_pattern_set.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using extensions::api::permissions::Permissions;
using extensions::permissions_api_helpers::PackPermissionSet;
using extensions::permissions_api_helpers::UnpackPermissionSet;

namespace extensions {

namespace {

static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
  int schemes = URLPattern::SCHEME_ALL;
  extent->AddPattern(URLPattern(schemes, pattern));
}

}  // namespace

// Tests that we can convert PermissionSets to and from values.
TEST(ExtensionPermissionsAPIHelpers, Pack) {
  APIPermissionSet apis;
  apis.insert(APIPermission::kTab);
  apis.insert(APIPermission::kWebRequest);
  // Note: kWebRequest implies also kWebRequestInternal.
  URLPatternSet hosts;
  AddPattern(&hosts, "http://a.com/*");
  AddPattern(&hosts, "http://b.com/*");

  scoped_refptr<PermissionSet> permission_set =
      new PermissionSet(apis, ManifestPermissionSet(), hosts, URLPatternSet());

  // Pack the permission set to value and verify its contents.
  scoped_ptr<Permissions> permissions(PackPermissionSet(permission_set.get()));
  scoped_ptr<base::DictionaryValue> value(permissions->ToValue());
  base::ListValue* api_list = NULL;
  base::ListValue* origin_list = NULL;
  EXPECT_TRUE(value->GetList("permissions", &api_list));
  EXPECT_TRUE(value->GetList("origins", &origin_list));

  EXPECT_EQ(3u, api_list->GetSize());
  EXPECT_EQ(2u, origin_list->GetSize());

  std::string expected_apis[] = { "tabs", "webRequest" };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_apis); ++i) {
    scoped_ptr<Value> value(new base::StringValue(expected_apis[i]));
    EXPECT_NE(api_list->end(), api_list->Find(*value));
  }

  std::string expected_origins[] = { "http://a.com/*", "http://b.com/*" };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_origins); ++i) {
    scoped_ptr<Value> value(new base::StringValue(expected_origins[i]));
    EXPECT_NE(origin_list->end(), origin_list->Find(*value));
  }

  // Unpack the value back to a permission set and make sure its equal to the
  // original one.
  scoped_refptr<PermissionSet> from_value;
  std::string error;
  Permissions permissions_object;
  EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
  from_value = UnpackPermissionSet(permissions_object, true, &error);
  EXPECT_TRUE(error.empty());

  EXPECT_EQ(*permission_set.get(), *from_value.get());
}

// Tests various error conditions and edge cases when unpacking values
// into PermissionSets.
TEST(ExtensionPermissionsAPIHelpers, Unpack) {
  scoped_ptr<base::ListValue> apis(new base::ListValue());
  apis->Append(new base::StringValue("tabs"));
  scoped_ptr<base::ListValue> origins(new base::ListValue());
  origins->Append(new base::StringValue("http://a.com/*"));

  scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
  scoped_refptr<PermissionSet> permissions;
  std::string error;

  // Origins shouldn't have to be present.
  {
    Permissions permissions_object;
    value->Set("permissions", apis->DeepCopy());
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kTab));
    EXPECT_TRUE(permissions.get());
    EXPECT_TRUE(error.empty());
  }

  // The api permissions don't need to be present either.
  {
    Permissions permissions_object;
    value->Clear();
    value->Set("origins", origins->DeepCopy());
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_TRUE(permissions.get());
    EXPECT_TRUE(error.empty());
    EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
  }

  // Throw errors for non-string API permissions.
  {
    Permissions permissions_object;
    value->Clear();
    scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    invalid_apis->Append(new base::FundamentalValue(3));
    value->Set("permissions", invalid_apis->DeepCopy());
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  // Throw errors for non-string origins.
  {
    Permissions permissions_object;
    value->Clear();
    scoped_ptr<base::ListValue> invalid_origins(origins->DeepCopy());
    invalid_origins->Append(new base::FundamentalValue(3));
    value->Set("origins", invalid_origins->DeepCopy());
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  // Throw errors when "origins" or "permissions" are not list values.
  {
    Permissions permissions_object;
    value->Clear();
    value->Set("origins", new base::FundamentalValue(2));
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  {
    Permissions permissions_object;
    value->Clear();
    value->Set("permissions", new base::FundamentalValue(2));
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  // Additional fields should be allowed.
  {
    Permissions permissions_object;
    value->Clear();
    value->Set("origins", origins->DeepCopy());
    value->Set("random", new base::FundamentalValue(3));
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_TRUE(permissions.get());
    EXPECT_TRUE(error.empty());
    EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
  }

  // Unknown permissions should throw an error.
  {
    Permissions permissions_object;
    value->Clear();
    scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    invalid_apis->Append(new base::StringValue("unknown_permission"));
    value->Set("permissions", invalid_apis->DeepCopy());
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_FALSE(permissions.get());
    EXPECT_FALSE(error.empty());
    EXPECT_EQ(error, "'unknown_permission' is not a recognized permission.");
  }
}

}  // namespace extensions