summaryrefslogtreecommitdiff
path: root/chromium/extensions/renderer/feature_cache_unittest.cc
blob: 826122d1c19d06170bdf8b1f74221060f4cb8c48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/renderer/feature_cache.h"

#include "base/containers/contains.h"
#include "components/crx_file/id_util.h"
#include "content/public/test/test_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/value_builder.h"
#include "extensions/renderer/bindings/api_binding_test.h"
#include "extensions/renderer/scoped_web_frame.h"
#include "extensions/renderer/script_context.h"
#include "v8/include/v8.h"

#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"

namespace extensions {

namespace {

struct FakeContext {
  Feature::Context context_type;
  const Extension* extension;
  const GURL url;
};

bool HasFeature(FeatureCache& cache,
                const FakeContext& context,
                const std::string& feature) {
  return base::Contains(
      cache.GetAvailableFeatures(context.context_type, context.extension,
                                 context.url),
      feature);
}

}  // namespace

using FeatureCacheTest = testing::Test;

TEST_F(FeatureCacheTest, Basic) {
  FeatureCache cache;
  scoped_refptr<const Extension> extension_a = ExtensionBuilder("a").Build();
  scoped_refptr<const Extension> extension_b =
      ExtensionBuilder("b").AddPermission("storage").Build();

  FakeContext context_a = {Feature::BLESSED_EXTENSION_CONTEXT,
                           extension_a.get(), extension_a->url()};
  FakeContext context_b = {Feature::BLESSED_EXTENSION_CONTEXT,
                           extension_b.get(), extension_b->url()};
  // To start, context a should not have access to storage, but context b
  // should.
  EXPECT_FALSE(HasFeature(cache, context_a, "storage"));
  EXPECT_TRUE(HasFeature(cache, context_b, "storage"));

  // Update extension b's permissions and invalidate the cache.
  extension_b->permissions_data()->SetPermissions(
      std::make_unique<PermissionSet>(), std::make_unique<PermissionSet>());
  cache.InvalidateExtension(extension_b->id());

  // Now, neither context should have storage access.
  EXPECT_FALSE(HasFeature(cache, context_a, "storage"));
  EXPECT_FALSE(HasFeature(cache, context_b, "storage"));
}

TEST_F(FeatureCacheTest, WebUIContexts) {
  FeatureCache cache;
  scoped_refptr<const Extension> extension_a = ExtensionBuilder("a").Build();

  // The chrome://extensions page is whitelisted for the management API.
  FakeContext webui_context = {Feature::WEBUI_CONTEXT, nullptr,
                               content::GetWebUIURL("extensions")};
  // chrome://baz is not whitelisted, and should not have access.
  FakeContext webui_context_without_access = {Feature::WEBUI_CONTEXT, nullptr,
                                              content::GetWebUIURL("baz")};

  EXPECT_TRUE(HasFeature(cache, webui_context, "management"));
  EXPECT_FALSE(HasFeature(cache, webui_context_without_access, "management"));
  // No webui context is whitelisted for, e.g., the idle API, so neither should
  // have access.
  EXPECT_FALSE(HasFeature(cache, webui_context, "idle"));
  EXPECT_FALSE(HasFeature(cache, webui_context_without_access, "idle"));
}

}  // namespace extensions