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 "chrome/common/chrome_version_info.h"
15#include "chrome/common/extensions/features/feature_channel.h"
16#include "extensions/common/extension.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_(chrome::VersionInfo::CHANNEL_DEV) {}
27
28  virtual ~StorageSchemaManifestHandlerTest() {}
29
30  virtual 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 = Extension::Create(
41        temp_dir_.path(), Manifest::UNPACKED, manifest_,
42        Extension::NO_FLAGS, "", &error);
43    if (!extension.get())
44      return NULL;
45    base::FilePath schema_path = temp_dir_.path().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_.Set("permissions", permissions.DeepCopy());
92
93#if defined(ENABLE_CONFIGURATION_POLICY)
94  // Absolute path.
95  manifest_.SetString("storage.managed_schema", "/etc/passwd");
96  EXPECT_FALSE(Validates(""));
97
98  // Path with ..
99  manifest_.SetString("storage.managed_schema", "../../../../../etc/passwd");
100  EXPECT_FALSE(Validates(""));
101
102  // Does not exist.
103  manifest_.SetString("storage.managed_schema", "not-there");
104  EXPECT_FALSE(Validates(""));
105
106  // Invalid JSON.
107  manifest_.SetString("storage.managed_schema", "schema.json");
108  EXPECT_FALSE(Validates("-invalid-"));
109
110  // No version.
111  EXPECT_FALSE(Validates("{}"));
112
113  // Invalid version.
114  EXPECT_FALSE(Validates(
115      "{"
116      "  \"$schema\": \"http://json-schema.org/draft-42/schema#\""
117      "}"));
118
119  // Missing type.
120  EXPECT_FALSE(Validates(
121      "{"
122      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\""
123      "}"));
124
125  // Invalid type.
126  EXPECT_FALSE(Validates(
127      "{"
128      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\","
129      "  \"type\": \"string\""
130      "}"));
131
132  // "additionalProperties" not supported at top level.
133  EXPECT_FALSE(Validates(
134      "{"
135      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\","
136      "  \"type\": \"object\","
137      "  \"additionalProperties\": {}"
138      "}"));
139#endif
140
141  // All good now.
142  EXPECT_TRUE(Validates(
143      "{"
144      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\","
145      "  \"type\": \"object\""
146      "}"));
147}
148
149}  // namespace extensions
150