1// Copyright 2013 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/pickle.h" 6#include "base/values.h" 7#include "extensions/common/extension_messages.h" 8#include "extensions/common/permissions/api_permission_set.h" 9#include "extensions/common/permissions/permissions_info.h" 10#include "ipc/ipc_message.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13namespace extensions { 14 15TEST(APIPermissionSetTest, General) { 16 APIPermissionSet apis; 17 apis.insert(APIPermission::kTab); 18 apis.insert(APIPermission::kBackground); 19 apis.insert(APIPermission::kProxy); 20 apis.insert(APIPermission::kClipboardWrite); 21 apis.insert(APIPermission::kPlugin); 22 23 EXPECT_EQ(apis.find(APIPermission::kProxy)->id(), APIPermission::kProxy); 24 EXPECT_TRUE(apis.find(APIPermission::kSocket) == apis.end()); 25 26 EXPECT_EQ(apis.size(), 5u); 27 28 EXPECT_EQ(apis.erase(APIPermission::kTab), 1u); 29 EXPECT_EQ(apis.size(), 4u); 30 31 EXPECT_EQ(apis.erase(APIPermission::kTab), 0u); 32 EXPECT_EQ(apis.size(), 4u); 33} 34 35TEST(APIPermissionSetTest, CreateUnion) { 36 APIPermission* permission = NULL; 37 38 APIPermissionSet apis1; 39 APIPermissionSet apis2; 40 APIPermissionSet expected_apis; 41 APIPermissionSet result; 42 43 const APIPermissionInfo* permission_info = 44 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 45 permission = permission_info->CreateAPIPermission(); 46 { 47 scoped_ptr<base::ListValue> value(new base::ListValue()); 48 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 49 value->Append(new base::StringValue("udp-bind::8080")); 50 value->Append(new base::StringValue("udp-send-to::8888")); 51 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 52 } 53 54 // Union with an empty set. 55 apis1.insert(APIPermission::kTab); 56 apis1.insert(APIPermission::kBackground); 57 apis1.insert(permission->Clone()); 58 expected_apis.insert(APIPermission::kTab); 59 expected_apis.insert(APIPermission::kBackground); 60 expected_apis.insert(permission); 61 62 APIPermissionSet::Union(apis1, apis2, &result); 63 64 EXPECT_TRUE(apis1.Contains(apis2)); 65 EXPECT_TRUE(apis1.Contains(result)); 66 EXPECT_FALSE(apis2.Contains(apis1)); 67 EXPECT_FALSE(apis2.Contains(result)); 68 EXPECT_TRUE(result.Contains(apis1)); 69 EXPECT_TRUE(result.Contains(apis2)); 70 71 EXPECT_EQ(expected_apis, result); 72 73 // Now use a real second set. 74 apis2.insert(APIPermission::kTab); 75 apis2.insert(APIPermission::kProxy); 76 apis2.insert(APIPermission::kClipboardWrite); 77 apis2.insert(APIPermission::kPlugin); 78 79 permission = permission_info->CreateAPIPermission(); 80 { 81 scoped_ptr<base::ListValue> value(new base::ListValue()); 82 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 83 value->Append(new base::StringValue("udp-send-to::8899")); 84 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 85 } 86 apis2.insert(permission); 87 88 expected_apis.insert(APIPermission::kTab); 89 expected_apis.insert(APIPermission::kProxy); 90 expected_apis.insert(APIPermission::kClipboardWrite); 91 expected_apis.insert(APIPermission::kPlugin); 92 93 permission = permission_info->CreateAPIPermission(); 94 { 95 scoped_ptr<base::ListValue> value(new base::ListValue()); 96 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 97 value->Append(new base::StringValue("udp-bind::8080")); 98 value->Append(new base::StringValue("udp-send-to::8888")); 99 value->Append(new base::StringValue("udp-send-to::8899")); 100 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 101 } 102 // Insert a new socket permission which will replace the old one. 103 expected_apis.insert(permission); 104 105 APIPermissionSet::Union(apis1, apis2, &result); 106 107 EXPECT_FALSE(apis1.Contains(apis2)); 108 EXPECT_FALSE(apis1.Contains(result)); 109 EXPECT_FALSE(apis2.Contains(apis1)); 110 EXPECT_FALSE(apis2.Contains(result)); 111 EXPECT_TRUE(result.Contains(apis1)); 112 EXPECT_TRUE(result.Contains(apis2)); 113 114 EXPECT_EQ(expected_apis, result); 115} 116 117TEST(APIPermissionSetTest, CreateIntersection) { 118 APIPermission* permission = NULL; 119 120 APIPermissionSet apis1; 121 APIPermissionSet apis2; 122 APIPermissionSet expected_apis; 123 APIPermissionSet result; 124 125 const APIPermissionInfo* permission_info = 126 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 127 128 // Intersection with an empty set. 129 apis1.insert(APIPermission::kTab); 130 apis1.insert(APIPermission::kBackground); 131 permission = permission_info->CreateAPIPermission(); 132 { 133 scoped_ptr<base::ListValue> value(new base::ListValue()); 134 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 135 value->Append(new base::StringValue("udp-bind::8080")); 136 value->Append(new base::StringValue("udp-send-to::8888")); 137 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 138 } 139 apis1.insert(permission); 140 141 APIPermissionSet::Intersection(apis1, apis2, &result); 142 EXPECT_TRUE(apis1.Contains(result)); 143 EXPECT_TRUE(apis2.Contains(result)); 144 EXPECT_TRUE(apis1.Contains(apis2)); 145 EXPECT_FALSE(apis2.Contains(apis1)); 146 EXPECT_FALSE(result.Contains(apis1)); 147 EXPECT_TRUE(result.Contains(apis2)); 148 149 EXPECT_TRUE(result.empty()); 150 EXPECT_EQ(expected_apis, result); 151 152 // Now use a real second set. 153 apis2.insert(APIPermission::kTab); 154 apis2.insert(APIPermission::kProxy); 155 apis2.insert(APIPermission::kClipboardWrite); 156 apis2.insert(APIPermission::kPlugin); 157 permission = permission_info->CreateAPIPermission(); 158 { 159 scoped_ptr<base::ListValue> value(new base::ListValue()); 160 value->Append(new base::StringValue("udp-bind::8080")); 161 value->Append(new base::StringValue("udp-send-to::8888")); 162 value->Append(new base::StringValue("udp-send-to::8899")); 163 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 164 } 165 apis2.insert(permission); 166 167 expected_apis.insert(APIPermission::kTab); 168 permission = permission_info->CreateAPIPermission(); 169 { 170 scoped_ptr<base::ListValue> value(new base::ListValue()); 171 value->Append(new base::StringValue("udp-bind::8080")); 172 value->Append(new base::StringValue("udp-send-to::8888")); 173 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 174 } 175 expected_apis.insert(permission); 176 177 APIPermissionSet::Intersection(apis1, apis2, &result); 178 179 EXPECT_TRUE(apis1.Contains(result)); 180 EXPECT_TRUE(apis2.Contains(result)); 181 EXPECT_FALSE(apis1.Contains(apis2)); 182 EXPECT_FALSE(apis2.Contains(apis1)); 183 EXPECT_FALSE(result.Contains(apis1)); 184 EXPECT_FALSE(result.Contains(apis2)); 185 186 EXPECT_EQ(expected_apis, result); 187} 188 189TEST(APIPermissionSetTest, CreateDifference) { 190 APIPermission* permission = NULL; 191 192 APIPermissionSet apis1; 193 APIPermissionSet apis2; 194 APIPermissionSet expected_apis; 195 APIPermissionSet result; 196 197 const APIPermissionInfo* permission_info = 198 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 199 200 // Difference with an empty set. 201 apis1.insert(APIPermission::kTab); 202 apis1.insert(APIPermission::kBackground); 203 permission = permission_info->CreateAPIPermission(); 204 { 205 scoped_ptr<base::ListValue> value(new base::ListValue()); 206 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 207 value->Append(new base::StringValue("udp-bind::8080")); 208 value->Append(new base::StringValue("udp-send-to::8888")); 209 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 210 } 211 apis1.insert(permission); 212 213 APIPermissionSet::Difference(apis1, apis2, &result); 214 215 EXPECT_EQ(apis1, result); 216 217 // Now use a real second set. 218 apis2.insert(APIPermission::kTab); 219 apis2.insert(APIPermission::kProxy); 220 apis2.insert(APIPermission::kClipboardWrite); 221 apis2.insert(APIPermission::kPlugin); 222 permission = permission_info->CreateAPIPermission(); 223 { 224 scoped_ptr<base::ListValue> value(new base::ListValue()); 225 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 226 value->Append(new base::StringValue("udp-send-to::8899")); 227 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 228 } 229 apis2.insert(permission); 230 231 expected_apis.insert(APIPermission::kBackground); 232 permission = permission_info->CreateAPIPermission(); 233 { 234 scoped_ptr<base::ListValue> value(new base::ListValue()); 235 value->Append(new base::StringValue("udp-bind::8080")); 236 value->Append(new base::StringValue("udp-send-to::8888")); 237 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 238 } 239 expected_apis.insert(permission); 240 241 APIPermissionSet::Difference(apis1, apis2, &result); 242 243 EXPECT_TRUE(apis1.Contains(result)); 244 EXPECT_FALSE(apis2.Contains(result)); 245 246 EXPECT_EQ(expected_apis, result); 247 248 // |result| = |apis1| - |apis2| --> |result| intersect |apis2| == empty_set 249 APIPermissionSet result2; 250 APIPermissionSet::Intersection(result, apis2, &result2); 251 EXPECT_TRUE(result2.empty()); 252} 253 254TEST(APIPermissionSetTest, IPC) { 255 APIPermission* permission = NULL; 256 257 APIPermissionSet apis; 258 APIPermissionSet expected_apis; 259 260 const APIPermissionInfo* permission_info = 261 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 262 263 apis.insert(APIPermission::kTab); 264 apis.insert(APIPermission::kBackground); 265 permission = permission_info->CreateAPIPermission(); 266 { 267 scoped_ptr<base::ListValue> value(new base::ListValue()); 268 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 269 value->Append(new base::StringValue("udp-bind::8080")); 270 value->Append(new base::StringValue("udp-send-to::8888")); 271 ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL)); 272 } 273 apis.insert(permission); 274 275 EXPECT_NE(apis, expected_apis); 276 277 IPC::Message m; 278 WriteParam(&m, apis); 279 PickleIterator iter(m); 280 CHECK(ReadParam(&m, &iter, &expected_apis)); 281 EXPECT_EQ(apis, expected_apis); 282} 283 284TEST(APIPermissionSetTest, ImplicitPermissions) { 285 APIPermissionSet apis; 286 apis.insert(APIPermission::kFileSystemWrite); 287 apis.AddImpliedPermissions(); 288 289 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(), 290 APIPermission::kFileSystemWrite); 291 EXPECT_EQ(apis.size(), 1u); 292 293 apis.erase(APIPermission::kFileSystemWrite); 294 apis.insert(APIPermission::kFileSystemDirectory); 295 apis.AddImpliedPermissions(); 296 297 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(), 298 APIPermission::kFileSystemDirectory); 299 EXPECT_EQ(apis.size(), 1u); 300 301 apis.insert(APIPermission::kFileSystemWrite); 302 apis.AddImpliedPermissions(); 303 304 EXPECT_EQ(apis.find(APIPermission::kFileSystemWrite)->id(), 305 APIPermission::kFileSystemWrite); 306 EXPECT_EQ(apis.find(APIPermission::kFileSystemDirectory)->id(), 307 APIPermission::kFileSystemDirectory); 308 EXPECT_EQ(apis.find(APIPermission::kFileSystemWriteDirectory)->id(), 309 APIPermission::kFileSystemWriteDirectory); 310 EXPECT_EQ(apis.size(), 3u); 311} 312 313} // namespace extensions 314