Home | History | Annotate | Download | only in storage
      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/file_util.h"
     11 #include "base/files/file_path.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 
     21 namespace extensions {
     22 
     23 class 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 
     73 TEST_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 
     88 TEST_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