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.
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"
14 using extensions::api::permissions::Permissions
;
15 using extensions::permissions_api_helpers::PackPermissionSet
;
16 using extensions::permissions_api_helpers::UnpackPermissionSet
;
18 namespace extensions
{
22 static void AddPattern(URLPatternSet
* extent
, const std::string
& pattern
) {
23 int schemes
= URLPattern::SCHEME_ALL
;
24 extent
->AddPattern(URLPattern(schemes
, pattern
));
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.
36 AddPattern(&hosts
, "http://a.com/*");
37 AddPattern(&hosts
, "http://b.com/*");
39 scoped_refptr
<const PermissionSet
> permission_set
=
40 new PermissionSet(apis
, ManifestPermissionSet(), hosts
, URLPatternSet());
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
));
50 EXPECT_EQ(3u, api_list
->GetSize());
51 EXPECT_EQ(2u, origin_list
->GetSize());
53 std::string expected_apis
[] = {"tabs", "fileBrowserHandler",
54 "fileBrowserHandlerInternal"};
55 for (size_t i
= 0; i
< arraysize(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
));
60 std::string expected_origins
[] = { "http://a.com/*", "http://b.com/*" };
61 for (size_t i
= 0; i
< arraysize(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
));
66 // Unpack the value back to a permission set and make sure its equal to the
68 scoped_refptr
<const PermissionSet
> from_value
;
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());
75 EXPECT_EQ(*permission_set
.get(), *from_value
.get());
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/*"));
86 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
87 scoped_refptr
<const PermissionSet
> permissions
;
90 // Origins shouldn't have to be present.
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());
101 // The api permissions don't need to be present either.
103 Permissions permissions_object
;
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/")));
113 // Throw errors for non-string API permissions.
115 Permissions permissions_object
;
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
));
123 // Throw errors for non-string origins.
125 Permissions permissions_object
;
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
));
133 // Throw errors when "origins" or "permissions" are not list values.
135 Permissions permissions_object
;
137 value
->Set("origins", new base::FundamentalValue(2));
138 EXPECT_FALSE(Permissions::Populate(*value
, &permissions_object
));
142 Permissions permissions_object
;
144 value
->Set("permissions", new base::FundamentalValue(2));
145 EXPECT_FALSE(Permissions::Populate(*value
, &permissions_object
));
148 // Additional fields should be allowed.
150 Permissions permissions_object
;
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/")));
161 // Unknown permissions should throw an error.
163 Permissions permissions_object
;
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.");
176 } // namespace extensions