1 // Copyright 2016 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 "components/crx_file/id_util.h"
6 #include "extensions/common/extension.h"
7 #include "extensions/common/extension_builder.h"
8 #include "extensions/common/extension_messages.h"
9 #include "extensions/common/manifest_handlers/permissions_parser.h"
10 #include "extensions/common/permissions/extensions_api_permissions.h"
11 #include "extensions/common/permissions/permissions_data.h"
12 #include "extensions/common/value_builder.h"
13 #include "ipc/ipc_message.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace extensions {
17
18 namespace {
19
CompareExtension(const Extension & extension1,const Extension & extension2)20 void CompareExtension(const Extension& extension1,
21 const Extension& extension2) {
22 EXPECT_EQ(extension1.name(), extension2.name());
23 EXPECT_EQ(extension1.id(), extension2.id());
24 EXPECT_EQ(extension1.path(), extension2.path());
25 EXPECT_EQ(extension1.permissions_data()->active_permissions(),
26 extension2.permissions_data()->active_permissions());
27 EXPECT_TRUE(extension1.manifest()->Equals(extension2.manifest()));
28 const PermissionsData::TabPermissionsMap& second_tab_permissions =
29 extension2.permissions_data()->tab_specific_permissions();
30 for (const auto& tab_permissions :
31 extension1.permissions_data()->tab_specific_permissions()) {
32 ASSERT_NE(0u, second_tab_permissions.count(tab_permissions.first));
33 EXPECT_EQ(*tab_permissions.second,
34 *(second_tab_permissions.at(tab_permissions.first)))
35 << tab_permissions.first;
36 }
37 EXPECT_EQ(extension1.permissions_data()->policy_blocked_hosts(),
38 extension2.permissions_data()->policy_blocked_hosts());
39 EXPECT_EQ(extension1.permissions_data()->policy_allowed_hosts(),
40 extension2.permissions_data()->policy_allowed_hosts());
41 }
42
AddPattern(const std::string & pattern,URLPatternSet * extent)43 void AddPattern(const std::string& pattern, URLPatternSet* extent) {
44 URLPattern parsed(URLPattern::SCHEME_ALL);
45 parsed.Parse(pattern);
46 extent->AddPattern(parsed);
47 }
48
49 } // namespace
50
TEST(ExtensionMessageTypesTest,TestLoadedParams)51 TEST(ExtensionMessageTypesTest, TestLoadedParams) {
52 std::unique_ptr<base::DictionaryValue> manifest =
53 DictionaryBuilder()
54 .Set("name", "extension")
55 .Set("description", "an extension")
56 .Set("permissions", ListBuilder().Append("alarms").Build())
57 .Set("manifest_version", 2)
58 .Set("version", "0.1")
59 .Build();
60 scoped_refptr<const Extension> extension =
61 ExtensionBuilder()
62 .SetManifest(std::move(manifest))
63 .SetID(crx_file::id_util::GenerateId("foo"))
64 .Build();
65 const PermissionSet& required_permissions =
66 PermissionsParser::GetRequiredPermissions(extension.get());
67 LOG(WARNING) << required_permissions.apis().size();
68 EXPECT_TRUE(
69 extension->permissions_data()->HasAPIPermission(APIPermission::kAlarms));
70 {
71 APIPermissionSet tab_permissions;
72 tab_permissions.insert(APIPermission::kDns);
73 extension->permissions_data()->UpdateTabSpecificPermissions(
74 1, PermissionSet(std::move(tab_permissions), ManifestPermissionSet(),
75 URLPatternSet(), URLPatternSet()));
76 }
77 URLPatternSet runtime_blocked_hosts;
78 AddPattern("*://*.example.com/*", &runtime_blocked_hosts);
79 URLPatternSet runtime_allowed_hosts;
80 AddPattern("*://good.example.com/*", &runtime_allowed_hosts);
81 extension->permissions_data()->SetPolicyHostRestrictions(
82 runtime_blocked_hosts, runtime_allowed_hosts);
83
84 ExtensionMsg_Loaded_Params params_in(extension.get(), true, base::nullopt);
85 EXPECT_EQ(extension->id(), params_in.id);
86
87 {
88 // First, test just converting back to an extension.
89 std::string error;
90 // TODO(devlin): Move this to a renderer-specific location in order to
91 // better enforce this restriction.
92
93 // The logic is only called in the render context that's why it's
94 // safe to pass 0 as context_id.
95 scoped_refptr<const Extension> extension_out =
96 params_in.ConvertToExtension(0, &error);
97 EXPECT_TRUE(error.empty());
98 ASSERT_TRUE(extension_out);
99 CompareExtension(*extension, *extension_out);
100 }
101
102 {
103 // Second, try bouncing the params and then converting back.
104 IPC::Message msg;
105 IPC::ParamTraits<ExtensionMsg_Loaded_Params>::Write(&msg, params_in);
106 ExtensionMsg_Loaded_Params params_out;
107 base::PickleIterator iter(msg);
108 EXPECT_TRUE(IPC::ParamTraits<ExtensionMsg_Loaded_Params>::Read(
109 &msg, &iter, ¶ms_out));
110
111 EXPECT_EQ(params_in.id, params_out.id);
112 EXPECT_TRUE(params_in.manifest.Equals(¶ms_out.manifest));
113 EXPECT_EQ(params_in.location, params_out.location);
114 EXPECT_EQ(params_in.path, params_out.path);
115 EXPECT_EQ(params_in.creation_flags, params_out.creation_flags);
116 // Permission equaliy on the params will be tested through the conversion to
117 // an extension.
118
119 std::string error;
120 scoped_refptr<const Extension> extension_out =
121 params_out.ConvertToExtension(0, &error);
122 EXPECT_TRUE(error.empty());
123 ASSERT_TRUE(extension_out);
124 CompareExtension(*extension, *extension_out);
125 }
126 }
127
128 } // namespace extensions
129