webui_allowlist.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2020 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. #include "ui/webui/webui_allowlist.h"
  5. #include <memory>
  6. #include "base/memory/scoped_refptr.h"
  7. #include "base/sequence_checker.h"
  8. #include "base/supports_user_data.h"
  9. #include "content/public/browser/browser_context.h"
  10. #include "content/public/browser/browser_thread.h"
  11. #include "content/public/common/url_constants.h"
  12. #include "content/public/common/url_utils.h"
  13. #include "ui/webui/webui_allowlist_provider.h"
  14. #include "url/gurl.h"
  15. const char kWebUIAllowlistKeyName[] = "WebUIAllowlist";
  16. namespace {
  17. struct WebUIAllowlistHolder : base::SupportsUserData::Data {
  18. explicit WebUIAllowlistHolder(scoped_refptr<WebUIAllowlist> list)
  19. : allow_list(std::move(list)) {}
  20. const scoped_refptr<WebUIAllowlist> allow_list;
  21. };
  22. } // namespace
  23. // static
  24. WebUIAllowlist* WebUIAllowlist::GetOrCreate(
  25. content::BrowserContext* browser_context) {
  26. if (!browser_context->GetUserData(kWebUIAllowlistKeyName)) {
  27. auto list = base::MakeRefCounted<WebUIAllowlist>();
  28. browser_context->SetUserData(
  29. kWebUIAllowlistKeyName,
  30. std::make_unique<WebUIAllowlistHolder>(std::move(list)));
  31. }
  32. return static_cast<WebUIAllowlistHolder*>(
  33. browser_context->GetUserData(kWebUIAllowlistKeyName))
  34. ->allow_list.get();
  35. }
  36. WebUIAllowlist::WebUIAllowlist() = default;
  37. WebUIAllowlist::~WebUIAllowlist() = default;
  38. void WebUIAllowlist::RegisterAutoGrantedPermission(const url::Origin& origin,
  39. ContentSettingsType type,
  40. ContentSetting setting) {
  41. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  42. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  43. DCHECK(content::HasWebUIOrigin(origin));
  44. // It doesn't make sense to grant a default content setting.
  45. DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
  46. SetContentSettingsAndNotifyProvider(
  47. ContentSettingsPattern::FromURLNoWildcard(origin.GetURL()),
  48. ContentSettingsPattern::Wildcard(), type, setting);
  49. }
  50. void WebUIAllowlist::RegisterAutoGrantedPermissions(
  51. const url::Origin& origin,
  52. std::initializer_list<ContentSettingsType> types) {
  53. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  54. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  55. for (const ContentSettingsType& type : types)
  56. RegisterAutoGrantedPermission(origin, type);
  57. }
  58. void WebUIAllowlist::RegisterAutoGrantedThirdPartyCookies(
  59. const url::Origin& top_level_origin,
  60. const std::vector<ContentSettingsPattern>& origin_patterns) {
  61. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  62. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  63. DCHECK(content::HasWebUIOrigin(top_level_origin));
  64. const auto top_level_origin_pattern =
  65. ContentSettingsPattern::FromURLNoWildcard(top_level_origin.GetURL());
  66. for (const auto& pattern : origin_patterns) {
  67. // For COOKIES content setting, |primary_pattern| is the origin setting the
  68. // cookie, |secondary_pattern| is the top-level document's origin.
  69. SetContentSettingsAndNotifyProvider(pattern, top_level_origin_pattern,
  70. ContentSettingsType::COOKIES,
  71. CONTENT_SETTING_ALLOW);
  72. }
  73. }
  74. void WebUIAllowlist::SetWebUIAllowlistProvider(
  75. WebUIAllowlistProvider* provider) {
  76. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  77. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  78. provider_ = provider;
  79. }
  80. void WebUIAllowlist::ResetWebUIAllowlistProvider() {
  81. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  82. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  83. provider_ = nullptr;
  84. }
  85. std::unique_ptr<content_settings::RuleIterator> WebUIAllowlist::GetRuleIterator(
  86. ContentSettingsType content_type) const NO_THREAD_SAFETY_ANALYSIS {
  87. // NO_THREAD_SAFETY_ANALYSIS: GetRuleIterator immediately locks the lock.
  88. return value_map_.GetRuleIterator(content_type, &lock_);
  89. }
  90. void WebUIAllowlist::SetContentSettingsAndNotifyProvider(
  91. const ContentSettingsPattern& primary_pattern,
  92. const ContentSettingsPattern& secondary_pattern,
  93. ContentSettingsType type,
  94. ContentSetting setting) {
  95. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  96. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  97. {
  98. base::AutoLock auto_lock(lock_);
  99. value_map_.SetValue(primary_pattern, secondary_pattern, type, base::Time(),
  100. base::Value(setting),
  101. /* constraints */ {});
  102. }
  103. // Notify the provider. |provider_| can be nullptr if
  104. // HostContentSettingsRegistry is shutting down i.e. when Chrome shuts down.
  105. //
  106. // It's okay to notify the provider multiple times even if the setting isn't
  107. // changed.
  108. if (provider_) {
  109. provider_->NotifyContentSettingChange(primary_pattern, secondary_pattern,
  110. type);
  111. }
  112. }