1 // Copyright (c) 2012 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 #ifndef COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_COOKIE_SETTINGS_H_
6 #define COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_COOKIE_SETTINGS_H_
7 
8 #include <string>
9 
10 #include "base/compiler_specific.h"
11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/observer_list.h"
14 #include "base/scoped_observer.h"
15 #include "base/synchronization/lock.h"
16 #include "base/threading/thread_checker.h"
17 #include "components/content_settings/core/browser/content_settings_observer.h"
18 #include "components/content_settings/core/browser/host_content_settings_map.h"
19 #include "components/content_settings/core/common/content_settings.h"
20 #include "components/content_settings/core/common/cookie_settings_base.h"
21 #include "components/keyed_service/core/refcounted_keyed_service.h"
22 #include "components/prefs/pref_change_registrar.h"
23 
24 class GURL;
25 class PrefService;
26 
27 namespace content_settings {
28 
29 // This enum is used in prefs, do not change values.
30 // The enum needs to correspond to CookieControlsMode in enums.xml.
31 // This enum needs to be kept in sync with the enum of the same name in
32 // browser/resources/settings/site_settings/constants.js.
33 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.content_settings
34 enum class CookieControlsMode {
35   kOff = 0,
36   kOn = 1,
37   kIncognitoOnly = 2,
38   kMaxValue = kIncognitoOnly,
39 };
40 
41 // Default value for |extension_scheme|.
42 const char kDummyExtensionScheme[] = ":no-extension-scheme:";
43 
44 // A frontend to the cookie settings of |HostContentSettingsMap|. Handles
45 // cookie-specific logic such as blocking third-party cookies. Written on the UI
46 // thread and read on any thread.
47 class CookieSettings : public CookieSettingsBase,
48                        public content_settings::Observer,
49                        public RefcountedKeyedService {
50  public:
51   class Observer : public base::CheckedObserver {
52    public:
OnThirdPartyCookieBlockingChanged(bool block_third_party_cookies)53     virtual void OnThirdPartyCookieBlockingChanged(
54         bool block_third_party_cookies) {}
OnCookieSettingChanged()55     virtual void OnCookieSettingChanged() {}
56   };
57 
58   // Creates a new CookieSettings instance.
59   // The caller is responsible for ensuring that |extension_scheme| is valid for
60   // the whole lifetime of this instance.
61   // |is_incognito| indicates whether this is an incognito profile. It is not
62   // true for other types of off-the-record profiles like guest mode.
63   CookieSettings(HostContentSettingsMap* host_content_settings_map,
64                  PrefService* prefs,
65                  bool is_incognito,
66                  const char* extension_scheme = kDummyExtensionScheme);
67 
68   // Returns the default content setting (CONTENT_SETTING_ALLOW,
69   // CONTENT_SETTING_BLOCK, or CONTENT_SETTING_SESSION_ONLY) for cookies. If
70   // |provider_id| is not nullptr, the id of the provider which provided the
71   // default setting is assigned to it.
72   //
73   // This may be called on any thread.
74   ContentSetting GetDefaultCookieSetting(std::string* provider_id) const;
75 
76   // Returns all patterns with a non-default cookie setting, mapped to their
77   // actual settings, in the precedence order of the setting rules. |settings|
78   // must be a non-nullptr outparam.
79   //
80   // This may be called on any thread.
81   void GetCookieSettings(ContentSettingsForOneType* settings) const;
82 
83   // Sets the default content setting (CONTENT_SETTING_ALLOW,
84   // CONTENT_SETTING_BLOCK, or CONTENT_SETTING_SESSION_ONLY) for cookies.
85   //
86   // This should only be called on the UI thread.
87   void SetDefaultCookieSetting(ContentSetting setting);
88 
89   // Sets the cookie setting for the given url.
90   //
91   // This should only be called on the UI thread.
92   void SetCookieSetting(const GURL& primary_url, ContentSetting setting);
93 
94   // Resets the cookie setting for the given url.
95   //
96   // This should only be called on the UI thread.
97   void ResetCookieSetting(const GURL& primary_url);
98 
99   // Returns true if cookies are allowed for *most* third parties on |url|.
100   // There might be rules allowing or blocking specific third parties from
101   // accessing cookies.
102   //
103   // This should only be called on the UI thread.
104   bool IsThirdPartyAccessAllowed(const GURL& first_party_url,
105                                  content_settings::SettingSource* source);
106 
107   // Sets the cookie setting for the site and third parties embedded in it.
108   //
109   // This should only be called on the UI thread.
110   void SetThirdPartyCookieSetting(const GURL& first_party_url,
111                                   ContentSetting setting);
112 
113   // Resets the third party cookie setting for the given url.
114   //
115   // This should only be called on the UI thread.
116   void ResetThirdPartyCookieSetting(const GURL& first_party_url);
117 
118   bool IsStorageDurable(const GURL& origin) const;
119 
120   // Returns true if third party cookies should be blocked.
121   //
122   // This method may be called on any thread.
123   bool ShouldBlockThirdPartyCookies() const;
124 
125   // content_settings::CookieSettingsBase:
126   void GetSettingForLegacyCookieAccess(const std::string& cookie_domain,
127                                        ContentSetting* setting) const override;
128   bool ShouldIgnoreSameSiteRestrictions(
129       const GURL& url,
130       const GURL& site_for_cookies) const override;
131 
132   // Detaches the |CookieSettings| from |PrefService|. This methods needs to be
133   // called before destroying the service. Afterwards, only const methods can be
134   // called.
135   void ShutdownOnUIThread() override;
136 
137   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
138 
AddObserver(Observer * obs)139   void AddObserver(Observer* obs) { observers_.AddObserver(obs); }
140 
RemoveObserver(Observer * obs)141   void RemoveObserver(Observer* obs) { observers_.RemoveObserver(obs); }
142 
143   // Returns true when the improved cookie control UI should be shown.
144   // TODO(dullweber): Fix grammar.
145   bool IsCookieControlsEnabled();
146 
147  private:
148   ~CookieSettings() override;
149 
150   // Returns whether third-party cookie blocking should be bypassed (i.e. always
151   // allow the cookie regardless of cookie content settings and third-party
152   // cookie blocking settings.
153   // This just checks the scheme of the |url| and |site_for_cookies|:
154   //  - Allow cookies if the |site_for_cookies| is a chrome:// scheme URL, and
155   //    the |url| has a secure scheme.
156   //  - Allow cookies if the |site_for_cookies| and the |url| match in scheme
157   //    and both have the Chrome extensions scheme.
158   bool ShouldAlwaysAllowCookies(const GURL& url,
159                                 const GURL& first_party_url) const;
160 
161   // content_settings::CookieSettingsBase:
162   void GetCookieSettingInternal(const GURL& url,
163                                 const GURL& first_party_url,
164                                 bool is_third_party_request,
165                                 content_settings::SettingSource* source,
166                                 ContentSetting* cookie_setting) const override;
167 
168   // content_settings::Observer:
169   void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
170                                const ContentSettingsPattern& secondary_pattern,
171                                ContentSettingsType content_type,
172                                const std::string& resource_identifier) override;
173 
174   void OnCookiePreferencesChanged();
175 
176   base::ThreadChecker thread_checker_;
177   base::ObserverList<Observer> observers_;
178   scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
179   ScopedObserver<HostContentSettingsMap, content_settings::Observer>
180       content_settings_observer_{this};
181   PrefChangeRegistrar pref_change_registrar_;
182   const bool is_incognito_;
183   const char* extension_scheme_;  // Weak.
184 
185   // Used around accesses to |block_third_party_cookies_| to guarantee thread
186   // safety.
187   mutable base::Lock lock_;
188 
189   bool block_third_party_cookies_;
190 
191   DISALLOW_COPY_AND_ASSIGN(CookieSettings);
192 };
193 
194 }  // namespace content_settings
195 
196 #endif  // COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_COOKIE_SETTINGS_H_
197