1 // Copyright (c) 2011 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 #include "base/message_loop.h" 6 #include "chrome/browser/content_settings/content_settings_details.h" 7 #include "chrome/browser/geolocation/geolocation_content_settings_map.h" 8 #include "chrome/browser/prefs/pref_service.h" 9 #include "chrome/browser/prefs/scoped_user_pref_update.h" 10 #include "chrome/common/pref_names.h" 11 #include "chrome/test/testing_profile.h" 12 #include "content/browser/browser_thread.h" 13 #include "content/common/notification_registrar.h" 14 #include "content/common/notification_service.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 17 18 namespace { 19 20 class StubSettingsObserver : public NotificationObserver { 21 public: 22 StubSettingsObserver() : last_notifier(NULL), counter(0) { 23 registrar_.Add(this, NotificationType::GEOLOCATION_SETTINGS_CHANGED, 24 NotificationService::AllSources()); 25 } 26 27 virtual void Observe(NotificationType type, 28 const NotificationSource& source, 29 const NotificationDetails& details) { 30 ++counter; 31 Source<GeolocationContentSettingsMap> content_settings(source); 32 Details<ContentSettingsDetails> settings_details(details); 33 last_notifier = content_settings.ptr(); 34 last_pattern = settings_details.ptr()->pattern(); 35 last_update_all = settings_details.ptr()->update_all(); 36 last_update_all_types = settings_details.ptr()->update_all_types(); 37 last_type = settings_details.ptr()->type(); 38 // This checks that calling a Get function from an observer doesn't 39 // deadlock. 40 last_notifier->GetContentSetting(GURL("http://random-hostname.com/"), 41 GURL("http://foo.random-hostname.com/")); 42 } 43 44 GeolocationContentSettingsMap* last_notifier; 45 ContentSettingsPattern last_pattern; 46 bool last_update_all; 47 bool last_update_all_types; 48 int counter; 49 ContentSettingsType last_type; 50 51 private: 52 NotificationRegistrar registrar_; 53 }; 54 55 class GeolocationContentSettingsMapTests : public testing::Test { 56 public: 57 GeolocationContentSettingsMapTests() 58 : ui_thread_(BrowserThread::UI, &message_loop_) { 59 } 60 61 protected: 62 MessageLoop message_loop_; 63 BrowserThread ui_thread_; 64 }; 65 66 TEST_F(GeolocationContentSettingsMapTests, DefaultValues) { 67 TestingProfile profile; 68 GeolocationContentSettingsMap* map = 69 profile.GetGeolocationContentSettingsMap(); 70 71 // Check setting defaults. 72 EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting()); 73 map->SetDefaultContentSetting(CONTENT_SETTING_BLOCK); 74 EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetDefaultContentSetting()); 75 } 76 77 TEST_F(GeolocationContentSettingsMapTests, Embedder) { 78 TestingProfile profile; 79 GeolocationContentSettingsMap* map = 80 profile.GetGeolocationContentSettingsMap(); 81 GURL top_level("http://www.toplevel0.com/foo/bar"); 82 EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(top_level, top_level)); 83 // Now set the permission for requester_0. 84 map->SetContentSetting(top_level, top_level, CONTENT_SETTING_ALLOW); 85 EXPECT_EQ(CONTENT_SETTING_ALLOW, 86 map->GetContentSetting(top_level, top_level)); 87 88 GURL requester_0("http://www.frame0.com/foo/bar"); 89 EXPECT_EQ(CONTENT_SETTING_ASK, 90 map->GetContentSetting(requester_0, top_level)); 91 // Now set the permission for only requester_1. 92 map->SetContentSetting(requester_0, top_level, CONTENT_SETTING_ALLOW); 93 EXPECT_EQ(CONTENT_SETTING_ALLOW, 94 map->GetContentSetting(top_level, top_level)); 95 EXPECT_EQ(CONTENT_SETTING_ALLOW, 96 map->GetContentSetting(requester_0, top_level)); 97 // Block only requester_1. 98 map->SetContentSetting(requester_0, top_level, CONTENT_SETTING_BLOCK); 99 EXPECT_EQ(CONTENT_SETTING_BLOCK, 100 map->GetContentSetting(requester_0, top_level)); 101 EXPECT_EQ(CONTENT_SETTING_ALLOW, 102 map->GetContentSetting(top_level, top_level)); 103 } 104 105 TEST_F(GeolocationContentSettingsMapTests, MultipleEmbeddersAndOrigins) { 106 TestingProfile profile; 107 GeolocationContentSettingsMap* map = 108 profile.GetGeolocationContentSettingsMap(); 109 GURL requester_0("http://www.iframe0.com/foo/bar"); 110 GURL requester_1("http://www.iframe1.co.uk/bar/foo"); 111 GURL embedder_0("http://www.toplevel0.com/foo/bar"); 112 EXPECT_EQ(CONTENT_SETTING_ASK, 113 map->GetContentSetting(requester_0, embedder_0)); 114 EXPECT_EQ(CONTENT_SETTING_ASK, 115 map->GetContentSetting(requester_1, embedder_0)); 116 // Now set the permission for only one origin. 117 map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW); 118 EXPECT_EQ(CONTENT_SETTING_ALLOW, 119 map->GetContentSetting(requester_0, embedder_0)); 120 EXPECT_EQ(CONTENT_SETTING_ASK, 121 map->GetContentSetting(requester_1, embedder_0)); 122 // Set the permission for the other origin. 123 map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_ALLOW); 124 EXPECT_EQ(CONTENT_SETTING_ALLOW, 125 map->GetContentSetting(requester_1, embedder_0)); 126 // Check they're not allowed on a different embedder. 127 GURL embedder_1("http://www.toplevel1.com/foo/bar"); 128 EXPECT_EQ(CONTENT_SETTING_ASK, 129 map->GetContentSetting(requester_0, embedder_1)); 130 EXPECT_EQ(CONTENT_SETTING_ASK, 131 map->GetContentSetting(requester_1, embedder_1)); 132 // Check all settings are valid. 133 GeolocationContentSettingsMap::AllOriginsSettings content_settings( 134 map->GetAllOriginsSettings()); 135 EXPECT_EQ(0U, content_settings.count(requester_0)); 136 EXPECT_EQ(1U, content_settings.count(requester_0.GetOrigin())); 137 GeolocationContentSettingsMap::OneOriginSettings one_origin_settings( 138 content_settings[requester_0.GetOrigin()]); 139 EXPECT_EQ(CONTENT_SETTING_ALLOW, one_origin_settings[embedder_0.GetOrigin()]); 140 141 EXPECT_EQ(0U, content_settings.count(requester_1)); 142 EXPECT_EQ(1U, content_settings.count(requester_1.GetOrigin())); 143 one_origin_settings = content_settings[requester_1.GetOrigin()]; 144 EXPECT_EQ(CONTENT_SETTING_ALLOW, one_origin_settings[embedder_0.GetOrigin()]); 145 // Block requester_1 on the first embedder and add it to the second. 146 map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_BLOCK); 147 map->SetContentSetting(requester_1, embedder_1, CONTENT_SETTING_ALLOW); 148 EXPECT_EQ(CONTENT_SETTING_BLOCK, 149 map->GetContentSetting(requester_1, embedder_0)); 150 EXPECT_EQ(CONTENT_SETTING_ALLOW, 151 map->GetContentSetting(requester_1, embedder_1)); 152 } 153 154 TEST_F(GeolocationContentSettingsMapTests, SetContentSettingDefault) { 155 TestingProfile profile; 156 GeolocationContentSettingsMap* map = 157 profile.GetGeolocationContentSettingsMap(); 158 GURL top_level("http://www.toplevel0.com/foo/bar"); 159 map->SetContentSetting(top_level, top_level, CONTENT_SETTING_ALLOW); 160 EXPECT_EQ(CONTENT_SETTING_ALLOW, 161 map->GetContentSetting(top_level, top_level)); 162 // Set to CONTENT_SETTING_DEFAULT and check the actual value has changed. 163 map->SetContentSetting(top_level, top_level, CONTENT_SETTING_DEFAULT); 164 EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(top_level, top_level)); 165 } 166 167 TEST_F(GeolocationContentSettingsMapTests, Reset) { 168 TestingProfile profile; 169 GeolocationContentSettingsMap* map = 170 profile.GetGeolocationContentSettingsMap(); 171 GURL requester_0("http://www.iframe0.com/foo/bar"); 172 GURL embedder_0("http://www.toplevel0.com/foo/bar"); 173 map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW); 174 EXPECT_EQ(CONTENT_SETTING_ALLOW, 175 map->GetContentSetting(requester_0, embedder_0)); 176 GeolocationContentSettingsMap::AllOriginsSettings content_settings( 177 map->GetAllOriginsSettings()); 178 EXPECT_EQ(1U, content_settings.size()); 179 180 // Set to CONTENT_SETTING_DEFAULT and check the actual value has changed. 181 map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_DEFAULT); 182 EXPECT_EQ(CONTENT_SETTING_ASK, 183 map->GetContentSetting(requester_0, embedder_0)); 184 content_settings = map->GetAllOriginsSettings(); 185 EXPECT_TRUE(content_settings.empty()); 186 } 187 188 TEST_F(GeolocationContentSettingsMapTests, ClearsWhenSettingBackToDefault) { 189 TestingProfile profile; 190 GeolocationContentSettingsMap* map = 191 profile.GetGeolocationContentSettingsMap(); 192 GURL requester_0("http://www.iframe0.com/foo/bar"); 193 GURL requester_1("http://www.iframe1.com/foo/bar"); 194 GURL embedder_0("http://www.toplevel0.com/foo/bar"); 195 map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW); 196 EXPECT_EQ(CONTENT_SETTING_ALLOW, 197 map->GetContentSetting(requester_0, embedder_0)); 198 GeolocationContentSettingsMap::AllOriginsSettings content_settings( 199 map->GetAllOriginsSettings()); 200 EXPECT_EQ(1U, content_settings.size()); 201 202 map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_ALLOW); 203 EXPECT_EQ(CONTENT_SETTING_ALLOW, 204 map->GetContentSetting(requester_1, embedder_0)); 205 content_settings = map->GetAllOriginsSettings(); 206 EXPECT_EQ(2U, content_settings.size()); 207 EXPECT_EQ(1U, content_settings[requester_0.GetOrigin()].size()); 208 EXPECT_EQ(1U, content_settings[requester_1.GetOrigin()].size()); 209 210 // Set to default. 211 map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_DEFAULT); 212 content_settings = map->GetAllOriginsSettings(); 213 EXPECT_EQ(1U, content_settings.size()); 214 215 map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_DEFAULT); 216 content_settings = map->GetAllOriginsSettings(); 217 EXPECT_TRUE(content_settings.empty()); 218 } 219 220 TEST_F(GeolocationContentSettingsMapTests, WildCardForEmptyEmbedder) { 221 TestingProfile profile; 222 GeolocationContentSettingsMap* map = 223 profile.GetGeolocationContentSettingsMap(); 224 GURL requester_0("http://www.iframe0.com/foo/bar"); 225 GURL embedder_0("http://www.toplevel0.com/foo/bar"); 226 GURL embedder_1("http://www.toplevel1.com/foo/bar"); 227 GURL empty_url; 228 map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_BLOCK); 229 map->SetContentSetting(requester_0, empty_url, CONTENT_SETTING_ALLOW); 230 EXPECT_EQ(CONTENT_SETTING_BLOCK, 231 map->GetContentSetting(requester_0, embedder_0)); 232 EXPECT_EQ(CONTENT_SETTING_ALLOW, 233 map->GetContentSetting(requester_0, embedder_1)); 234 EXPECT_EQ(CONTENT_SETTING_ASK, 235 map->GetContentSetting(requester_0, requester_0)); 236 237 // Change the wildcard behavior. 238 map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW); 239 map->SetContentSetting(requester_0, empty_url, CONTENT_SETTING_BLOCK); 240 map->SetDefaultContentSetting(CONTENT_SETTING_ALLOW); 241 EXPECT_EQ(CONTENT_SETTING_ALLOW, 242 map->GetContentSetting(requester_0, embedder_0)); 243 EXPECT_EQ(CONTENT_SETTING_BLOCK, 244 map->GetContentSetting(requester_0, embedder_1)); 245 EXPECT_EQ(CONTENT_SETTING_ALLOW, 246 map->GetContentSetting(requester_0, requester_0)); 247 } 248 249 TEST_F(GeolocationContentSettingsMapTests, IgnoreInvalidURLsInPrefs) { 250 TestingProfile profile; 251 { 252 DictionaryPrefUpdate update(profile.GetPrefs(), 253 prefs::kGeolocationContentSettings); 254 DictionaryValue* all_settings_dictionary = update.Get(); 255 // For simplicity, use the overloads that do path expansion. As '.' is the 256 // path separator, we can't have dotted hostnames (which is fine). 257 all_settings_dictionary->SetInteger("http://a/.http://b/", 258 CONTENT_SETTING_ALLOW); 259 all_settings_dictionary->SetInteger("bad_requester.http://b/", 260 CONTENT_SETTING_ALLOW); 261 all_settings_dictionary->SetInteger("http://a/.bad-embedder", 262 CONTENT_SETTING_ALLOW); 263 } 264 265 GeolocationContentSettingsMap* map = 266 profile.GetGeolocationContentSettingsMap(); 267 EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting()); 268 269 // Check the valid entry was read OK. 270 EXPECT_EQ(CONTENT_SETTING_ALLOW, 271 map->GetContentSetting(GURL("http://a/"), GURL("http://b/"))); 272 // But everything else should be according to the default. 273 EXPECT_EQ(CONTENT_SETTING_ASK, 274 map->GetContentSetting(GURL("http://a/"), 275 GURL("http://bad-embedder"))); 276 EXPECT_EQ(CONTENT_SETTING_ASK, 277 map->GetContentSetting(GURL("http://a/"), 278 GURL("http://example.com"))); 279 EXPECT_EQ(CONTENT_SETTING_ASK, 280 map->GetContentSetting(GURL("http://bad_requester/"), 281 GURL("http://b/"))); 282 } 283 284 TEST_F(GeolocationContentSettingsMapTests, Observe) { 285 TestingProfile profile; 286 GeolocationContentSettingsMap* map = 287 profile.GetGeolocationContentSettingsMap(); 288 StubSettingsObserver observer; 289 290 EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting()); 291 292 // Test if a CONTENT_SETTING_CHANGE notification is sent after the geolocation 293 // default content setting was changed through calling the 294 // SetDefaultContentSetting method. 295 map->SetDefaultContentSetting(CONTENT_SETTING_BLOCK); 296 EXPECT_EQ(map, observer.last_notifier); 297 EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); 298 EXPECT_EQ(1, observer.counter); 299 300 301 // Test if a CONTENT_SETTING_CHANGE notification is sent after the preference 302 // GeolocationDefaultContentSetting was changed. 303 PrefService* prefs = profile.GetPrefs(); 304 prefs->SetInteger(prefs::kGeolocationDefaultContentSetting, 305 CONTENT_SETTING_ALLOW); 306 EXPECT_EQ(2, observer.counter); 307 EXPECT_EQ(map, observer.last_notifier); 308 EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); 309 EXPECT_EQ(CONTENT_SETTING_ALLOW, map->GetDefaultContentSetting()); 310 } 311 312 } // namespace 313