Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/extensions/api/preference/preference_api.h" | 5 #include "chrome/browser/extensions/api/preference/preference_api.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 void | 580 void |
| 581 BrowserContextKeyedAPIFactory<PreferenceAPI>::DeclareFactoryDependencies() { | 581 BrowserContextKeyedAPIFactory<PreferenceAPI>::DeclareFactoryDependencies() { |
| 582 DependsOn(ContentSettingsService::GetFactoryInstance()); | 582 DependsOn(ContentSettingsService::GetFactoryInstance()); |
| 583 DependsOn(ExtensionPrefsFactory::GetInstance()); | 583 DependsOn(ExtensionPrefsFactory::GetInstance()); |
| 584 DependsOn(ExtensionPrefValueMapFactory::GetInstance()); | 584 DependsOn(ExtensionPrefValueMapFactory::GetInstance()); |
| 585 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | 585 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); |
| 586 } | 586 } |
| 587 | 587 |
| 588 PreferenceFunction::~PreferenceFunction() { } | 588 PreferenceFunction::~PreferenceFunction() { } |
| 589 | 589 |
| 590 bool PreferenceFunction::ValidateBrowserPref( | |
| 591 const std::string& extension_pref_key, | |
| 592 PreferenceFunction::PermissionType permission_type, | |
| 593 std::string* browser_pref_key) { | |
| 594 APIPermission::ID read_permission = APIPermission::kInvalid; | |
| 595 APIPermission::ID write_permission = APIPermission::kInvalid; | |
| 596 EXTENSION_FUNCTION_VALIDATE( | |
|
Devlin
2016/10/10 19:28:26
Note: Removed this function because validation fai
| |
| 597 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( | |
| 598 extension_pref_key, | |
| 599 browser_pref_key, | |
| 600 &read_permission, | |
| 601 &write_permission)); | |
| 602 APIPermission::ID permission = permission_type == PERMISSION_TYPE_READ | |
| 603 ? read_permission | |
| 604 : write_permission; | |
| 605 if (!extension()->permissions_data()->HasAPIPermission(permission)) { | |
| 606 error_ = ErrorUtils::FormatErrorMessage( | |
| 607 keys::kPermissionErrorMessage, extension_pref_key); | |
| 608 return false; | |
| 609 } | |
| 610 return true; | |
| 611 } | |
| 612 | |
| 613 GetPreferenceFunction::~GetPreferenceFunction() { } | 590 GetPreferenceFunction::~GetPreferenceFunction() { } |
| 614 | 591 |
| 615 bool GetPreferenceFunction::RunSync() { | 592 ExtensionFunction::ResponseAction GetPreferenceFunction::Run() { |
| 616 std::string pref_key; | 593 std::string pref_key; |
| 617 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); | 594 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); |
| 618 base::DictionaryValue* details = NULL; | 595 base::DictionaryValue* details = NULL; |
| 619 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | 596 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); |
| 620 | 597 |
| 621 bool incognito = false; | 598 bool incognito = false; |
| 622 if (details->HasKey(keys::kIncognitoKey)) | 599 if (details->HasKey(keys::kIncognitoKey)) |
| 623 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kIncognitoKey, | 600 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kIncognitoKey, |
| 624 &incognito)); | 601 &incognito)); |
| 625 | 602 |
| 626 // Check incognito access. | 603 // Check incognito access. |
| 627 if (incognito && !include_incognito()) { | 604 if (incognito && !include_incognito()) |
| 628 error_ = keys::kIncognitoErrorMessage; | 605 return RespondNow(Error(keys::kIncognitoErrorMessage)); |
| 629 return false; | |
| 630 } | |
| 631 | 606 |
| 632 // Obtain pref. | 607 // Obtain pref. |
| 633 std::string browser_pref; | 608 std::string browser_pref; |
| 634 if (!ValidateBrowserPref( | 609 APIPermission::ID read_permission = APIPermission::kInvalid; |
| 635 pref_key, PreferenceFunction::PERMISSION_TYPE_READ, &browser_pref)) { | 610 APIPermission::ID write_permission = APIPermission::kInvalid; |
| 636 return false; | 611 EXTENSION_FUNCTION_VALIDATE( |
| 637 } | 612 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| 638 PrefService* prefs = incognito ? GetProfile()->GetOffTheRecordPrefs() | 613 pref_key, &browser_pref, &read_permission, &write_permission)); |
| 639 : GetProfile()->GetPrefs(); | 614 if (!extension()->permissions_data()->HasAPIPermission(read_permission)) |
| 615 return RespondNow(Error(keys::kPermissionErrorMessage, pref_key)); | |
| 616 | |
| 617 Profile* profile = Profile::FromBrowserContext(browser_context()); | |
| 618 PrefService* prefs = | |
| 619 incognito ? profile->GetOffTheRecordPrefs() : profile->GetPrefs(); | |
| 640 const PrefService::Preference* pref = | 620 const PrefService::Preference* pref = |
| 641 prefs->FindPreference(browser_pref.c_str()); | 621 prefs->FindPreference(browser_pref.c_str()); |
| 642 CHECK(pref); | 622 CHECK(pref); |
| 643 | 623 |
| 644 std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue); | 624 std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue); |
| 645 | 625 |
| 646 // Retrieve level of control. | 626 // Retrieve level of control. |
| 647 std::string level_of_control = helpers::GetLevelOfControl( | 627 std::string level_of_control = helpers::GetLevelOfControl( |
| 648 GetProfile(), extension_id(), browser_pref, incognito); | 628 profile, extension_id(), browser_pref, incognito); |
| 649 result->SetString(keys::kLevelOfControl, level_of_control); | 629 result->SetString(keys::kLevelOfControl, level_of_control); |
| 650 | 630 |
| 651 // Retrieve pref value. | 631 // Retrieve pref value. |
| 652 PrefTransformerInterface* transformer = | 632 PrefTransformerInterface* transformer = |
| 653 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); | 633 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); |
| 654 base::Value* transformed_value = | 634 base::Value* transformed_value = |
| 655 transformer->BrowserToExtensionPref(pref->GetValue()); | 635 transformer->BrowserToExtensionPref(pref->GetValue()); |
| 656 if (!transformed_value) { | 636 if (!transformed_value) { |
| 637 // TODO(devlin): Can this happen? When? Should it be an error, or a bad | |
| 638 // message? | |
| 657 LOG(ERROR) << | 639 LOG(ERROR) << |
| 658 ErrorUtils::FormatErrorMessage(kConversionErrorMessage, | 640 ErrorUtils::FormatErrorMessage(kConversionErrorMessage, |
| 659 pref->name()); | 641 pref->name()); |
| 660 return false; | 642 return RespondNow(Error(kUnknownErrorDoNotUse)); |
| 661 } | 643 } |
| 662 result->Set(keys::kValue, transformed_value); | 644 result->Set(keys::kValue, transformed_value); |
| 663 | 645 |
| 664 // Retrieve incognito status. | 646 // Retrieve incognito status. |
| 665 if (incognito) { | 647 if (incognito) { |
| 666 ExtensionPrefs* ep = ExtensionPrefs::Get(GetProfile()); | 648 ExtensionPrefs* ep = ExtensionPrefs::Get(browser_context()); |
| 667 result->SetBoolean(keys::kIncognitoSpecific, | 649 result->SetBoolean(keys::kIncognitoSpecific, |
| 668 ep->HasIncognitoPrefValue(browser_pref)); | 650 ep->HasIncognitoPrefValue(browser_pref)); |
| 669 } | 651 } |
| 670 | 652 |
| 671 SetResult(std::move(result)); | 653 return RespondNow(OneArgument(std::move(result))); |
| 672 return true; | |
| 673 } | 654 } |
| 674 | 655 |
| 675 SetPreferenceFunction::~SetPreferenceFunction() { } | 656 SetPreferenceFunction::~SetPreferenceFunction() { } |
| 676 | 657 |
| 677 bool SetPreferenceFunction::RunSync() { | 658 ExtensionFunction::ResponseAction SetPreferenceFunction::Run() { |
| 678 std::string pref_key; | 659 std::string pref_key; |
| 679 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); | 660 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); |
| 680 base::DictionaryValue* details = NULL; | 661 base::DictionaryValue* details = NULL; |
| 681 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | 662 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); |
| 682 | 663 |
| 683 base::Value* value = NULL; | 664 base::Value* value = NULL; |
| 684 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kValue, &value)); | 665 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kValue, &value)); |
| 685 | 666 |
| 686 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; | 667 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; |
| 687 if (details->HasKey(keys::kScopeKey)) { | 668 if (details->HasKey(keys::kScopeKey)) { |
| 688 std::string scope_str; | 669 std::string scope_str; |
| 689 EXTENSION_FUNCTION_VALIDATE( | 670 EXTENSION_FUNCTION_VALIDATE( |
| 690 details->GetString(keys::kScopeKey, &scope_str)); | 671 details->GetString(keys::kScopeKey, &scope_str)); |
| 691 | 672 |
| 692 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); | 673 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); |
| 693 } | 674 } |
| 694 | 675 |
| 695 // Check incognito scope. | 676 // Check incognito scope. |
| 696 bool incognito = | 677 bool incognito = |
| 697 (scope == kExtensionPrefsScopeIncognitoPersistent || | 678 (scope == kExtensionPrefsScopeIncognitoPersistent || |
| 698 scope == kExtensionPrefsScopeIncognitoSessionOnly); | 679 scope == kExtensionPrefsScopeIncognitoSessionOnly); |
| 699 if (incognito) { | 680 if (incognito) { |
| 700 // Regular profiles can't access incognito unless include_incognito is true. | 681 // Regular profiles can't access incognito unless include_incognito is true. |
| 701 if (!GetProfile()->IsOffTheRecord() && !include_incognito()) { | 682 if (!browser_context()->IsOffTheRecord() && !include_incognito()) |
| 702 error_ = keys::kIncognitoErrorMessage; | 683 return RespondNow(Error(keys::kIncognitoErrorMessage)); |
| 703 return false; | 684 } else if (browser_context()->IsOffTheRecord()) { |
| 704 } | |
| 705 } else { | |
| 706 // Incognito profiles can't access regular mode ever, they only exist in | 685 // Incognito profiles can't access regular mode ever, they only exist in |
| 707 // split mode. | 686 // split mode. |
| 708 if (GetProfile()->IsOffTheRecord()) { | 687 return RespondNow( |
| 709 error_ = "Can't modify regular settings from an incognito context."; | 688 Error("Can't modify regular settings from an incognito context.")); |
| 710 return false; | |
| 711 } | |
| 712 } | 689 } |
| 713 | 690 |
| 691 Profile* profile = Profile::FromBrowserContext(browser_context()); | |
| 714 if (scope == kExtensionPrefsScopeIncognitoSessionOnly && | 692 if (scope == kExtensionPrefsScopeIncognitoSessionOnly && |
| 715 !GetProfile()->HasOffTheRecordProfile()) { | 693 !profile->HasOffTheRecordProfile()) { |
| 716 error_ = keys::kIncognitoSessionOnlyErrorMessage; | 694 return RespondNow(Error(keys::kIncognitoSessionOnlyErrorMessage)); |
| 717 return false; | |
| 718 } | 695 } |
| 719 | 696 |
| 720 // Obtain pref. | 697 // Obtain pref. |
| 721 std::string browser_pref; | 698 std::string browser_pref; |
| 722 if (!ValidateBrowserPref( | 699 APIPermission::ID read_permission = APIPermission::kInvalid; |
| 723 pref_key, PreferenceFunction::PERMISSION_TYPE_WRITE, &browser_pref)) { | 700 APIPermission::ID write_permission = APIPermission::kInvalid; |
| 724 return false; | 701 EXTENSION_FUNCTION_VALIDATE( |
| 725 } | 702 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| 726 ExtensionPrefs* prefs = ExtensionPrefs::Get(GetProfile()); | 703 pref_key, &browser_pref, &read_permission, &write_permission)); |
| 704 if (!extension()->permissions_data()->HasAPIPermission(write_permission)) | |
| 705 return RespondNow(Error(keys::kPermissionErrorMessage, pref_key)); | |
| 706 | |
| 707 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context()); | |
| 727 const PrefService::Preference* pref = | 708 const PrefService::Preference* pref = |
| 728 prefs->pref_service()->FindPreference(browser_pref.c_str()); | 709 prefs->pref_service()->FindPreference(browser_pref.c_str()); |
| 729 CHECK(pref); | 710 CHECK(pref); |
| 730 | 711 |
| 731 // Validate new value. | 712 // Validate new value. |
| 732 PrefTransformerInterface* transformer = | 713 PrefTransformerInterface* transformer = |
| 733 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); | 714 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); |
| 734 std::string error; | 715 std::string error; |
| 735 bool bad_message = false; | 716 bool bad_message = false; |
| 736 std::unique_ptr<base::Value> browser_pref_value( | 717 std::unique_ptr<base::Value> browser_pref_value( |
| 737 transformer->ExtensionToBrowserPref(value, &error, &bad_message)); | 718 transformer->ExtensionToBrowserPref(value, &error, &bad_message)); |
| 738 if (!browser_pref_value) { | 719 if (!browser_pref_value) { |
| 739 error_ = error; | 720 EXTENSION_FUNCTION_VALIDATE(!bad_message); |
| 740 set_bad_message(bad_message); | 721 return RespondNow(Error(error)); |
| 741 return false; | |
| 742 } | 722 } |
| 743 EXTENSION_FUNCTION_VALIDATE(browser_pref_value->GetType() == pref->GetType()); | 723 EXTENSION_FUNCTION_VALIDATE(browser_pref_value->GetType() == pref->GetType()); |
| 744 | 724 |
| 745 // Validate also that the stored value can be converted back by the | 725 // Validate also that the stored value can be converted back by the |
| 746 // transformer. | 726 // transformer. |
| 747 std::unique_ptr<base::Value> extensionPrefValue( | 727 std::unique_ptr<base::Value> extension_pref_value( |
| 748 transformer->BrowserToExtensionPref(browser_pref_value.get())); | 728 transformer->BrowserToExtensionPref(browser_pref_value.get())); |
| 749 if (!extensionPrefValue) { | 729 EXTENSION_FUNCTION_VALIDATE(extension_pref_value); |
| 750 error_ = ErrorUtils::FormatErrorMessage(kConversionErrorMessage, | |
| 751 pref->name()); | |
| 752 set_bad_message(true); | |
| 753 return false; | |
| 754 } | |
| 755 | 730 |
| 756 PreferenceAPI::Get(GetProfile())->SetExtensionControlledPref( | 731 PreferenceAPI::Get(browser_context()) |
| 757 extension_id(), browser_pref, scope, browser_pref_value.release()); | 732 ->SetExtensionControlledPref(extension_id(), browser_pref, scope, |
| 758 return true; | 733 browser_pref_value.release()); |
| 734 return RespondNow(NoArguments()); | |
| 759 } | 735 } |
| 760 | 736 |
| 761 ClearPreferenceFunction::~ClearPreferenceFunction() { } | 737 ClearPreferenceFunction::~ClearPreferenceFunction() { } |
| 762 | 738 |
| 763 bool ClearPreferenceFunction::RunSync() { | 739 ExtensionFunction::ResponseAction ClearPreferenceFunction::Run() { |
| 764 std::string pref_key; | 740 std::string pref_key; |
| 765 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); | 741 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); |
| 766 base::DictionaryValue* details = NULL; | 742 base::DictionaryValue* details = NULL; |
| 767 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | 743 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); |
| 768 | 744 |
| 769 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; | 745 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; |
| 770 if (details->HasKey(keys::kScopeKey)) { | 746 if (details->HasKey(keys::kScopeKey)) { |
| 771 std::string scope_str; | 747 std::string scope_str; |
| 772 EXTENSION_FUNCTION_VALIDATE( | 748 EXTENSION_FUNCTION_VALIDATE( |
| 773 details->GetString(keys::kScopeKey, &scope_str)); | 749 details->GetString(keys::kScopeKey, &scope_str)); |
| 774 | 750 |
| 775 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); | 751 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); |
| 776 } | 752 } |
| 777 | 753 |
| 778 // Check incognito scope. | 754 // Check incognito scope. |
| 779 bool incognito = | 755 bool incognito = |
| 780 (scope == kExtensionPrefsScopeIncognitoPersistent || | 756 (scope == kExtensionPrefsScopeIncognitoPersistent || |
| 781 scope == kExtensionPrefsScopeIncognitoSessionOnly); | 757 scope == kExtensionPrefsScopeIncognitoSessionOnly); |
| 782 if (incognito) { | 758 if (incognito) { |
| 783 // We don't check incognito permissions here, as an extension should be | 759 // We don't check incognito permissions here, as an extension should be |
| 784 // always allowed to clear its own settings. | 760 // always allowed to clear its own settings. |
| 785 } else { | 761 } else if (browser_context()->IsOffTheRecord()) { |
| 786 // Incognito profiles can't access regular mode ever, they only exist in | 762 // Incognito profiles can't access regular mode ever, they only exist in |
| 787 // split mode. | 763 // split mode. |
| 788 if (GetProfile()->IsOffTheRecord()) { | 764 return RespondNow( |
| 789 error_ = "Can't modify regular settings from an incognito context."; | 765 Error("Can't modify regular settings from an incognito context.")); |
| 790 return false; | |
| 791 } | |
| 792 } | 766 } |
| 793 | 767 |
| 794 std::string browser_pref; | 768 std::string browser_pref; |
| 795 if (!ValidateBrowserPref( | 769 APIPermission::ID read_permission = APIPermission::kInvalid; |
| 796 pref_key, PreferenceFunction::PERMISSION_TYPE_WRITE, &browser_pref)) { | 770 APIPermission::ID write_permission = APIPermission::kInvalid; |
| 797 return false; | 771 EXTENSION_FUNCTION_VALIDATE( |
| 798 } | 772 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| 773 pref_key, &browser_pref, &read_permission, &write_permission)); | |
| 774 if (!extension()->permissions_data()->HasAPIPermission(write_permission)) | |
| 775 return RespondNow(Error(keys::kPermissionErrorMessage, pref_key)); | |
| 799 | 776 |
| 800 PreferenceAPI::Get(GetProfile()) | 777 PreferenceAPI::Get(browser_context()) |
| 801 ->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); | 778 ->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); |
| 802 return true; | 779 return RespondNow(NoArguments()); |
| 803 } | 780 } |
| 804 | 781 |
| 805 } // namespace extensions | 782 } // namespace extensions |
| OLD | NEW |