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 "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h"
6
7#include <string>
8#include <vector>
9
10#include "base/files/file_path.h"
11#include "base/files/file_util.h"
12#include "base/files/scoped_temp_dir.h"
13#include "base/values.h"
14#include "components/version_info/version_info.h"
15#include "extensions/common/extension.h"
16#include "extensions/common/features/feature_channel.h"
17#include "extensions/common/file_util.h"
18#include "extensions/common/manifest.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21namespace extensions {
22
23class StorageSchemaManifestHandlerTest : public testing::Test {
24 public:
25 StorageSchemaManifestHandlerTest()
26 : scoped_channel_(version_info::Channel::DEV) {}
27
28 ~StorageSchemaManifestHandlerTest() override {}
29
30 void SetUp() override {
31 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
32
33 manifest_.SetString("name", "test");
34 manifest_.SetString("version", "1.2.3.4");
35 manifest_.SetInteger("manifest_version", 2);
36 }
37
38 scoped_refptr<Extension> CreateExtension(const std::string& schema) {
39 std::string error;
40 scoped_refptr<Extension> extension =
41 Extension::Create(temp_dir_.GetPath(), Manifest::UNPACKED, manifest_,
42 Extension::NO_FLAGS, "", &error);
43 if (!extension.get())
44 return NULL;
45 base::FilePath schema_path = temp_dir_.GetPath().AppendASCII("schema.json");
46 if (schema.empty()) {
47 base::DeleteFile(schema_path, false);
48 } else {
49 if (base::WriteFile(schema_path, schema.data(), schema.size()) !=
50 static_cast<int>(schema.size())) {
51 return NULL;
52 }
53 }
54 return extension;
55 }
56
57 testing::AssertionResult Validates(const std::string& schema) {
58 scoped_refptr<Extension> extension = CreateExtension(schema);
59 if (!extension.get())
60 return testing::AssertionFailure() << "Failed to create test extension";
61 std::string error;
62 std::vector<InstallWarning> warnings;
63 if (file_util::ValidateExtension(extension.get(), &error, &warnings))
64 return testing::AssertionSuccess();
65 return testing::AssertionFailure() << error;
66 }
67
68 base::ScopedTempDir temp_dir_;
69 ScopedCurrentChannel scoped_channel_;
70 base::DictionaryValue manifest_;
71};
72
73TEST_F(StorageSchemaManifestHandlerTest, Parse) {
74 scoped_refptr<Extension> extension = CreateExtension("");
75 ASSERT_TRUE(extension.get());
76
77 // Not a string.
78 manifest_.SetInteger("storage.managed_schema", 123);
79 extension = CreateExtension("");
80 EXPECT_FALSE(extension.get());
81
82 // All good now.
83 manifest_.SetString("storage.managed_schema", "schema.json");
84 extension = CreateExtension("");
85 ASSERT_TRUE(extension.get());
86}
87
88TEST_F(StorageSchemaManifestHandlerTest, Validate) {
89 base::ListValue permissions;
90 permissions.AppendString("storage");
91 manifest_.SetKey("permissions", permissions.Clone());
92
93 // Absolute path.
94 manifest_.SetString("storage.managed_schema", "/etc/passwd");
95 EXPECT_FALSE(Validates(""));
96
97 // Path with ..
98 manifest_.SetString("storage.managed_schema", "../../../../../etc/passwd");
99 EXPECT_FALSE(Validates(""));
100
101 // Does not exist.
102 manifest_.SetString("storage.managed_schema", "not-there");
103 EXPECT_FALSE(Validates(""));
104
105 // Invalid JSON.
106 manifest_.SetString("storage.managed_schema", "schema.json");
107 EXPECT_FALSE(Validates("-invalid-"));
108
109 // No version.
110 EXPECT_FALSE(Validates("{}"));
111
112 // Invalid version.
113 EXPECT_FALSE(Validates(
114 "{"
115 " \"$schema\": \"http://json-schema.org/draft-42/schema#\""
116 "}"));
117
118 // Missing type.
119 EXPECT_FALSE(Validates(
120 "{"
121 " \"$schema\": \"http://json-schema.org/draft-03/schema#\""
122 "}"));
123
124 // Invalid type.
125 EXPECT_FALSE(Validates(
126 "{"
127 " \"$schema\": \"http://json-schema.org/draft-03/schema#\","
128 " \"type\": \"string\""
129 "}"));
130
131 // "additionalProperties" not supported at top level.
132 EXPECT_FALSE(Validates(
133 "{"
134 " \"$schema\": \"http://json-schema.org/draft-03/schema#\","
135 " \"type\": \"object\","
136 " \"additionalProperties\": {}"
137 "}"));
138
139 // All good now.
140 EXPECT_TRUE(Validates(
141 "{"
142 " \"$schema\": \"http://json-schema.org/draft-03/schema#\","
143 " \"type\": \"object\""
144 "}"));
145}
146
147} // namespace extensions
148