summaryrefslogtreecommitdiffstats
path: root/chrome/browser/host_content_settings_map.h
blob: 00e15bd19fd74445c018a56f92f95538370959ae (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
// Copyright (c) 2010 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.

// Maps hostnames to custom content settings.  Written on the UI thread and read
// on any thread.  One instance per profile.

#ifndef CHROME_BROWSER_HOST_CONTENT_SETTINGS_MAP_H_
#define CHROME_BROWSER_HOST_CONTENT_SETTINGS_MAP_H_
#pragma once

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/lock.h"
#include "base/ref_counted.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/common/content_settings.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"

class DictionaryValue;
class GURL;
class PrefService;
class Profile;

class HostContentSettingsMap
    : public NotificationObserver,
      public base::RefCountedThreadSafe<HostContentSettingsMap,
                                        BrowserThread::DeleteOnUIThread> {
 public:
  // A hostname pattern. See |IsValid| for a description of possible patterns.
  class Pattern {
   public:
    // Returns a pattern that matches the host of this URL and all subdomains.
    static Pattern FromURL(const GURL& url);

    // Returns a pattern that matches exactly this URL.
    static Pattern FromURLNoWildcard(const GURL& url);

    Pattern() {}

    explicit Pattern(const std::string& pattern) : pattern_(pattern) {}

    // True if this is a valid pattern. Valid patterns are
    //   - [*.]domain.tld (matches domain.tld and all sub-domains)
    //   - host (matches an exact hostname)
    //   - a.b.c.d (matches an exact IPv4 ip)
    //   - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip)
    bool IsValid() const;

    // True if |url| matches this pattern.
    bool Matches(const GURL& url) const;

    // Returns a std::string representation of this pattern.
    const std::string& AsString() const { return pattern_; }

    bool operator==(const Pattern& other) const {
      return pattern_ == other.pattern_;
    }

    // Canonicalizes the pattern so that it's ASCII only, either
    // in original or punycode form.
    std::string CanonicalizePattern() const;

   private:
    std::string pattern_;
  };

  // Details for the CONTENT_SETTINGS_CHANGED notification. This is sent when
  // content settings change for at least one host. If settings change for more
  // than one pattern in one user interaction, this will usually send a single
  // notification with update_all() returning true instead of one notification
  // for each pattern.
  class ContentSettingsDetails {
   public:
    // Update the setting that matches this pattern/content type/resource.
    ContentSettingsDetails(const Pattern& pattern,
                           ContentSettingsType type,
                           const std::string& resource_identifier)
        : pattern_(pattern),
          type_(type),
          resource_identifier_(resource_identifier) {}

    // The pattern whose settings have changed.
    const Pattern& pattern() const { return pattern_; }

    // True if all settings should be updated for the given type.
    bool update_all() const { return pattern_.AsString().empty(); }

    // The type of the pattern whose settings have changed.
    ContentSettingsType type() const { return type_; }

    // The resource identifier for the settings type that has changed.
    const std::string& resource_identifier() const {
      return resource_identifier_;
    }

    // True if all types should be updated. If update_all() is false, this will
    // be false as well (although the reverse does not hold true).
    bool update_all_types() const {
      return CONTENT_SETTINGS_TYPE_DEFAULT == type_;
    }

   private:
    Pattern pattern_;
    ContentSettingsType type_;
    std::string resource_identifier_;
  };

  typedef std::pair<Pattern, ContentSetting> PatternSettingPair;
  typedef std::vector<PatternSettingPair> SettingsForOneType;

  explicit HostContentSettingsMap(Profile* profile);
  ~HostContentSettingsMap();

  static void RegisterUserPrefs(PrefService* prefs);

  // Returns the default setting for a particular content type.
  //
  // This may be called on any thread.
  ContentSetting GetDefaultContentSetting(
      ContentSettingsType content_type) const;

  // Returns a single ContentSetting which applies to a given URL. Note that
  // certain internal schemes are whitelisted. For ContentSettingsTypes that
  // require an resource identifier to be specified, the |resource_identifier|
  // must be non-empty.
  //
  // This may be called on any thread.
  ContentSetting GetContentSetting(
      const GURL& url,
      ContentSettingsType content_type,
      const std::string& resource_identifier) const;

  // Returns a single ContentSetting which applies to a given URL or
  // CONTENT_SETTING_DEFAULT, if no exception applies. Note that certain
  // internal schemes are whitelisted. For ContentSettingsTypes that require an
  // resource identifier to be specified, the |resource_identifier| must be
  // non-empty.
  //
  // This may be called on any thread.
  ContentSetting GetNonDefaultContentSetting(
      const GURL& url,
      ContentSettingsType content_type,
      const std::string& resource_identifier) const;

  // Returns all ContentSettings which apply to a given URL. For content
  // setting types that require an additional resource identifier, the default
  // content setting is returned.
  //
  // This may be called on any thread.
  ContentSettings GetContentSettings(const GURL& url) const;

  // Returns all non-default ContentSettings which apply to a given URL. For
  // content setting types that require an additional resource identifier,
  // CONTENT_SETTING_DEFAULT is returned.
  //
  // This may be called on any thread.
  ContentSettings GetNonDefaultContentSettings(const GURL& url) const;

  // For a given content type, returns all patterns with a non-default setting,
  // mapped to their actual settings, in lexicographical order.  |settings|
  // must be a non-NULL outparam. If this map was created for the
  // off-the-record profile, it will only return those settings differing from
  // the main map. For ContentSettingsTypes that require an resource identifier
  // to be specified, the |resource_identifier| must be non-empty.
  //
  // This may be called on any thread.
  void GetSettingsForOneType(ContentSettingsType content_type,
                             const std::string& resource_identifier,
                             SettingsForOneType* settings) const;

  // Sets the default setting for a particular content type. This method must
  // not be invoked on an off-the-record map.
  //
  // This should only be called on the UI thread.
  void SetDefaultContentSetting(ContentSettingsType content_type,
                                ContentSetting setting);

  // Sets the blocking setting for a particular pattern and content type.
  // Setting the value to CONTENT_SETTING_DEFAULT causes the default setting
  // for that type to be used when loading pages matching this pattern. For
  // ContentSettingsTypes that require an resource identifier to be specified,
  // the |resource_identifier| must be non-empty.
  //
  // This should only be called on the UI thread.
  void SetContentSetting(const Pattern& pattern,
                         ContentSettingsType content_type,
                         const std::string& resource_identifier,
                         ContentSetting setting);

  // Convenience method to add a content setting for a given URL, making sure
  // that there is no setting overriding it. For ContentSettingsTypes that
  // require an resource identifier to be specified, the |resource_identifier|
  // must be non-empty.
  //
  // This should only be called on the UI thread.
  void AddExceptionForURL(const GURL& url,
                          ContentSettingsType content_type,
                          const std::string& resource_identifier,
                          ContentSetting setting);

  // Clears all host-specific settings for one content type.
  //
  // This should only be called on the UI thread.
  void ClearSettingsForOneType(ContentSettingsType content_type);

  // Whether the |content_type| requires an additional resource identifier for
  // accessing content settings.
  bool RequiresResourceIdentifier(ContentSettingsType content_type) const;

  // This setting trumps any host-specific settings.
  bool BlockThirdPartyCookies() const { return block_third_party_cookies_; }
  bool IsBlockThirdPartyCookiesManaged() const {
    return is_block_third_party_cookies_managed_;
  }

  // Sets whether we block all third-party cookies. This method must not be
  // invoked on an off-the-record map.
  //
  // This should only be called on the UI thread.
  void SetBlockThirdPartyCookies(bool block);

  bool GetBlockNonsandboxedPlugins() const {
    return block_nonsandboxed_plugins_;
  }

  void SetBlockNonsandboxedPlugins(bool block);

  // Resets all settings levels.
  //
  // This should only be called on the UI thread.
  void ResetToDefaults();

  // Returns true if the default setting for the |content_type| is managed.
  bool IsDefaultContentSettingManaged(ContentSettingsType content_type) const;

  // NotificationObserver implementation.
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details);

 private:
  friend class base::RefCountedThreadSafe<HostContentSettingsMap>;

  typedef std::pair<ContentSettingsType, std::string>
      ContentSettingsTypeResourceIdentifierPair;
  typedef std::map<ContentSettingsTypeResourceIdentifierPair, ContentSetting>
      ResourceContentSettings;

  struct ExtendedContentSettings;
  typedef std::map<std::string, ExtendedContentSettings> HostContentSettings;

  // Sets the fields of |settings| based on the values in |dictionary|.
  void GetSettingsFromDictionary(const DictionaryValue* dictionary,
                                 ContentSettings* settings);

  // Populates |settings| based on the values in |dictionary|.
  void GetResourceSettingsFromDictionary(const DictionaryValue* dictionary,
                                         ResourceContentSettings* settings);

  // Forces the default settings to be explicitly set instead of themselves
  // being CONTENT_SETTING_DEFAULT.
  void ForceDefaultsToBeExplicit();

  // Returns true if |settings| consists entirely of CONTENT_SETTING_DEFAULT.
  bool AllDefault(const ExtendedContentSettings& settings) const;

  // Reads the default settings from the prefereces service. If |overwrite| is
  // true and the preference is missing, the local copy will be cleared as well.
  void ReadDefaultSettings(bool overwrite);

  // Reads managed default content settings from the preference service |prefs|.
  // |settings| is set to the respective content setting for managed settings,
  // and to CONTENT_SETTING_DEFAULT for other settings.
  void ReadManagedDefaultSettings(const PrefService* prefs,
                                  ContentSettings* settings);

  // Updates the managed setting of the default-content-settings-type |type|.
  // The updated setting is read from the preference service |prefs| and written
  // to |settings|.
  void UpdateManagedDefaultSetting(ContentSettingsType type,
                                   const PrefService* prefs,
                                   ContentSettings* settings);

  // Reads the host exceptions from the prefereces service. If |overwrite| is
  // true and the preference is missing, the local copy will be cleared as well.
  void ReadExceptions(bool overwrite);

  // Informs observers that content settings have changed. Make sure that
  // |lock_| is not held when calling this, as listeners will usually call one
  // of the GetSettings functions in response, which would then lead to a
  // mutex deadlock.
  void NotifyObservers(const ContentSettingsDetails& details);

  void UnregisterObservers();

  // Various migration methods (old cookie, popup and per-host data gets
  // migrated to the new format).
  void MigrateObsoleteCookiePref(PrefService* prefs);
  void MigrateObsoletePopupsPref(PrefService* prefs);
  void MigrateObsoletePerhostPref(PrefService* prefs);

  // Converts all exceptions that have non-canonicalized pattern into
  // canonicalized pattern. If such pattern already exists, we just remove the
  // old exception.
  void CanonicalizeContentSettingsExceptions(DictionaryValue* settings);

  // The profile we're associated with.
  Profile* profile_;

  NotificationRegistrar notification_registrar_;
  PrefChangeRegistrar pref_change_registrar_;

  // Copies of the pref data, so that we can read it on the IO thread.
  ContentSettings default_content_settings_;
  ContentSettings managed_default_content_settings_;
  HostContentSettings host_content_settings_;

  // Differences to the preference-stored host content settings for
  // off-the-record settings.
  HostContentSettings off_the_record_settings_;

  // Misc global settings.
  bool block_third_party_cookies_;
  bool is_block_third_party_cookies_managed_;
  bool block_nonsandboxed_plugins_;

  // Used around accesses to the settings objects to guarantee thread safety.
  mutable Lock lock_;

  // Whether this settings map is for an OTR session.
  bool is_off_the_record_;

  // Whether we are currently updating preferences, this is used to ignore
  // notifications from the preferences service that we triggered ourself.
  bool updating_preferences_;

  DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMap);
};

// Stream operator so HostContentSettingsMap::Pattern can be used in
// assertion statements.
inline std::ostream& operator<<(
    std::ostream& out, const HostContentSettingsMap::Pattern& pattern) {
  return out << pattern.AsString();
}

#endif  // CHROME_BROWSER_HOST_CONTENT_SETTINGS_MAP_H_