Commit 8ecc1eb5 authored by treib's avatar treib Committed by Commit bot

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}
parent fe3f7ae8
...@@ -84,6 +84,11 @@ ...@@ -84,6 +84,11 @@
#include "extensions/common/permissions/permission_message_provider.h" #include "extensions/common/permissions/permission_message_provider.h"
#include "extensions/common/permissions/permissions_data.h" #include "extensions/common/permissions/permissions_data.h"
#if defined(ENABLE_SUPERVISED_USERS)
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#endif
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/extensions/install_limiter.h" #include "chrome/browser/chromeos/extensions/install_limiter.h"
#include "storage/browser/fileapi/file_system_backend.h" #include "storage/browser/fileapi/file_system_backend.h"
...@@ -110,13 +115,18 @@ using extensions::SharedModuleInfo; ...@@ -110,13 +115,18 @@ using extensions::SharedModuleInfo;
using extensions::SharedModuleService; using extensions::SharedModuleService;
using extensions::UnloadedExtensionInfo; using extensions::UnloadedExtensionInfo;
namespace errors = extensions::manifest_errors;
namespace { namespace {
// Wait this many seconds after an extensions becomes idle before updating it. // Wait this many seconds after an extensions becomes idle before updating it.
const int kUpdateIdleDelay = 5; const int kUpdateIdleDelay = 5;
#if defined(ENABLE_SUPERVISED_USERS)
// Callback for SupervisedUserService::AddExtensionUpdateRequest.
void ExtensionUpdateRequestSent(const std::string& id, bool success) {
LOG_IF(WARNING, !success) << "Failed sending update request for " << id;
}
#endif
} // namespace } // namespace
// ExtensionService. // ExtensionService.
...@@ -1660,6 +1670,19 @@ void ExtensionService::CheckPermissionsIncrease(const Extension* extension, ...@@ -1660,6 +1670,19 @@ void ExtensionService::CheckPermissionsIncrease(const Extension* extension,
} }
extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED);
extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); extension_prefs_->SetDidExtensionEscalatePermissions(extension, true);
#if defined(ENABLE_SUPERVISED_USERS)
// If a custodian-installed extension is disabled for a supervised user due
// to a permissions increase, send a request to the custodian, since the
// supervised user itself can't re-enable the extension.
if (extensions::util::IsExtensionSupervised(extension, profile_)) {
SupervisedUserService* supervised_user_service =
SupervisedUserServiceFactory::GetForProfile(profile_);
supervised_user_service->AddExtensionUpdateRequest(
extension->id(),
base::Bind(ExtensionUpdateRequestSent, extension->id()));
}
#endif
} }
if (disable_reasons != Extension::DISABLE_NONE) { if (disable_reasons != Extension::DISABLE_NONE) {
extension_prefs_->AddDisableReason( extension_prefs_->AddDisableReason(
......
...@@ -134,6 +134,7 @@ ...@@ -134,6 +134,7 @@
#include "url/gurl.h" #include "url/gurl.h"
#if defined(ENABLE_SUPERVISED_USERS) #if defined(ENABLE_SUPERVISED_USERS)
#include "chrome/browser/supervised_user/permission_request_creator.h"
#include "chrome/browser/supervised_user/supervised_user_service.h" #include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#endif #endif
...@@ -6609,6 +6610,26 @@ TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) { ...@@ -6609,6 +6610,26 @@ TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
} }
#if defined(ENABLE_SUPERVISED_USERS) #if defined(ENABLE_SUPERVISED_USERS)
class MockPermissionRequestCreator : public PermissionRequestCreator {
public:
MockPermissionRequestCreator() {}
~MockPermissionRequestCreator() override {}
bool IsEnabled() const override { return true; }
void CreateURLAccessRequest(const GURL& url_requested,
const SuccessCallback& callback) override {
FAIL();
}
MOCK_METHOD2(CreateExtensionUpdateRequest,
void(const std::string& extension_id,
const SupervisedUserService::SuccessCallback& callback));
private:
DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
};
TEST_F(ExtensionServiceTest, SupervisedUser_InstallOnlyAllowedByCustodian) { TEST_F(ExtensionServiceTest, SupervisedUser_InstallOnlyAllowedByCustodian) {
ExtensionServiceInitParams params = CreateDefaultInitParams(); ExtensionServiceInitParams params = CreateDefaultInitParams();
params.profile_is_supervised = true; params.profile_is_supervised = true;
...@@ -6676,6 +6697,9 @@ TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) { ...@@ -6676,6 +6697,9 @@ TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) {
SupervisedUserService* supervised_user_service = SupervisedUserService* supervised_user_service =
SupervisedUserServiceFactory::GetForProfile(profile()); SupervisedUserServiceFactory::GetForProfile(profile());
GetManagementPolicy()->RegisterProvider(supervised_user_service); GetManagementPolicy()->RegisterProvider(supervised_user_service);
MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
supervised_user_service->AddPermissionRequestCreator(
make_scoped_ptr(creator));
base::FilePath base_path = data_dir().AppendASCII("permissions_increase"); base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
base::FilePath pem_path = base_path.AppendASCII("permissions.pem"); base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
...@@ -6694,6 +6718,7 @@ TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) { ...@@ -6694,6 +6718,7 @@ TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) {
std::string old_version = extension->VersionString(); std::string old_version = extension->VersionString();
// Update to a new version with increased permissions. // Update to a new version with increased permissions.
EXPECT_CALL(*creator, CreateExtensionUpdateRequest(id, testing::_));
path = base_path.AppendASCII("v2"); path = base_path.AppendASCII("v2");
PackCRXAndUpdateExtension(id, path, pem_path, DISABLED); PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
......
...@@ -33,34 +33,47 @@ const char kApiUrl[] = ...@@ -33,34 +33,47 @@ const char kApiUrl[] =
const char kApiScope[] = "https://www.googleapis.com/auth/kid.permission"; const char kApiScope[] = "https://www.googleapis.com/auth/kid.permission";
const int kNumRetries = 1; 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"; const char kState[] = "PENDING";
// Response keys.
const char kPermissionRequestKey[] = "permissionRequest"; const char kPermissionRequestKey[] = "permissionRequest";
const char kIdKey[] = "id"; const char kIdKey[] = "id";
static const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";
struct PermissionRequestCreatorApiary::Request { struct PermissionRequestCreatorApiary::Request {
Request(const GURL& url_requested, Request(const std::string& request_namespace,
const std::string& object_ref,
const SuccessCallback& callback, const SuccessCallback& callback,
int url_fetcher_id); int url_fetcher_id);
~Request(); ~Request();
GURL url_requested; std::string request_namespace;
std::string object_ref;
SuccessCallback callback; SuccessCallback callback;
scoped_ptr<OAuth2TokenService::Request> access_token_request; scoped_ptr<OAuth2TokenService::Request> access_token_request;
std::string access_token; std::string access_token;
bool access_token_expired; bool access_token_expired;
int url_fetcher_id; int url_fetcher_id;
scoped_ptr<net::URLFetcher> url_fetcher; scoped_ptr<URLFetcher> url_fetcher;
}; };
PermissionRequestCreatorApiary::Request::Request( PermissionRequestCreatorApiary::Request::Request(
const GURL& url_requested, const std::string& request_namespace,
const std::string& object_ref,
const SuccessCallback& callback, const SuccessCallback& callback,
int url_fetcher_id) int url_fetcher_id)
: url_requested(url_requested), : request_namespace(request_namespace),
object_ref(object_ref),
callback(callback), callback(callback),
access_token_expired(false), access_token_expired(false),
url_fetcher_id(url_fetcher_id) { url_fetcher_id(url_fetcher_id) {
...@@ -97,11 +110,16 @@ bool PermissionRequestCreatorApiary::IsEnabled() const { ...@@ -97,11 +110,16 @@ bool PermissionRequestCreatorApiary::IsEnabled() const {
return true; return true;
} }
void PermissionRequestCreatorApiary::CreatePermissionRequest( void PermissionRequestCreatorApiary::CreateURLAccessRequest(
const GURL& url_requested, const GURL& url_requested,
const SuccessCallback& callback) { const SuccessCallback& callback) {
requests_.push_back(new Request(url_requested, callback, url_fetcher_id_)); CreateRequest(kNamespaceURLRequest, url_requested.spec(), callback);
StartFetching(requests_.back()); }
void PermissionRequestCreatorApiary::CreateExtensionUpdateRequest(
const std::string& extension_id,
const SuccessCallback& callback) {
CreateRequest(kNamespaceUpdateRequest, extension_id, callback);
} }
GURL PermissionRequestCreatorApiary::GetApiUrl() const { GURL PermissionRequestCreatorApiary::GetApiUrl() const {
...@@ -127,6 +145,15 @@ std::string PermissionRequestCreatorApiary::GetApiScope() 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) { void PermissionRequestCreatorApiary::StartFetching(Request* request) {
OAuth2TokenService::ScopeSet scopes; OAuth2TokenService::ScopeSet scopes;
scopes.insert(GetApiScope()); scopes.insert(GetApiScope());
...@@ -160,9 +187,10 @@ void PermissionRequestCreatorApiary::OnGetTokenSuccess( ...@@ -160,9 +187,10 @@ void PermissionRequestCreatorApiary::OnGetTokenSuccess(
base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str()));
base::DictionaryValue dict; base::DictionaryValue dict;
dict.SetStringWithoutPathExpansion("namespace", kNamespace); dict.SetStringWithoutPathExpansion(kNamespaceKey, (*it)->request_namespace);
dict.SetStringWithoutPathExpansion("objectRef", (*it)->url_requested.spec()); dict.SetStringWithoutPathExpansion(kObjectRefKey, (*it)->object_ref);
dict.SetStringWithoutPathExpansion("state", kState); dict.SetStringWithoutPathExpansion(kStateKey, kState);
std::string body; std::string body;
base::JSONWriter::Write(&dict, &body); base::JSONWriter::Write(&dict, &body);
(*it)->url_fetcher->SetUploadData("application/json", body); (*it)->url_fetcher->SetUploadData("application/json", body);
......
...@@ -40,8 +40,10 @@ class PermissionRequestCreatorApiary : public PermissionRequestCreator, ...@@ -40,8 +40,10 @@ class PermissionRequestCreatorApiary : public PermissionRequestCreator,
// PermissionRequestCreator implementation: // PermissionRequestCreator implementation:
bool IsEnabled() const override; bool IsEnabled() const override;
void CreatePermissionRequest(const GURL& url_requested, void CreateURLAccessRequest(const GURL& url_requested,
const SuccessCallback& callback) override; 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; } void set_url_fetcher_id_for_testing(int id) { url_fetcher_id_ = id; }
...@@ -62,6 +64,10 @@ class PermissionRequestCreatorApiary : public PermissionRequestCreator, ...@@ -62,6 +64,10 @@ class PermissionRequestCreatorApiary : public PermissionRequestCreator,
GURL GetApiUrl() const; GURL GetApiUrl() const;
std::string GetApiScope() 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 // Requests an access token, which is the first thing we need. This is where
// we restart when the returned access token has expired. // we restart when the returned access token has expired.
void StartFetching(Request* request); void StartFetching(Request* request);
......
...@@ -56,7 +56,7 @@ class PermissionRequestCreatorApiaryTest : public testing::Test { ...@@ -56,7 +56,7 @@ class PermissionRequestCreatorApiaryTest : public testing::Test {
void CreateRequest(int url_fetcher_id, const GURL& url) { void CreateRequest(int url_fetcher_id, const GURL& url) {
permission_creator_.set_url_fetcher_id_for_testing(url_fetcher_id); permission_creator_.set_url_fetcher_id_for_testing(url_fetcher_id);
permission_creator_.CreatePermissionRequest( permission_creator_.CreateURLAccessRequest(
url, url,
base::Bind(&PermissionRequestCreatorApiaryTest::OnRequestCreated, base::Bind(&PermissionRequestCreatorApiaryTest::OnRequestCreated,
base::Unretained(this))); base::Unretained(this)));
......
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
#include "net/base/escape.h" #include "net/base/escape.h"
#include "url/gurl.h" #include "url/gurl.h"
using base::Time;
const char kSupervisedUserAccessRequestKeyPrefix[] = const char kSupervisedUserAccessRequestKeyPrefix[] =
"X-ManagedUser-AccessRequests"; "X-ManagedUser-AccessRequests";
const char kSupervisedUserUpdateRequestKeyPrefix[] =
"X-ManagedUser-UpdateRequests";
const char kSupervisedUserAccessRequestTime[] = "timestamp"; const char kSupervisedUserAccessRequestTime[] = "timestamp";
const char kSupervisedUserName[] = "name"; const char kSupervisedUserName[] = "name";
...@@ -48,20 +48,33 @@ bool PermissionRequestCreatorSync::IsEnabled() const { ...@@ -48,20 +48,33 @@ bool PermissionRequestCreatorSync::IsEnabled() const {
state == GoogleServiceAuthError::SERVICE_UNAVAILABLE); state == GoogleServiceAuthError::SERVICE_UNAVAILABLE);
} }
void PermissionRequestCreatorSync::CreatePermissionRequest( void PermissionRequestCreatorSync::CreateURLAccessRequest(
const GURL& url_requested, const GURL& url_requested,
const SuccessCallback& callback) { 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( std::string key = SupervisedUserSettingsService::MakeSplitSettingKey(
kSupervisedUserAccessRequestKeyPrefix, prefix,
net::EscapeQueryParamValue(url_requested.spec(), true)); net::EscapeQueryParamValue(data, true));
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
// TODO(sergiu): Use sane time here when it's ready. // TODO(sergiu): Use sane time here when it's ready.
dict->SetDouble(kSupervisedUserAccessRequestTime, dict->SetDouble(kSupervisedUserAccessRequestTime,
base::Time::Now().ToJsTime()); base::Time::Now().ToJsTime());
dict->SetString(kSupervisedUserName, name_); dict->SetString(kSupervisedUserName, name_);
// Copy the notification setting of the custodian. // Copy the notification setting of the custodian.
......
...@@ -14,6 +14,9 @@ class ProfileSyncService; ...@@ -14,6 +14,9 @@ class ProfileSyncService;
class SupervisedUserSettingsService; class SupervisedUserSettingsService;
class SupervisedUserSharedSettingsService; 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 { class PermissionRequestCreatorSync : public PermissionRequestCreator {
public: public:
PermissionRequestCreatorSync( PermissionRequestCreatorSync(
...@@ -26,10 +29,15 @@ class PermissionRequestCreatorSync : public PermissionRequestCreator { ...@@ -26,10 +29,15 @@ class PermissionRequestCreatorSync : public PermissionRequestCreator {
// PermissionRequestCreator implementation: // PermissionRequestCreator implementation:
bool IsEnabled() const override; bool IsEnabled() const override;
void CreatePermissionRequest(const GURL& url_requested, void CreateURLAccessRequest(const GURL& url_requested,
const SuccessCallback& callback) override; const SuccessCallback& callback) override;
void CreateExtensionUpdateRequest(const std::string& extension_id,
const SuccessCallback& callback) override;
private: private:
void CreateRequest(const std::string& prefix,
const std::string& data,
const SuccessCallback& callback);
SupervisedUserSettingsService* settings_service_; SupervisedUserSettingsService* settings_service_;
SupervisedUserSharedSettingsService* shared_settings_service_; SupervisedUserSharedSettingsService* shared_settings_service_;
ProfileSyncService* sync_service_; ProfileSyncService* sync_service_;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_ #ifndef CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_
#define CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_ #define CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_
#include <string>
#include "base/callback_forward.h" #include "base/callback_forward.h"
class GURL; class GURL;
...@@ -23,8 +25,14 @@ class PermissionRequestCreator { ...@@ -23,8 +25,14 @@ class PermissionRequestCreator {
// Creates a permission request for |url_requested| and calls |callback| with // Creates a permission request for |url_requested| and calls |callback| with
// the result (whether creating the permission request was successful). // the result (whether creating the permission request was successful).
virtual void CreatePermissionRequest(const GURL& url_requested, virtual void CreateURLAccessRequest(const GURL& url_requested,
const SuccessCallback& callback) = 0; 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_ #endif // CHROME_BROWSER_SUPERVISED_USER_PERMISSION_REQUEST_CREATOR_H_
...@@ -311,7 +311,7 @@ void SupervisedUserInterstitial::CommandReceived(const std::string& command) { ...@@ -311,7 +311,7 @@ void SupervisedUserInterstitial::CommandReceived(const std::string& command) {
SupervisedUserService* supervised_user_service = SupervisedUserService* supervised_user_service =
SupervisedUserServiceFactory::GetForProfile(profile_); SupervisedUserServiceFactory::GetForProfile(profile_);
supervised_user_service->AddAccessRequest( supervised_user_service->AddURLAccessRequest(
url_, base::Bind(&SupervisedUserInterstitial::OnAccessRequestAdded, url_, base::Bind(&SupervisedUserInterstitial::OnAccessRequestAdded,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
return; return;
......
...@@ -78,6 +78,20 @@ const char* const kCustodianInfoPrefs[] = { ...@@ -78,6 +78,20 @@ const char* const kCustodianInfoPrefs[] = {
prefs::kSupervisedUserSecondCustodianProfileURL, 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) #if defined(ENABLE_EXTENSIONS)
enum ExtensionState { enum ExtensionState {
EXTENSION_FORCED, EXTENSION_FORCED,
...@@ -531,8 +545,8 @@ size_t SupervisedUserService::FindEnabledPermissionRequestCreator( ...@@ -531,8 +545,8 @@ size_t SupervisedUserService::FindEnabledPermissionRequestCreator(
return permissions_creators_.size(); return permissions_creators_.size();
} }
void SupervisedUserService::AddAccessRequestInternal( void SupervisedUserService::AddPermissionRequestInternal(
const GURL& url, const CreatePermissionRequestCallback& create_request,
const SuccessCallback& callback, const SuccessCallback& callback,
size_t index) { size_t index) {
// Find a permission request creator that is enabled. // Find a permission request creator that is enabled.
...@@ -542,14 +556,15 @@ void SupervisedUserService::AddAccessRequestInternal( ...@@ -542,14 +556,15 @@ void SupervisedUserService::AddAccessRequestInternal(
return; return;
} }
permissions_creators_[next_index]->CreatePermissionRequest( create_request.Run(
url, permissions_creators_[next_index],
base::Bind(&SupervisedUserService::OnPermissionRequestIssued, base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
weak_ptr_factory_.GetWeakPtr(), url, callback, next_index)); weak_ptr_factory_.GetWeakPtr(), create_request,
callback, next_index));
} }
void SupervisedUserService::OnPermissionRequestIssued( void SupervisedUserService::OnPermissionRequestIssued(
const GURL& url, const CreatePermissionRequestCallback& create_request,
const SuccessCallback& callback, const SuccessCallback& callback,
size_t index, size_t index,
bool success) { bool success) {
...@@ -558,7 +573,7 @@ void SupervisedUserService::OnPermissionRequestIssued( ...@@ -558,7 +573,7 @@ void SupervisedUserService::OnPermissionRequestIssued(
return; return;
} }
AddAccessRequestInternal(url, callback, index + 1); AddPermissionRequestInternal(create_request, callback, index + 1);
} }
void SupervisedUserService::OnSupervisedUserIdChanged() { void SupervisedUserService::OnSupervisedUserIdChanged() {
...@@ -631,10 +646,21 @@ bool SupervisedUserService::AccessRequestsEnabled() { ...@@ -631,10 +646,21 @@ bool SupervisedUserService::AccessRequestsEnabled() {
return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size(); return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size();
} }
void SupervisedUserService::AddAccessRequest(const GURL& url, void SupervisedUserService::AddURLAccessRequest(
const SuccessCallback& callback) { const GURL& url,
AddAccessRequestInternal(SupervisedUserURLFilter::Normalize(url), callback, const SuccessCallback& callback) {
0); 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) { void SupervisedUserService::InitSync(const std::string& refresh_token) {
......
...@@ -69,9 +69,9 @@ class SupervisedUserService : public KeyedService, ...@@ -69,9 +69,9 @@ class SupervisedUserService : public KeyedService,
public chrome::BrowserListObserver, public chrome::BrowserListObserver,
public SupervisedUserURLFilter::Observer { public SupervisedUserURLFilter::Observer {
public: public:
typedef base::Callback<void(content::WebContents*)> NavigationBlockedCallback; using NavigationBlockedCallback = base::Callback<void(content::WebContents*)>;
typedef base::Callback<void(const GoogleServiceAuthError&)> AuthErrorCallback; using AuthErrorCallback = base::Callback<void(const GoogleServiceAuthError&)>;
typedef base::Callback<void(bool)> SuccessCallback; using SuccessCallback = base::Callback<void(bool)>;
class Delegate { class Delegate {
public: public:
...@@ -111,13 +111,16 @@ class SupervisedUserService : public KeyedService, ...@@ -111,13 +111,16 @@ class SupervisedUserService : public KeyedService,
// Returns the whitelist service. // Returns the whitelist service.
SupervisedUserWhitelistService* GetWhitelistService(); 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(); bool AccessRequestsEnabled();
// Adds an access request for the given URL. The requests are stored using // Adds an access request for the given URL.
// a prefix followed by a URIEncoded version of the URL. Each entry contains void AddURLAccessRequest(const GURL& url, const SuccessCallback& callback);
// a dictionary which currently has the timestamp of the request in it.
void AddAccessRequest(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. // Returns the email address of the custodian.
std::string GetCustodianEmailAddress() const; std::string GetCustodianEmailAddress() const;
...@@ -186,6 +189,9 @@ class SupervisedUserService : public KeyedService, ...@@ -186,6 +189,9 @@ class SupervisedUserService : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(SupervisedUserServiceExtensionTest, FRIEND_TEST_ALL_PREFIXES(SupervisedUserServiceExtensionTest,
ExtensionManagementPolicyProvider); ExtensionManagementPolicyProvider);
using CreatePermissionRequestCallback =
base::Callback<void(PermissionRequestCreator*, const SuccessCallback&)>;
// A bridge from the UI thread to the SupervisedUserURLFilters, one of which // 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 // lives on the IO thread. This class mediates access to them and makes sure
// they are kept in sync. // they are kept in sync.
...@@ -266,13 +272,15 @@ class SupervisedUserService : public KeyedService, ...@@ -266,13 +272,15 @@ class SupervisedUserService : public KeyedService,
SupervisedUserSettingsService* GetSettingsService(); SupervisedUserSettingsService* GetSettingsService();
size_t FindEnabledPermissionRequestCreator(size_t start); size_t FindEnabledPermissionRequestCreator(size_t start);
void AddAccessRequestInternal(const GURL& url, void AddPermissionRequestInternal(
const SuccessCallback& callback, const CreatePermissionRequestCallback& create_request,
size_t index); const SuccessCallback& callback,
void OnPermissionRequestIssued(const GURL& url, size_t index);
const SuccessCallback& callback, void OnPermissionRequestIssued(
size_t index, const CreatePermissionRequestCallback& create_request,
bool success); const SuccessCallback& callback,
size_t index,
bool success);
void OnSupervisedUserIdChanged(); void OnSupervisedUserIdChanged();
......
...@@ -190,8 +190,8 @@ class SupervisedUserServiceTest : public ::testing::Test { ...@@ -190,8 +190,8 @@ class SupervisedUserServiceTest : public ::testing::Test {
~SupervisedUserServiceTest() override {} ~SupervisedUserServiceTest() override {}
protected: protected:
void AddAccessRequest(const GURL& url, AsyncResultHolder* result_holder) { void AddURLAccessRequest(const GURL& url, AsyncResultHolder* result_holder) {
supervised_user_service_->AddAccessRequest( supervised_user_service_->AddURLAccessRequest(
url, base::Bind(&AsyncResultHolder::SetResult, url, base::Bind(&AsyncResultHolder::SetResult,
base::Unretained(result_holder))); base::Unretained(result_holder)));
} }
...@@ -249,13 +249,18 @@ class MockPermissionRequestCreator : public PermissionRequestCreator { ...@@ -249,13 +249,18 @@ class MockPermissionRequestCreator : public PermissionRequestCreator {
// PermissionRequestCreator: // PermissionRequestCreator:
bool IsEnabled() const override { return enabled_; } bool IsEnabled() const override { return enabled_; }
void CreatePermissionRequest(const GURL& url_requested, void CreateURLAccessRequest(const GURL& url_requested,
const SuccessCallback& callback) override { const SuccessCallback& callback) override {
ASSERT_TRUE(enabled_); ASSERT_TRUE(enabled_);
requested_urls_.push_back(url_requested); requested_urls_.push_back(url_requested);
callbacks_.push_back(callback); callbacks_.push_back(callback);
} }
void CreateExtensionUpdateRequest(const std::string& extension_id,
const SuccessCallback& callback) override {
FAIL();
}
bool enabled_; bool enabled_;
std::vector<GURL> requested_urls_; std::vector<GURL> requested_urls_;
std::vector<SuccessCallback> callbacks_; std::vector<SuccessCallback> callbacks_;
...@@ -269,11 +274,11 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { ...@@ -269,11 +274,11 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
GURL url("http://www.example.com"); GURL url("http://www.example.com");
// Without any permission request creators, it should be disabled, and any // 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()); EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled());
{ {
AsyncResultHolder result_holder; AsyncResultHolder result_holder;
AddAccessRequest(url, &result_holder); AddURLAccessRequest(url, &result_holder);
EXPECT_FALSE(result_holder.GetResult()); EXPECT_FALSE(result_holder.GetResult());
} }
...@@ -285,7 +290,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { ...@@ -285,7 +290,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled()); EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled());
{ {
AsyncResultHolder result_holder; AsyncResultHolder result_holder;
AddAccessRequest(url, &result_holder); AddURLAccessRequest(url, &result_holder);
EXPECT_FALSE(result_holder.GetResult()); EXPECT_FALSE(result_holder.GetResult());
} }
...@@ -295,7 +300,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { ...@@ -295,7 +300,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
EXPECT_TRUE(supervised_user_service_->AccessRequestsEnabled()); EXPECT_TRUE(supervised_user_service_->AccessRequestsEnabled());
{ {
AsyncResultHolder result_holder; AsyncResultHolder result_holder;
AddAccessRequest(url, &result_holder); AddURLAccessRequest(url, &result_holder);
ASSERT_EQ(1u, creator->requested_urls().size()); ASSERT_EQ(1u, creator->requested_urls().size());
EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
...@@ -305,7 +310,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { ...@@ -305,7 +310,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
{ {
AsyncResultHolder result_holder; AsyncResultHolder result_holder;
AddAccessRequest(url, &result_holder); AddURLAccessRequest(url, &result_holder);
ASSERT_EQ(1u, creator->requested_urls().size()); ASSERT_EQ(1u, creator->requested_urls().size());
EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
...@@ -321,7 +326,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { ...@@ -321,7 +326,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
{ {
AsyncResultHolder result_holder; AsyncResultHolder result_holder;
AddAccessRequest(url, &result_holder); AddURLAccessRequest(url, &result_holder);
ASSERT_EQ(1u, creator->requested_urls().size()); ASSERT_EQ(1u, creator->requested_urls().size());
EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
...@@ -332,7 +337,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) { ...@@ -332,7 +337,7 @@ TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
{ {
AsyncResultHolder result_holder; AsyncResultHolder result_holder;
AddAccessRequest(url, &result_holder); AddURLAccessRequest(url, &result_holder);
ASSERT_EQ(1u, creator->requested_urls().size()); ASSERT_EQ(1u, creator->requested_urls().size());
EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec()); EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment