diff options
author | treib <treib@chromium.org> | 2015-03-04 10:29:06 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-04 18:30:03 +0000 |
commit | 8ecc1eb5c39ec46c20e410195ef454d5116239c5 (patch) | |
tree | b0ef4cc0766034b5f2c9ddb7a72e16b0cec1788f /chrome/browser/supervised_user | |
parent | fe3f7ae8eb9390a4fe3f59e6244d4bbd6af7a9cd (diff) | |
download | chromium_src-8ecc1eb5c39ec46c20e410195ef454d5116239c5.zip chromium_src-8ecc1eb5c39ec46c20e410195ef454d5116239c5.tar.gz chromium_src-8ecc1eb5c39ec46c20e410195ef454d5116239c5.tar.bz2 |
Supervised users: When an extension requires new permissions, send request to custodian
BUG=397951
Review URL: https://codereview.chromium.org/971733003
Cr-Commit-Position: refs/heads/master@{#319086}
Diffstat (limited to 'chrome/browser/supervised_user')
10 files changed, 169 insertions, 67 deletions
diff --git a/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.cc b/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.cc index 37a7ce6..668fe4a 100644 --- a/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.cc +++ b/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.cc @@ -33,34 +33,47 @@ const char kApiUrl[] = const char kApiScope[] = "https://www.googleapis.com/auth/kid.permission"; const int kNumRetries = 1; -const char kNamespace[] = "PERMISSION_CHROME_URL"; + +const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; + +// Request keys. +const char kNamespaceKey[] = "namespace"; +const char kObjectRefKey[] = "objectRef"; +const char kStateKey[] = "state"; + +// Request values. +const char kNamespaceURLRequest[] = "PERMISSION_CHROME_URL"; +const char kNamespaceUpdateRequest[] = "PERMISSION_CHROME_CWS_ITEM_UPDATE"; const char kState[] = "PENDING"; +// Response keys. const char kPermissionRequestKey[] = "permissionRequest"; const char kIdKey[] = "id"; -static const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; - struct PermissionRequestCreatorApiary::Request { - Request(const GURL& url_requested, + Request(const std::string& request_namespace, + const std::string& object_ref, const SuccessCallback& callback, int url_fetcher_id); ~Request(); - GURL url_requested; + std::string request_namespace; + std::string object_ref; SuccessCallback callback; scoped_ptr<OAuth2TokenService::Request> access_token_request; std::string access_token; bool access_token_expired; int url_fetcher_id; - scoped_ptr<net::URLFetcher> url_fetcher; + scoped_ptr<URLFetcher> url_fetcher; }; PermissionRequestCreatorApiary::Request::Request( - const GURL& url_requested, + const std::string& request_namespace, + const std::string& object_ref, const SuccessCallback& callback, int url_fetcher_id) - : url_requested(url_requested), + : request_namespace(request_namespace), + object_ref(object_ref), callback(callback), access_token_expired(false), url_fetcher_id(url_fetcher_id) { @@ -97,11 +110,16 @@ bool PermissionRequestCreatorApiary::IsEnabled() const { return true; } -void PermissionRequestCreatorApiary::CreatePermissionRequest( +void PermissionRequestCreatorApiary::CreateURLAccessRequest( const GURL& url_requested, const SuccessCallback& callback) { - requests_.push_back(new Request(url_requested, callback, url_fetcher_id_)); - StartFetching(requests_.back()); + CreateRequest(kNamespaceURLRequest, url_requested.spec(), callback); +} + +void PermissionRequestCreatorApiary::CreateExtensionUpdateRequest( + const std::string& extension_id, + const SuccessCallback& callback) { + CreateRequest(kNamespaceUpdateRequest, extension_id, callback); } GURL PermissionRequestCreatorApiary::GetApiUrl() const { @@ -127,6 +145,15 @@ std::string PermissionRequestCreatorApiary::GetApiScope() const { } } +void PermissionRequestCreatorApiary::CreateRequest( + const std::string& request_namespace, + const std::string& object_ref, + const SuccessCallback& callback) { + requests_.push_back( + new Request(request_namespace, object_ref, callback, url_fetcher_id_)); + StartFetching(requests_.back()); +} + void PermissionRequestCreatorApiary::StartFetching(Request* request) { OAuth2TokenService::ScopeSet scopes; scopes.insert(GetApiScope()); @@ -160,9 +187,10 @@ void PermissionRequestCreatorApiary::OnGetTokenSuccess( base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); base::DictionaryValue dict; - dict.SetStringWithoutPathExpansion("namespace", kNamespace); - dict.SetStringWithoutPathExpansion("objectRef", (*it)->url_requested.spec()); - dict.SetStringWithoutPathExpansion("state", kState); + dict.SetStringWithoutPathExpansion(kNamespaceKey, (*it)->request_namespace); + dict.SetStringWithoutPathExpansion(kObjectRefKey, (*it)->object_ref); + dict.SetStringWithoutPathExpansion(kStateKey, kState); + std::string body; base::JSONWriter::Write(&dict, &body); (*it)->url_fetcher->SetUploadData("application/json", body); diff --git a/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.h b/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.h index 14a6aa8..9556d68 100644 --- a/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.h +++ b/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.h @@ -40,8 +40,10 @@ class PermissionRequestCreatorApiary : public PermissionRequestCreator, // PermissionRequestCreator implementation: bool IsEnabled() const override; - void CreatePermissionRequest(const GURL& url_requested, - const SuccessCallback& callback) override; + void CreateURLAccessRequest(const GURL& url_requested, + const SuccessCallback& callback) override; + void CreateExtensionUpdateRequest(const std::string& extension_id, + const SuccessCallback& callback) override; void set_url_fetcher_id_for_testing(int id) { url_fetcher_id_ = id; } @@ -62,6 +64,10 @@ class PermissionRequestCreatorApiary : public PermissionRequestCreator, GURL GetApiUrl() const; std::string GetApiScope() const; + void CreateRequest(const std::string& request_namespace, + const std::string& object_ref, + const SuccessCallback& callback); + // Requests an access token, which is the first thing we need. This is where // we restart when the returned access token has expired. void StartFetching(Request* request); diff --git a/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc b/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc index 35a8693..50b4443 100644 --- a/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc +++ b/chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc @@ -56,7 +56,7 @@ class PermissionRequestCreatorApiaryTest : public testing::Test { void CreateRequest(int url_fetcher_id, const GURL& url) { permission_creator_.set_url_fetcher_id_for_testing(url_fetcher_id); - permission_creator_.CreatePermissionRequest( + permission_creator_.CreateURLAccessRequest( url, base::Bind(&PermissionRequestCreatorApiaryTest::OnRequestCreated, base::Unretained(this))); diff --git a/chrome/browser/supervised_user/legacy/permission_request_creator_sync.cc b/chrome/browser/supervised_user/legacy/permission_request_creator_sync.cc index a4402e8..0bba1ce 100644 --- a/chrome/browser/supervised_user/legacy/permission_request_creator_sync.cc +++ b/chrome/browser/supervised_user/legacy/permission_request_creator_sync.cc @@ -13,10 +13,10 @@ #include "net/base/escape.h" #include "url/gurl.h" -using base::Time; - const char kSupervisedUserAccessRequestKeyPrefix[] = "X-ManagedUser-AccessRequests"; +const char kSupervisedUserUpdateRequestKeyPrefix[] = + "X-ManagedUser-UpdateRequests"; const char kSupervisedUserAccessRequestTime[] = "timestamp"; const char kSupervisedUserName[] = "name"; @@ -48,20 +48,33 @@ bool PermissionRequestCreatorSync::IsEnabled() const { state == GoogleServiceAuthError::SERVICE_UNAVAILABLE); } -void PermissionRequestCreatorSync::CreatePermissionRequest( +void PermissionRequestCreatorSync::CreateURLAccessRequest( const GURL& url_requested, const SuccessCallback& callback) { - // Escape the URL and add the prefix. + CreateRequest(kSupervisedUserAccessRequestKeyPrefix, + url_requested.spec(), + callback); +} + +void PermissionRequestCreatorSync::CreateExtensionUpdateRequest( + const std::string& extension_id, + const SuccessCallback& callback) { + CreateRequest(kSupervisedUserUpdateRequestKeyPrefix, extension_id, callback); +} + +void PermissionRequestCreatorSync::CreateRequest( + const std::string& prefix, + const std::string& data, + const SuccessCallback& callback) { + // Escape the data string and add the prefix. std::string key = SupervisedUserSettingsService::MakeSplitSettingKey( - kSupervisedUserAccessRequestKeyPrefix, - net::EscapeQueryParamValue(url_requested.spec(), true)); + prefix, + net::EscapeQueryParamValue(data, true)); scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); - // TODO(sergiu): Use sane time here when it's ready. dict->SetDouble(kSupervisedUserAccessRequestTime, base::Time::Now().ToJsTime()); - dict->SetString(kSupervisedUserName, name_); // Copy the notification setting of the custodian. diff --git a/chrome/browser/supervised_user/legacy/permission_request_creator_sync.h b/chrome/browser/supervised_user/legacy/permission_request_creator_sync.h index 0ba5eaa..552dca0 100644 --- a/chrome/browser/supervised_user/legacy/permission_request_creator_sync.h +++ b/chrome/browser/supervised_user/legacy/permission_request_creator_sync.h @@ -14,6 +14,9 @@ class ProfileSyncService; class SupervisedUserSettingsService; class SupervisedUserSharedSettingsService; +// The requests are stored using a prefix followed by a URIEncoded version of +// the URL/extension ID. Each entry contains a dictionary which currently has +// the timestamp of the request in it. class PermissionRequestCreatorSync : public PermissionRequestCreator { public: PermissionRequestCreatorSync( @@ -26,10 +29,15 @@ class PermissionRequestCreatorSync : public PermissionRequestCreator { // PermissionRequestCreator implementation: bool IsEnabled() const override; - void CreatePermissionRequest(const GURL& url_requested, - const SuccessCallback& callback) override; + void CreateURLAccessRequest(const GURL& url_requested, + const SuccessCallback& callback) override; + void CreateExtensionUpdateRequest(const std::string& extension_id, + const SuccessCallback& callback) override; private: + void CreateRequest(const std::string& prefix, + const std::string& data, + const SuccessCallback& callback); SupervisedUserSettingsService* settings_service_; SupervisedUserSharedSettingsService* shared_settings_service_; ProfileSyncService* sync_service_; diff --git a/chrome/browser/supervised_user/permission_request_creator.h b/chrome/browser/supervised_user/permission_request_creator.h index 6237431..549f0c9 100644 --- a/chrome/browser/supervised_user/permission_request_creator.h +++ b/chrome/browser/supervised_user/permission_request_creator.h @@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_ #define CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_ +#include <string> + #include "base/callback_forward.h" class GURL; @@ -23,8 +25,14 @@ class PermissionRequestCreator { // Creates a permission request for |url_requested| and calls |callback| with // the result (whether creating the permission request was successful). - virtual void CreatePermissionRequest(const GURL& url_requested, - const SuccessCallback& callback) = 0; + virtual void CreateURLAccessRequest(const GURL& url_requested, + const SuccessCallback& callback) = 0; + + // Creates a request to re-enable the extension with the given |extension_id|, + // which was disabled due to a permission increase. + virtual void CreateExtensionUpdateRequest( + const std::string& extension_id, + const SuccessCallback& callback) = 0; }; #endif // CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_ diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc index 65798dc..fe59b98 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.cc +++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc @@ -311,7 +311,7 @@ void SupervisedUserInterstitial::CommandReceived(const std::string& command) { SupervisedUserService* supervised_user_service = SupervisedUserServiceFactory::GetForProfile(profile_); - supervised_user_service->AddAccessRequest( + supervised_user_service->AddURLAccessRequest( url_, base::Bind(&SupervisedUserInterstitial::OnAccessRequestAdded, weak_ptr_factory_.GetWeakPtr())); return; diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index e464400..102b9f5 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc @@ -78,6 +78,20 @@ const char* const kCustodianInfoPrefs[] = { prefs::kSupervisedUserSecondCustodianProfileURL, }; +void CreateURLAccessRequest( + const GURL& url, + PermissionRequestCreator* creator, + const SupervisedUserService::SuccessCallback& callback) { + creator->CreateURLAccessRequest(url, callback); +} + +void CreateExtensionUpdateRequest( + const std::string& extension_id, + PermissionRequestCreator* creator, + const SupervisedUserService::SuccessCallback& callback) { + creator->CreateExtensionUpdateRequest(extension_id, callback); +} + #if defined(ENABLE_EXTENSIONS) enum ExtensionState { EXTENSION_FORCED, @@ -531,8 +545,8 @@ size_t SupervisedUserService::FindEnabledPermissionRequestCreator( return permissions_creators_.size(); } -void SupervisedUserService::AddAccessRequestInternal( - const GURL& url, +void SupervisedUserService::AddPermissionRequestInternal( + const CreatePermissionRequestCallback& create_request, const SuccessCallback& callback, size_t index) { // Find a permission request creator that is enabled. @@ -542,14 +556,15 @@ void SupervisedUserService::AddAccessRequestInternal( return; } - permissions_creators_[next_index]->CreatePermissionRequest( - url, + create_request.Run( + permissions_creators_[next_index], base::Bind(&SupervisedUserService::OnPermissionRequestIssued, - weak_ptr_factory_.GetWeakPtr(), url, callback, next_index)); + weak_ptr_factory_.GetWeakPtr(), create_request, + callback, next_index)); } void SupervisedUserService::OnPermissionRequestIssued( - const GURL& url, + const CreatePermissionRequestCallback& create_request, const SuccessCallback& callback, size_t index, bool success) { @@ -558,7 +573,7 @@ void SupervisedUserService::OnPermissionRequestIssued( return; } - AddAccessRequestInternal(url, callback, index + 1); + AddPermissionRequestInternal(create_request, callback, index + 1); } void SupervisedUserService::OnSupervisedUserIdChanged() { @@ -631,10 +646,21 @@ bool SupervisedUserService::AccessRequestsEnabled() { return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size(); } -void SupervisedUserService::AddAccessRequest(const GURL& url, - const SuccessCallback& callback) { - AddAccessRequestInternal(SupervisedUserURLFilter::Normalize(url), callback, - 0); +void SupervisedUserService::AddURLAccessRequest( + const GURL& url, + const SuccessCallback& callback) { + AddPermissionRequestInternal( + base::Bind(CreateURLAccessRequest, + SupervisedUserURLFilter::Normalize(url)), + callback, 0); +} + +void SupervisedUserService::AddExtensionUpdateRequest( + const std::string& extension_id, + const SuccessCallback& callback) { + AddPermissionRequestInternal( + base::Bind(CreateExtensionUpdateRequest, extension_id), + callback, 0); } void SupervisedUserService::InitSync(const std::string& refresh_token) { diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h index e4b77e1..6757352 100644 --- a/chrome/browser/supervised_user/supervised_user_service.h +++ b/chrome/browser/supervised_user/supervised_user_service.h @@ -69,9 +69,9 @@ class SupervisedUserService : public KeyedService, public chrome::BrowserListObserver, public SupervisedUserURLFilter::Observer { public: - typedef base::Callback<void(content::WebContents*)> NavigationBlockedCallback; - typedef base::Callback<void(const GoogleServiceAuthError&)> AuthErrorCallback; - typedef base::Callback<void(bool)> SuccessCallback; + using NavigationBlockedCallback = base::Callback<void(content::WebContents*)>; + using AuthErrorCallback = base::Callback<void(const GoogleServiceAuthError&)>; + using SuccessCallback = base::Callback<void(bool)>; class Delegate { public: @@ -111,13 +111,16 @@ class SupervisedUserService : public KeyedService, // Returns the whitelist service. SupervisedUserWhitelistService* GetWhitelistService(); - // Whether the user can request access to blocked URLs. + // Whether the user can request to get access to blocked URLs or to new + // extensions. bool AccessRequestsEnabled(); - // Adds an access request for the given URL. The requests are stored using - // a prefix followed by a URIEncoded version of the URL. Each entry contains - // a dictionary which currently has the timestamp of the request in it. - void AddAccessRequest(const GURL& url, const SuccessCallback& callback); + // Adds an access request for the given URL. + void AddURLAccessRequest(const GURL& url, const SuccessCallback& callback); + + // Adds an update request for the given WebStore item (App/Extension). + void AddExtensionUpdateRequest(const std::string& extension_id, + const SuccessCallback& callback); // Returns the email address of the custodian. std::string GetCustodianEmailAddress() const; @@ -186,6 +189,9 @@ class SupervisedUserService : public KeyedService, FRIEND_TEST_ALL_PREFIXES(SupervisedUserServiceExtensionTest, ExtensionManagementPolicyProvider); + using CreatePermissionRequestCallback = + base::Callback<void(PermissionRequestCreator*, const SuccessCallback&)>; + // A bridge from the UI thread to the SupervisedUserURLFilters, one of which // lives on the IO thread. This class mediates access to them and makes sure // they are kept in sync. @@ -266,13 +272,15 @@ class SupervisedUserService : public KeyedService, SupervisedUserSettingsService* GetSettingsService(); size_t FindEnabledPermissionRequestCreator(size_t start); - void AddAccessRequestInternal(const GURL& url, - const SuccessCallback& callback, - size_t index); - void OnPermissionRequestIssued(const GURL& url, - const SuccessCallback& callback, - size_t index, - bool success); + void AddPermissionRequestInternal( + const CreatePermissionRequestCallback& create_request, + const SuccessCallback& callback, + size_t index); + void OnPermissionRequestIssued( + const CreatePermissionRequestCallback& create_request, + const SuccessCallback& callback, + size_t index, + bool success); void OnSupervisedUserIdChanged(); diff --git a/chrome/browser/supervised_user/supervised_user_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_service_unittest.cc index 5e604a7..fa41642 100644 --- a/chrome/browser/supervised_user/supervised_user_service_unittest.cc +++ b/chrome/browser/supervised_user/supervised_user_service_unittest.cc @@ -190,8 +190,8 @@ class SupervisedUserServiceTest : public ::testing::Test { ~SupervisedUserServiceTest() override {} protected: - void AddAccessRequest(const GURL& url, AsyncResultHolder* result_holder) { - supervised_user_service_->AddAccessRequest( + void AddURLAccessRequest(const GURL& url, AsyncResultHolder* result_holder) { + supervised_user_service_->AddURLAccessRequest( url, base::Bind(&AsyncResultHolder::SetResult, base::Unretained(result_holder))); } @@ -249,13 +249,18 @@ class MockPermissionRequestCreator : public PermissionRequestCreator { // PermissionRequestCreator: bool IsEnabled() const override { return enabled_; } - void CreatePermissionRequest(const GURL& url_requested, - const SuccessCallback& callback) override { + void CreateURLAccessRequest(const GURL& url_requested, + const SuccessCallback& callback) override { ASSERT_TRUE(enabled_); requested_urls_.push_back(url_requested); callbacks_.push_back(callback); } + void CreateExtensionUpdateRequest(const std::string& extension_id, + const SuccessCallback& callback) override { + FAIL(); + } + bool enabled_; std::vector<GURL> requested_urls_; std::vector<SuccessCallback> callbacks_; @@ -269,11 +274,11 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { GURL url("http://www.example.com"); // Without any permission request creators, it should be disabled, and any - // AddAccessRequest() calls should fail. + // AddURLAccessRequest() calls should fail. EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled()); { AsyncResultHolder result_holder; - AddAccessRequest(url, &result_holder); + AddURLAccessRequest(url, &result_holder); EXPECT_FALSE(result_holder.GetResult()); } @@ -285,7 +290,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled()); { AsyncResultHolder result_holder; - AddAccessRequest(url, &result_holder); + AddURLAccessRequest(url, &result_holder); EXPECT_FALSE(result_holder.GetResult()); } @@ -295,7 +300,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { EXPECT_TRUE(supervised_user_service_->AccessRequestsEnabled()); { AsyncResultHolder result_holder; - AddAccessRequest(url, &result_holder); + AddURLAccessRequest(url, &result_holder); ASSERT_EQ(1u, creator->requested_urls().size()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); @@ -305,7 +310,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { { AsyncResultHolder result_holder; - AddAccessRequest(url, &result_holder); + AddURLAccessRequest(url, &result_holder); ASSERT_EQ(1u, creator->requested_urls().size()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); @@ -321,7 +326,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { { AsyncResultHolder result_holder; - AddAccessRequest(url, &result_holder); + AddURLAccessRequest(url, &result_holder); ASSERT_EQ(1u, creator->requested_urls().size()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); @@ -332,7 +337,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { { AsyncResultHolder result_holder; - AddAccessRequest(url, &result_holder); + AddURLAccessRequest(url, &result_holder); ASSERT_EQ(1u, creator->requested_urls().size()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); |