root/chrome/browser/content_settings/cookie_settings.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. IsValidSetting
  2. IsAllowed
  3. GetForProfile
  4. GetInstance
  5. RegisterProfilePrefs
  6. GetBrowserContextToUse
  7. BuildServiceInstanceFor
  8. block_third_party_cookies_
  9. GetDefaultCookieSetting
  10. IsReadingCookieAllowed
  11. IsSettingCookieAllowed
  12. IsCookieSessionOnly
  13. GetCookieSettings
  14. SetDefaultCookieSetting
  15. SetCookieSetting
  16. ResetCookieSetting
  17. ShutdownOnUIThread
  18. GetCookieSetting
  19. OnBlockThirdPartyCookiesChanged
  20. ShouldBlockThirdPartyCookies

// Copyright (c) 2012 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 "chrome/browser/content_settings/cookie_settings.h"

#include "base/command_line.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/content_settings_utils.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/content_settings_pattern.h"
#include "chrome/common/pref_names.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "extensions/common/constants.h"
#include "net/base/net_errors.h"
#include "net/base/static_cookie_policy.h"
#include "url/gurl.h"

using base::UserMetricsAction;
using content::BrowserThread;

namespace {

bool IsValidSetting(ContentSetting setting) {
  return (setting == CONTENT_SETTING_ALLOW ||
          setting == CONTENT_SETTING_SESSION_ONLY ||
          setting == CONTENT_SETTING_BLOCK);
}

bool IsAllowed(ContentSetting setting) {
  DCHECK(IsValidSetting(setting));
  return (setting == CONTENT_SETTING_ALLOW ||
          setting == CONTENT_SETTING_SESSION_ONLY);
}

}  // namespace

// static
scoped_refptr<CookieSettings> CookieSettings::Factory::GetForProfile(
    Profile* profile) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return static_cast<CookieSettings*>(
      GetInstance()->GetServiceForBrowserContext(profile, true).get());
}

// static
CookieSettings::Factory* CookieSettings::Factory::GetInstance() {
  return Singleton<CookieSettings::Factory>::get();
}

CookieSettings::Factory::Factory()
    : RefcountedBrowserContextKeyedServiceFactory(
        "CookieSettings",
        BrowserContextDependencyManager::GetInstance()) {
}

CookieSettings::Factory::~Factory() {}

void CookieSettings::Factory::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterBooleanPref(
      prefs::kBlockThirdPartyCookies,
      false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
}

content::BrowserContext* CookieSettings::Factory::GetBrowserContextToUse(
    content::BrowserContext* context) const {
  return chrome::GetBrowserContextRedirectedInIncognito(context);
}

scoped_refptr<RefcountedBrowserContextKeyedService>
CookieSettings::Factory::BuildServiceInstanceFor(
    content::BrowserContext* context) const {
  Profile* profile = static_cast<Profile*>(context);
  return new CookieSettings(profile->GetHostContentSettingsMap(),
                            profile->GetPrefs());
}

CookieSettings::CookieSettings(
    HostContentSettingsMap* host_content_settings_map,
    PrefService* prefs)
    : host_content_settings_map_(host_content_settings_map),
      block_third_party_cookies_(
          prefs->GetBoolean(prefs::kBlockThirdPartyCookies)) {
  if (block_third_party_cookies_) {
    content::RecordAction(
        UserMetricsAction("ThirdPartyCookieBlockingEnabled"));
  } else {
    content::RecordAction(
        UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
  }

  pref_change_registrar_.Init(prefs);
  pref_change_registrar_.Add(
      prefs::kBlockThirdPartyCookies,
      base::Bind(&CookieSettings::OnBlockThirdPartyCookiesChanged,
                 base::Unretained(this)));
}

ContentSetting
CookieSettings::GetDefaultCookieSetting(std::string* provider_id) const {
  return host_content_settings_map_->GetDefaultContentSetting(
      CONTENT_SETTINGS_TYPE_COOKIES, provider_id);
}

bool CookieSettings::IsReadingCookieAllowed(const GURL& url,
                                            const GURL& first_party_url) const {
  ContentSetting setting = GetCookieSetting(url, first_party_url, false, NULL);
  return IsAllowed(setting);
}

bool CookieSettings::IsSettingCookieAllowed(const GURL& url,
                                            const GURL& first_party_url) const {
  ContentSetting setting = GetCookieSetting(url, first_party_url, true, NULL);
  return IsAllowed(setting);
}

bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const {
  ContentSetting setting = GetCookieSetting(origin, origin, true, NULL);
  DCHECK(IsValidSetting(setting));
  return (setting == CONTENT_SETTING_SESSION_ONLY);
}

void CookieSettings::GetCookieSettings(
    ContentSettingsForOneType* settings) const {
  return host_content_settings_map_->GetSettingsForOneType(
      CONTENT_SETTINGS_TYPE_COOKIES, std::string(), settings);
}

void CookieSettings::SetDefaultCookieSetting(ContentSetting setting) {
  DCHECK(IsValidSetting(setting));
  host_content_settings_map_->SetDefaultContentSetting(
      CONTENT_SETTINGS_TYPE_COOKIES, setting);
}

void CookieSettings::SetCookieSetting(
    const ContentSettingsPattern& primary_pattern,
    const ContentSettingsPattern& secondary_pattern,
    ContentSetting setting) {
  DCHECK(IsValidSetting(setting));
  if (setting == CONTENT_SETTING_SESSION_ONLY) {
    DCHECK(secondary_pattern == ContentSettingsPattern::Wildcard());
  }
  host_content_settings_map_->SetContentSetting(primary_pattern,
                                                secondary_pattern,
                                                CONTENT_SETTINGS_TYPE_COOKIES,
                                                std::string(),
                                                setting);
}

void CookieSettings::ResetCookieSetting(
    const ContentSettingsPattern& primary_pattern,
    const ContentSettingsPattern& secondary_pattern) {
  host_content_settings_map_->SetContentSetting(primary_pattern,
                                                secondary_pattern,
                                                CONTENT_SETTINGS_TYPE_COOKIES,
                                                std::string(),
                                                CONTENT_SETTING_DEFAULT);
}

void CookieSettings::ShutdownOnUIThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  pref_change_registrar_.RemoveAll();
}

ContentSetting CookieSettings::GetCookieSetting(
    const GURL& url,
    const GURL& first_party_url,
    bool setting_cookie,
    content_settings::SettingSource* source) const {
  if (HostContentSettingsMap::ShouldAllowAllContent(
        url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES))
    return CONTENT_SETTING_ALLOW;

  // First get any host-specific settings.
  content_settings::SettingInfo info;
  scoped_ptr<base::Value> value(host_content_settings_map_->GetWebsiteSetting(
      url,
      first_party_url,
      CONTENT_SETTINGS_TYPE_COOKIES,
      std::string(),
      &info));
  if (source)
    *source = info.source;

  // If no explicit exception has been made and third-party cookies are blocked
  // by default, apply that rule.
  if (info.primary_pattern.MatchesAllHosts() &&
      info.secondary_pattern.MatchesAllHosts() &&
      ShouldBlockThirdPartyCookies() &&
      !first_party_url.SchemeIs(extensions::kExtensionScheme)) {
    net::StaticCookiePolicy policy(
        net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES);
    int rv;
    if (setting_cookie)
      rv = policy.CanSetCookie(url, first_party_url);
    else
      rv = policy.CanGetCookies(url, first_party_url);
    DCHECK_NE(net::ERR_IO_PENDING, rv);
    if (rv != net::OK)
      return CONTENT_SETTING_BLOCK;
  }

  // We should always have a value, at least from the default provider.
  DCHECK(value.get());
  return content_settings::ValueToContentSetting(value.get());
}

CookieSettings::~CookieSettings() {}

void CookieSettings::OnBlockThirdPartyCookiesChanged() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  base::AutoLock auto_lock(lock_);
  block_third_party_cookies_ = pref_change_registrar_.prefs()->GetBoolean(
      prefs::kBlockThirdPartyCookies);
}

bool CookieSettings::ShouldBlockThirdPartyCookies() const {
  base::AutoLock auto_lock(lock_);
  return block_third_party_cookies_;
}

/* [<][>][^][v][top][bottom][index][help] */