| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/webui/site_settings_helper.h" | 5 #include "chrome/browser/ui/webui/site_settings_helper.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "chrome/browser/permissions/chooser_context_base.h" |
| 9 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
| 11 #include "chrome/browser/usb/usb_chooser_context_factory.h" |
| 10 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
| 11 #include "components/content_settings/core/browser/host_content_settings_map.h" | 13 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 12 #include "components/prefs/pref_service.h" | 14 #include "components/prefs/pref_service.h" |
| 13 | 15 |
| 14 namespace site_settings { | 16 namespace site_settings { |
| 15 | 17 |
| 16 const char kSetting[] = "setting"; | 18 const char kSetting[] = "setting"; |
| 17 const char kOrigin[] = "origin"; | 19 const char kOrigin[] = "origin"; |
| 18 const char kPolicyProviderId[] = "policy"; | 20 const char kPolicyProviderId[] = "policy"; |
| 19 const char kSource[] = "source"; | 21 const char kSource[] = "source"; |
| 20 const char kEmbeddingOrigin[] = "embeddingOrigin"; | 22 const char kEmbeddingOrigin[] = "embeddingOrigin"; |
| 21 const char kPreferencesSource[] = "preference"; | 23 const char kPreferencesSource[] = "preference"; |
| 24 const char kObject[] = "object"; |
| 25 const char kObjectName[] = "objectName"; |
| 22 | 26 |
| 23 struct ContentSettingsTypeNameEntry { | 27 const char kGroupTypeUsb[] = "usb-devices"; |
| 24 ContentSettingsType type; | |
| 25 const char* name; | |
| 26 }; | |
| 27 | 28 |
| 28 const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { | 29 ChooserContextBase* GetUsbChooserContext(Profile* profile) { |
| 29 {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"}, | 30 return reinterpret_cast<ChooserContextBase*>( |
| 30 {CONTENT_SETTINGS_TYPE_IMAGES, "images"}, | 31 UsbChooserContextFactory::GetForProfile(profile)); |
| 31 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"}, | 32 } |
| 32 {CONTENT_SETTINGS_TYPE_PLUGINS, "plugins"}, | 33 |
| 33 {CONTENT_SETTINGS_TYPE_POPUPS, "popups"}, | 34 namespace { |
| 34 {CONTENT_SETTINGS_TYPE_GEOLOCATION, "location"}, | 35 |
| 35 {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications"}, | 36 // Maps from the UI string to the object it represents (for sorting purposes). |
| 36 {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, "auto-select-certificate"}, | 37 typedef std::multimap<std::string, const base::DictionaryValue*> SortedObjects; |
| 37 {CONTENT_SETTINGS_TYPE_FULLSCREEN, "fullscreen"}, | 38 |
| 38 {CONTENT_SETTINGS_TYPE_MOUSELOCK, "mouselock"}, | 39 // Maps from a secondary URL to the set of objects it has permission to access. |
| 39 {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, "register-protocol-handler"}, | 40 typedef std::map<GURL, SortedObjects> OneOriginObjects; |
| 40 {CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, "media-stream-mic"}, | 41 |
| 41 {CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, "media-stream-camera"}, | 42 // Maps from a primary URL/source pair to a OneOriginObjects. All the mappings |
| 42 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, "ppapi-broker"}, | 43 // in OneOriginObjects share the given primary URL and source. |
| 43 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, "multiple-automatic-downloads"}, | 44 typedef std::map<std::pair<GURL, std::string>, OneOriginObjects> |
| 44 {CONTENT_SETTINGS_TYPE_MIDI_SYSEX, "midi-sysex"}, | 45 AllOriginObjects; |
| 45 {CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, "ssl-cert-decisions"}, | 46 |
| 46 #if defined(OS_CHROMEOS) | 47 } // namespace |
| 47 {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, "protectedContent"}, | |
| 48 #endif | |
| 49 {CONTENT_SETTINGS_TYPE_KEYGEN, "keygen"}, | |
| 50 {CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, "background-sync"}, | |
| 51 }; | |
| 52 | 48 |
| 53 bool HasRegisteredGroupName(ContentSettingsType type) { | 49 bool HasRegisteredGroupName(ContentSettingsType type) { |
| 54 for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) { | 50 for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) { |
| 55 if (type == kContentSettingsTypeGroupNames[i].type) | 51 if (type == kContentSettingsTypeGroupNames[i].type) |
| 56 return true; | 52 return true; |
| 57 } | 53 } |
| 58 return false; | 54 return false; |
| 59 } | 55 } |
| 60 | 56 |
| 61 ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) { | 57 ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 std::sort( | 221 std::sort( |
| 226 patterns.begin(), patterns.end(), std::greater<ContentSettingsPattern>()); | 222 patterns.begin(), patterns.end(), std::greater<ContentSettingsPattern>()); |
| 227 | 223 |
| 228 for (const ContentSettingsPattern& pattern : patterns) { | 224 for (const ContentSettingsPattern& pattern : patterns) { |
| 229 exceptions->push_back(GetExceptionForPage(pattern, ContentSettingsPattern(), | 225 exceptions->push_back(GetExceptionForPage(pattern, ContentSettingsPattern(), |
| 230 CONTENT_SETTING_ALLOW, | 226 CONTENT_SETTING_ALLOW, |
| 231 kPolicyProviderId)); | 227 kPolicyProviderId)); |
| 232 } | 228 } |
| 233 } | 229 } |
| 234 | 230 |
| 231 const ChooserTypeNameEntry* ChooserTypeFromGroupName(const std::string& name) { |
| 232 for (const auto& chooser_type : kChooserTypeGroupNames) { |
| 233 if (chooser_type.name == name) |
| 234 return &chooser_type; |
| 235 } |
| 236 return nullptr; |
| 237 } |
| 238 |
| 239 // Create a DictionaryValue* that will act as a data source for a single row |
| 240 // in a chooser permission exceptions table. |
| 241 std::unique_ptr<base::DictionaryValue> GetChooserExceptionForPage( |
| 242 const GURL& requesting_origin, |
| 243 const GURL& embedding_origin, |
| 244 const std::string& provider_name, |
| 245 const std::string& name, |
| 246 const base::DictionaryValue* object) { |
| 247 std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue()); |
| 248 |
| 249 std::string setting_string = |
| 250 content_settings::ContentSettingToString(CONTENT_SETTING_DEFAULT); |
| 251 DCHECK(!setting_string.empty()); |
| 252 |
| 253 exception->SetString(site_settings::kSetting, setting_string); |
| 254 exception->SetString(site_settings::kOrigin, requesting_origin.spec()); |
| 255 exception->SetString( |
| 256 site_settings::kEmbeddingOrigin, embedding_origin.spec()); |
| 257 exception->SetString(site_settings::kSource, provider_name); |
| 258 if (object) { |
| 259 exception->SetString(kObjectName, name); |
| 260 exception->Set(kObject, object->CreateDeepCopy()); |
| 261 } |
| 262 return exception; |
| 263 } |
| 264 |
| 265 void GetChooserExceptionsFromProfile( |
| 266 Profile* profile, |
| 267 bool incognito, |
| 268 const ChooserTypeNameEntry& chooser_type, |
| 269 base::ListValue* exceptions) { |
| 270 if (incognito) { |
| 271 if (!profile->HasOffTheRecordProfile()) |
| 272 return; |
| 273 profile = profile->GetOffTheRecordProfile(); |
| 274 } |
| 275 |
| 276 ChooserContextBase* chooser_context = chooser_type.get_context(profile); |
| 277 std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = |
| 278 chooser_context->GetAllGrantedObjects(); |
| 279 AllOriginObjects all_origin_objects; |
| 280 for (const auto& object : objects) { |
| 281 std::string name; |
| 282 bool found = object->object.GetString(chooser_type.ui_name_key, &name); |
| 283 DCHECK(found); |
| 284 // It is safe for this structure to hold references into |objects| because |
| 285 // they are both destroyed at the end of this function. |
| 286 all_origin_objects[make_pair(object->requesting_origin, |
| 287 object->source)][object->embedding_origin] |
| 288 .insert(make_pair(name, &object->object)); |
| 289 } |
| 290 |
| 291 // Keep the exceptions sorted by provider so they will be displayed in |
| 292 // precedence order. |
| 293 std::vector<std::unique_ptr<base::DictionaryValue>> |
| 294 all_provider_exceptions[HostContentSettingsMap::NUM_PROVIDER_TYPES]; |
| 295 |
| 296 for (const auto& all_origin_objects_entry : all_origin_objects) { |
| 297 const GURL& requesting_origin = all_origin_objects_entry.first.first; |
| 298 const std::string& source = all_origin_objects_entry.first.second; |
| 299 const OneOriginObjects& one_origin_objects = |
| 300 all_origin_objects_entry.second; |
| 301 |
| 302 auto& this_provider_exceptions = all_provider_exceptions |
| 303 [HostContentSettingsMap::GetProviderTypeFromSource(source)]; |
| 304 |
| 305 // Add entries for any non-embedded origins. |
| 306 bool has_embedded_entries = false; |
| 307 for (const auto& one_origin_objects_entry : one_origin_objects) { |
| 308 const GURL& embedding_origin = one_origin_objects_entry.first; |
| 309 const SortedObjects& sorted_objects = one_origin_objects_entry.second; |
| 310 |
| 311 // Skip the embedded settings which will be added below. |
| 312 if (requesting_origin != embedding_origin) { |
| 313 has_embedded_entries = true; |
| 314 continue; |
| 315 } |
| 316 |
| 317 for (const auto& sorted_objects_entry : sorted_objects) { |
| 318 this_provider_exceptions.push_back(GetChooserExceptionForPage( |
| 319 requesting_origin, embedding_origin, source, |
| 320 sorted_objects_entry.first, sorted_objects_entry.second)); |
| 321 } |
| 322 } |
| 323 |
| 324 if (has_embedded_entries) { |
| 325 // Add a "parent" entry that simply acts as a heading for all entries |
| 326 // where |requesting_origin| has been embedded. |
| 327 this_provider_exceptions.push_back( |
| 328 GetChooserExceptionForPage(requesting_origin, requesting_origin, |
| 329 source, std::string(), nullptr)); |
| 330 |
| 331 // Add the "children" for any embedded settings. |
| 332 for (const auto& one_origin_objects_entry : one_origin_objects) { |
| 333 const GURL& embedding_origin = one_origin_objects_entry.first; |
| 334 const SortedObjects& sorted_objects = one_origin_objects_entry.second; |
| 335 |
| 336 // Skip the non-embedded setting which we already added above. |
| 337 if (requesting_origin == embedding_origin) |
| 338 continue; |
| 339 |
| 340 for (const auto& sorted_objects_entry : sorted_objects) { |
| 341 this_provider_exceptions.push_back(GetChooserExceptionForPage( |
| 342 requesting_origin, embedding_origin, source, |
| 343 sorted_objects_entry.first, sorted_objects_entry.second)); |
| 344 } |
| 345 } |
| 346 } |
| 347 } |
| 348 |
| 349 for (auto& one_provider_exceptions : all_provider_exceptions) { |
| 350 for (auto& exception : one_provider_exceptions) |
| 351 exceptions->Append(std::move(exception)); |
| 352 } |
| 353 } |
| 354 |
| 235 } // namespace site_settings | 355 } // namespace site_settings |
| OLD | NEW |