|
|
Created:
4 years, 7 months ago by mamir Modified:
4 years, 5 months ago CC:
asvitkine+watch_chromium.org, chromium-apps-reviews_chromium.org, chromium-reviews, extensions-reviews_chromium.org, pam+watch_chromium.org Base URL:
https://chromium.googlesource.com/chromium/src.git@kid_initiated_install Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionSupervised users initiated extensions installs
Supervised users can install apps and extension. The extension will be
installed in a disabled state and an approval request will be sent to
their custodian.
If the custodian approves the request, the extension will be enabled.
If the custodian denies the request, the extension will be uninstalled.
BUG=619526
Committed: https://crrev.com/e960964b7ea2caff5289d4a2f40488af7613389d
Cr-Commit-Position: refs/heads/master@{#402570}
Patch Set 1 #Patch Set 2 : Style fix #
Total comments: 42
Patch Set 3 : Response to 1st round of code review from treib@ #Patch Set 4 : reparent #Patch Set 5 : Removing unrelated formating changes. #Patch Set 6 : minor #
Total comments: 49
Patch Set 7 : Response to code review feedback #Patch Set 8 : Checking approved version #Patch Set 9 : Fixing updates of SU initiated installs #
Total comments: 14
Patch Set 10 : Code review response #
Total comments: 26
Patch Set 11 : Response to code review by treib@ #
Total comments: 10
Patch Set 12 : Testing if the approved version is pushed to sync upon extension update #Patch Set 13 : Response to code review by treib@ #
Total comments: 2
Patch Set 14 : Response to code review by treib@ #
Total comments: 2
Patch Set 15 : Adding a comment in a response to review by treib@ #
Total comments: 8
Patch Set 16 : Response to feedback from rdevlin.cronin@ #
Total comments: 20
Patch Set 17 : Response to codereview by rdevlin.cronin@ #
Total comments: 24
Patch Set 18 : Response to code review from Marc #
Total comments: 25
Patch Set 19 : response to cdoe review by treib@ #Patch Set 20 : Respones to code review by Marc #
Total comments: 31
Patch Set 21 : Response to code review by Marc #Patch Set 22 : minor #
Total comments: 2
Patch Set 23 : minor #
Total comments: 12
Patch Set 24 : Response to code review by Devlin #
Total comments: 2
Patch Set 25 : rebasing #Patch Set 26 : adding missing dep #Patch Set 27 : rebasing #Patch Set 28 : Removing uncessary changes after rebasing #Patch Set 29 : Response to code review by Devlin and fixing a test #
Total comments: 10
Patch Set 30 : Fixing the build for ChromeOS and Android #Patch Set 31 : hiding extensions related code behind #ifdefine #Patch Set 32 : Hiding SUService::UpdateApprovedExtensions behind ifdef Ext. #Patch Set 33 : Hiding extensions related code behind #ifdefine #
Total comments: 14
Patch Set 34 : Response to code review by Marc #
Total comments: 14
Patch Set 35 : Response to code review by Devlin #
Total comments: 2
Patch Set 36 : Fixing the DelegatedAndPreinstalledExtension test #Patch Set 37 : Small change to CheckDisabledForCustodianApproval #
Total comments: 7
Patch Set 38 : Response to code review by Marc #Patch Set 39 : fixing the build #Patch Set 40 : Fixing the build again! #Dependent Patchsets: Messages
Total messages: 103 (27 generated)
Description was changed from ========== Fixing style Fixing the tests Fixing the format It compiles now Adding approved extensions to supervised user settings Removing "is_approved_by_custodian" flag. minor fix SetIsApprovedByCustodian should never unset the flag Fixing two typos Response to seventh round of comment by treib Style Response to sixth round of comments by treib FREEZE.unindexed formating. Response to Marc fifth round of comments and fixing after rebase FREEZE.unindexed git squash commit. 0ab7fe868446c104081cfef0abf046d41df6b958 [WIP - DO NOT SUBMIT] SU-initiated extension installs patch from issue 1663023003 at patchset 1 (http://crrev.com/1663023003#ps1) ea7c4d69a7ab6089b8583c94bb920d4ced12f54f Implementing virtual methods in PermissionRequestCreator fb12917a27f41879cf9ca0c024c43fd7edc85025 fixing some unit tests 227c994e7c38a6bee14f7e8d5722e1c066cbc346 formatting e74a7e070bfb4bb99ec8c099f0bf474e5f516fa8 testing kid-initiated installs flow 58984bbac4292608b5810959d55f18240aaf9a02 Fixing style 731f390db51d033d010b85fac71ba25aa29317b7 Hiding supervised user initiaied installs behind a feature 4433c5845b0a7de1595306c027fbee788f4bd312 Fixing test afer the supervised user initiated installs feature flag ea6d7407345c1673ca69def4c9df6c76c9c9d597 Fixing test afer the supervised user initiated installs feature flag ee25280c2b98d26fa5b80775bd088d09357aa6b9 Fixing test afer the supervised user initiated installs feature flag 3283afe876e1b0ff51a9a85c736d1f7cca955cc0 is_approved_by_custodian flag instead of disable_reasons bit 7c807fa3ac40e18055c9c3d1adecdbcc5549c453 Adding is_approved_by_custodian flag and keeping the oldpending_approval_disable_reason 6d4180cfacb7d35cc88928f29493c18630007e2b fixing more tests f36ede5c9f9cd499fa8b2a04d5a9e640c5d59d49 All tests fixed ffb0f9343ffcb99d8faccc7e955cf41ad23adacb All tests fixed b660dc67604d8c2a45d3d65c71d3e127bc880dd7 All test actually pass now ca9dc738567cb2bf77d02af3ab9ca5f3c07bda50 Response to first round of comment from treib@ 7a3b274ffcc6a7de9f73cae6e99e9769be60061a Fixing the style. ff368483ec97128fce649ef5b8dc88d9a0cbb091 Response to second round of comments from treib@ 19b1b6a8eacc6582980e9d018bbf8f702f38aa65 Fixing the style. 1522c76e5d5848e31dd97dfc087e19f6770bdc37 Response to third round of comments from treib@ 2866a4c1877f5b80539fed5e368f15826434aee1 Fixing the style. 6c41af51616e7fcffa83d32887046c9f5ef943e4 Response to fourth round of comments from treib@ 914747e0f7437a80661b1298c2cee304be43bc13 Fixing the style. BUG= ========== to ========== BUG= ==========
mamir@chromium.org changed reviewers: + treib@chromium.org
https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (left): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1846: ext_specifics->set_installed_by_custodian(true); Don't remove this https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:317: ExtensionSyncData disable_good_crx( And once more: no unrelated formatting changes please https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1991: extension_sync_service()->ProcessSyncChanges(FROM_HERE, list1); After this, we should make sure that the extension is not enabled yet. Also add a second test, where the sync changes come in in the other order, and make sure things work out too. Or actually, come to think of it: This sync change shouldn't even matter, right? If so, just make sure that the extension still has the same state, e.g. disable reasons. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_sync_data.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_sync_data.cc:90: : ExtensionSyncData(extension, Please undo - this file isn't touched except for this formatting change. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_sync_service.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_sync_service.cc:286: extension.is_app() Also here: Please avoid unrelated formatting changes. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/permission_request_creator.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/permission_request_creator.h:31: // Creates a request to re-enable the extension with the given |id| (composed Update comment https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_constants.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_constants.h:13: extern const char kContentPackApprovedExtensions[]; Don't add "ContentPack" here, just kApprovedExtensions https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:921: std::string version = ""; No need to initialize with empty string, it'll do that anyway https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:924: (*approved_extensions_map)[it.key()] = version; Convert version to an actual base::Version, to make sure it's properly formatted? https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:931: // Try to Enable the extension, this will call the ManagmentPolicy and nit: don't capitalize "Enable" https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:933: service->EnableExtension(extensions_entry.first); This will also re-enable extensions that have other disable reasons. Check the disable reasons, and only re-enable if yours was the only one. Otherwise just remove that reason. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1089: auto extention_it = approved_extensions_map_->find(extension->id()); "extension" But IMO something like bool approved = map_.count(id) > 0; is clearer anyway. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1091: (extention_it != approved_extensions_map_->end()); Can we use GetExtensionState here, like all the other ManagementPolicy methods do? (The approved_extensions_map_ check will have to move in there, which is probably better anyway) https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:386: // is changed nit: period after comment https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:428: std::unique_ptr<std::map<std::string, std::string>> approved_extensions_map_; Why is this a pointer? Also, please document what's actually stored - presumably ID -> version? Can we use the actual Version type? https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:547: EXPECT_TRUE(supervised_user_service->MustRemainInstalled(extension.get(), Add checks for MustRemainDisabled, and also for UserMayModifySettings? Also in the previous test. https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... File chrome/test/base/testing_profile.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... chrome/test/base/testing_profile.cc:361: supervised_user_id_ = supervised_user_id; Set this in the initializer list above? https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... chrome/test/base/testing_profile.cc:771: factory.CreateSyncable(registry.get())); Can't you assign this directly to prefs_? https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... File chrome/test/base/testing_profile.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... chrome/test/base/testing_profile.h:357: // Creates a pref services that uses SupervisedUserPrefStore and associates "service", singular
Thank you Marc for useful comments. I think there is something wrong with the formatting, or probably I am missing something. I think all the diff shown here is against the previous CL (on which this is based). Shoudn't it show the diff against what's in the repo? Thank you. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (left): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1846: ext_specifics->set_installed_by_custodian(true); On 2016/05/23 15:32:42, Marc Treib wrote: > Don't remove this Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:317: ExtensionSyncData disable_good_crx( On 2016/05/23 15:32:42, Marc Treib wrote: > And once more: no unrelated formatting changes please Sorry! I made sure not to produce those but seems I overlooked some. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1991: extension_sync_service()->ProcessSyncChanges(FROM_HERE, list1); On 2016/05/23 15:32:42, Marc Treib wrote: > After this, we should make sure that the extension is not enabled yet. > Also add a second test, where the sync changes come in in the other order, and > make sure things work out too. > Or actually, come to think of it: This sync change shouldn't even matter, right? > If so, just make sure that the extension still has the same state, e.g. disable > reasons. Yes this Sync change indeed shouldn't matter. But (apart from their order) those steps accurately simulates what happens on the server side. Because the same approval pipeline is used for approving requests upon permission increase and upon SU-initiated installs. i.e. for both requests, the disable reasons as well as approved extensions are touched. What do you mean with "just make sure the extension still has the same state, e.g. disable reason"? https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_sync_data.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_sync_data.cc:90: : ExtensionSyncData(extension, On 2016/05/23 15:32:42, Marc Treib wrote: > Please undo - this file isn't touched except for this formatting change. Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_sync_service.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_sync_service.cc:286: extension.is_app() On 2016/05/23 15:32:42, Marc Treib wrote: > Also here: Please avoid unrelated formatting changes. I got confused while moving between different branches and comitted some formatting changes by mistake, sorry! https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/permission_request_creator.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/permission_request_creator.h:31: // Creates a request to re-enable the extension with the given |id| (composed On 2016/05/23 15:32:42, Marc Treib wrote: > Update comment Which part exactly you aren't happy with? https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_constants.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_constants.h:13: extern const char kContentPackApprovedExtensions[]; On 2016/05/23 15:32:42, Marc Treib wrote: > Don't add "ContentPack" here, just kApprovedExtensions Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:921: std::string version = ""; On 2016/05/23 15:32:42, Marc Treib wrote: > No need to initialize with empty string, it'll do that anyway Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:924: (*approved_extensions_map)[it.key()] = version; On 2016/05/23 15:32:42, Marc Treib wrote: > Convert version to an actual base::Version, to make sure it's properly > formatted? Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:931: // Try to Enable the extension, this will call the ManagmentPolicy and On 2016/05/23 15:32:42, Marc Treib wrote: > nit: don't capitalize "Enable" Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:933: service->EnableExtension(extensions_entry.first); On 2016/05/23 15:32:42, Marc Treib wrote: > This will also re-enable extensions that have other disable reasons. Check the > disable reasons, and only re-enable if yours was the only one. Otherwise just > remove that reason. Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1089: auto extention_it = approved_extensions_map_->find(extension->id()); On 2016/05/23 15:32:42, Marc Treib wrote: > "extension" > But IMO something like > bool approved = map_.count(id) > 0; > is clearer anyway. Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1091: (extention_it != approved_extensions_map_->end()); On 2016/05/23 15:32:42, Marc Treib wrote: > Can we use GetExtensionState here, like all the other ManagementPolicy methods > do? (The approved_extensions_map_ check will have to move in there, which is > probably better anyway) Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:386: // is changed On 2016/05/23 15:32:42, Marc Treib wrote: > nit: period after comment Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:428: std::unique_ptr<std::map<std::string, std::string>> approved_extensions_map_; On 2016/05/23 15:32:42, Marc Treib wrote: > Why is this a pointer? > Also, please document what's actually stored - presumably ID -> version? Can we > use the actual Version type? Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:547: EXPECT_TRUE(supervised_user_service->MustRemainInstalled(extension.get(), On 2016/05/23 15:32:42, Marc Treib wrote: > Add checks for MustRemainDisabled, and also for UserMayModifySettings? Also in > the previous test. Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... File chrome/test/base/testing_profile.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... chrome/test/base/testing_profile.cc:361: supervised_user_id_ = supervised_user_id; On 2016/05/23 15:32:43, Marc Treib wrote: > Set this in the initializer list above? Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... chrome/test/base/testing_profile.cc:771: factory.CreateSyncable(registry.get())); On 2016/05/23 15:32:43, Marc Treib wrote: > Can't you assign this directly to prefs_? Done. https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... File chrome/test/base/testing_profile.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/test/base/testin... chrome/test/base/testing_profile.h:357: // Creates a pref services that uses SupervisedUserPrefStore and associates On 2016/05/23 15:32:43, Marc Treib wrote: > "service", singular Done.
On 2016/05/23 19:35:15, mamir wrote: > Thank you Marc for useful comments. > I think there is something wrong with the formatting, or probably I am missing > something. > I think all the diff shown here is against the previous CL (on which this is > based). > Shoudn't it show the diff against what's in the repo? > > Thank you. No, if this is based on the other patchset (see the "Depends on patchset" above), then it'll show the diff against that, and you won't be able to land it before the other one has landed. It's simple to sort this out client-side though, ping me when it's a good time for you.
https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1991: extension_sync_service()->ProcessSyncChanges(FROM_HERE, list1); On 2016/05/23 19:35:14, mamir wrote: > On 2016/05/23 15:32:42, Marc Treib wrote: > > After this, we should make sure that the extension is not enabled yet. > > Also add a second test, where the sync changes come in in the other order, and > > make sure things work out too. > > Or actually, come to think of it: This sync change shouldn't even matter, > right? > > If so, just make sure that the extension still has the same state, e.g. > disable > > reasons. > > Yes this Sync change indeed shouldn't matter. But (apart from their order) > those steps accurately simulates what happens on the server side. Because the > same approval pipeline is used for approving requests upon permission increase > and upon SU-initiated installs. > i.e. for both requests, the disable reasons as well as approved extensions are > touched. > What do you mean with "just make sure the extension still has the same state, > e.g. disable reason"? But here, the Sync change will actually be a no-op change, since the disable reason isn't synced. Right? So, I'm not sure if it makes sense to keep the Extension change, since it's not actually a change at all. But if we do keep it, then we should make sure it behaves correctly, i.e. after the change has been processed, the extension is still disabled with REQUIRE_CUSTODIAN_APPROVAL. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/permission_request_creator.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/permission_request_creator.h:31: // Creates a request to re-enable the extension with the given |id| (composed On 2016/05/23 19:35:14, mamir wrote: > On 2016/05/23 15:32:42, Marc Treib wrote: > > Update comment > > Which part exactly you aren't happy with? The text is exactly the same as for update requests below. In particular, "re-enable" doesn't really make sense here. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1590: // profile to create a pref service to uses SupervisedUserPrefStore instead. some comment nits: You're not *forcing* the testing profile to do anything by not passing a pref file path. s/to uses/that uses/ ? Also it's not really using the SUPrefStore *instead* of anything. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1690: // While the extension missing the flag is a supervised user initiated install not a complete sentence :) TBH I'd just drop this comment - in this test, there are no SU-initiated installs https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1711: // supervised user initiated install and hence not allowed. "not allowed" isn't really accurate - installing is allowed, but enabling isn't https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1719: PreinstalledExtensionWithSUInitiatedInstallsEnabled) { just PreinstalledExtensionWithSUInitiatedInstalls? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1743: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); Also check that it has the proper disable reason? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1747: PreinstalledExtensionWithSUInitiatedInstallsDisabled) { PreinstalledExtensionWithoutSUInitiatedInstalls? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1774: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); Also here: What should the disable reasons be? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1980: Something I learned recently: You can do Mock::VerifyAndClearExpectations(creator); to make sure the EXPECT_CALL has actually happened at this point. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:921: std::map<std::string, base::Version> approved_extensions_map; Why the separate variable? Can't you just approved_extensions_map_.clear() and then add stuff directly into approved_extensions_map_? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:926: approved_extensions_map[it.key()] = base::Version(version); Check that the version is valid before using it. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:935: std::string extension_id = extensions_entry.first; const std::string& ? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:941: service->EnableExtension(extension_id); This will get called even if the extension is already enabled. That *should* not hurt, but is still not very nice. Also, if there *are* other disable reasons, you still want to remove DISABLE_CUSTODIAN_APPROVAL_REQUIRED. So what I'd do is: remove DISABLE_CUSTODIAN_APPROVAL_REQUIRED, then check if any disable reasons are left. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1022: nit: extra empty line https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1026: if (extension_prefs->GetInstalledExtensionInfo(id) Is this check needed? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1085: const extensions::Extension* extension, optional: You could add using extensions::Extension; above (plus a few more for ExtensionPrefs etc) and save a whole lot of "extensions::" here. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:228: ChangesSyncSessionStateOnChangedSettings); Any reason for adding these unrelated tests here? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:329: // BLOCKED: Extension is blocked if it is not ALLOWED or FORCED remove "Extension is blocked" to be consistent with the other case descriptions https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:430: // Stores a map from extension_id -> latest approved version by the custodian. It's not really *latest* approved version, but rather exact approved version, right? Is the version here ever updated? What about extension updates that don't add new permissions? Also it's only relevant for SU-initiated installs. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:53: using extensions::Extension; This should probably go into the ENABLE_EXTENSIONS block above https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:460: ExtensionManagementPolicyProviderWithDisabledSUInitiatedInstalls) { ExtensionManagementPolicyProviderWithoutSUInitiatedInstalls? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:516: ExtensionManagementPolicyProviderWithEnabledSUInitiatedInstalls) { ExtensionManagementPolicyProviderWithSUInitiatedInstalls? https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:540: &reason, misaligned, also below https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... File chrome/test/base/testing_profile.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... chrome/test/base/testing_profile.cc:425: #if defined(ENABLE_SUPERVISED_USERS) Is it necessary to move this up here? It used to happen after browser_context_dependency_manager_->CreateBrowserContextServicesForTest, doing it before that seems like it might mess things up...
https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1991: extension_sync_service()->ProcessSyncChanges(FROM_HERE, list1); On 2016/05/24 09:54:57, Marc Treib wrote: > On 2016/05/23 19:35:14, mamir wrote: > > On 2016/05/23 15:32:42, Marc Treib wrote: > > > After this, we should make sure that the extension is not enabled yet. > > > Also add a second test, where the sync changes come in in the other order, > and > > > make sure things work out too. > > > Or actually, come to think of it: This sync change shouldn't even matter, > > right? > > > If so, just make sure that the extension still has the same state, e.g. > > disable > > > reasons. > > > > Yes this Sync change indeed shouldn't matter. But (apart from their order) > > those steps accurately simulates what happens on the server side. Because the > > same approval pipeline is used for approving requests upon permission increase > > and upon SU-initiated installs. > > i.e. for both requests, the disable reasons as well as approved extensions are > > touched. > > What do you mean with "just make sure the extension still has the same state, > > e.g. disable reason"? > > But here, the Sync change will actually be a no-op change, since the disable > reason isn't synced. Right? > > So, I'm not sure if it makes sense to keep the Extension change, since it's not > actually a change at all. But if we do keep it, then we should make sure it > behaves correctly, i.e. after the change has been processed, the extension is > still disabled with REQUIRE_CUSTODIAN_APPROVAL. Yes, it's not Synced. I will remove it then. https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... File chrome/browser/supervised_user/permission_request_creator.h (right): https://codereview.chromium.org/2004043002/diff/20001/chrome/browser/supervis... chrome/browser/supervised_user/permission_request_creator.h:31: // Creates a request to re-enable the extension with the given |id| (composed On 2016/05/24 09:54:57, Marc Treib wrote: > On 2016/05/23 19:35:14, mamir wrote: > > On 2016/05/23 15:32:42, Marc Treib wrote: > > > Update comment > > > > Which part exactly you aren't happy with? > > The text is exactly the same as for update requests below. In particular, > "re-enable" doesn't really make sense here. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1590: // profile to create a pref service to uses SupervisedUserPrefStore instead. On 2016/05/24 09:54:57, Marc Treib wrote: > some comment nits: > You're not *forcing* the testing profile to do anything by not passing a pref > file path. > > s/to uses/that uses/ ? > > Also it's not really using the SUPrefStore *instead* of anything. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1690: // While the extension missing the flag is a supervised user initiated install On 2016/05/24 09:54:57, Marc Treib wrote: > not a complete sentence :) > TBH I'd just drop this comment - in this test, there are no SU-initiated > installs Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1711: // supervised user initiated install and hence not allowed. On 2016/05/24 09:54:57, Marc Treib wrote: > "not allowed" isn't really accurate - installing is allowed, but enabling isn't Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1719: PreinstalledExtensionWithSUInitiatedInstallsEnabled) { On 2016/05/24 09:54:57, Marc Treib wrote: > just PreinstalledExtensionWithSUInitiatedInstalls? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1743: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); On 2016/05/24 09:54:57, Marc Treib wrote: > Also check that it has the proper disable reason? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1747: PreinstalledExtensionWithSUInitiatedInstallsDisabled) { On 2016/05/24 09:54:57, Marc Treib wrote: > PreinstalledExtensionWithoutSUInitiatedInstalls? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1774: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); On 2016/05/24 09:54:58, Marc Treib wrote: > Also here: What should the disable reasons be? It also should have the same reason DISABLE_CUSTODIAN_APPROVAL_REQUIRED. The only difference is not approval request is sent. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/extensio... chrome/browser/extensions/extension_service_sync_unittest.cc:1980: On 2016/05/24 09:54:57, Marc Treib wrote: > Something I learned recently: You can do > Mock::VerifyAndClearExpectations(creator); > to make sure the EXPECT_CALL has actually happened at this point. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:921: std::map<std::string, base::Version> approved_extensions_map; On 2016/05/24 09:54:58, Marc Treib wrote: > Why the separate variable? Can't you just approved_extensions_map_.clear() and > then add stuff directly into approved_extensions_map_? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:926: approved_extensions_map[it.key()] = base::Version(version); On 2016/05/24 09:54:58, Marc Treib wrote: > Check that the version is valid before using it. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:935: std::string extension_id = extensions_entry.first; On 2016/05/24 09:54:58, Marc Treib wrote: > const std::string& ? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:941: service->EnableExtension(extension_id); On 2016/05/24 09:54:58, Marc Treib wrote: > This will get called even if the extension is already enabled. That *should* not > hurt, but is still not very nice. > Also, if there *are* other disable reasons, you still want to remove > DISABLE_CUSTODIAN_APPROVAL_REQUIRED. So what I'd do is: remove > DISABLE_CUSTODIAN_APPROVAL_REQUIRED, then check if any disable reasons are left. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1022: On 2016/05/24 09:54:58, Marc Treib wrote: > nit: extra empty line Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1026: if (extension_prefs->GetInstalledExtensionInfo(id) On 2016/05/24 09:54:58, Marc Treib wrote: > Is this check needed? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.cc:1085: const extensions::Extension* extension, On 2016/05/24 09:54:58, Marc Treib wrote: > optional: You could add > using extensions::Extension; > above (plus a few more for ExtensionPrefs etc) and save a whole lot of > "extensions::" here. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:228: ChangesSyncSessionStateOnChangedSettings); On 2016/05/24 09:54:58, Marc Treib wrote: > Any reason for adding these unrelated tests here? Nop :-) I think they came here during a rebase. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:329: // BLOCKED: Extension is blocked if it is not ALLOWED or FORCED On 2016/05/24 09:54:58, Marc Treib wrote: > remove "Extension is blocked" to be consistent with the other case descriptions Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:53: using extensions::Extension; On 2016/05/24 09:54:58, Marc Treib wrote: > This should probably go into the ENABLE_EXTENSIONS block above Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:460: ExtensionManagementPolicyProviderWithDisabledSUInitiatedInstalls) { On 2016/05/24 09:54:58, Marc Treib wrote: > ExtensionManagementPolicyProviderWithoutSUInitiatedInstalls? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:516: ExtensionManagementPolicyProviderWithEnabledSUInitiatedInstalls) { On 2016/05/24 09:54:58, Marc Treib wrote: > ExtensionManagementPolicyProviderWithSUInitiatedInstalls? Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service_unittest.cc:540: &reason, On 2016/05/24 09:54:58, Marc Treib wrote: > misaligned, also below Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... File chrome/test/base/testing_profile.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... chrome/test/base/testing_profile.cc:425: #if defined(ENABLE_SUPERVISED_USERS) On 2016/05/24 09:54:58, Marc Treib wrote: > Is it necessary to move this up here? > It used to happen after > browser_context_dependency_manager_->CreateBrowserContextServicesForTest, doing > it before that seems like it might mess things up... Yes, it is. Because CreatePrefServiceForSupervisedUser() requires the SupervisedUserSettingsService to be initialized (specifically to have a pref store)
https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... File chrome/test/base/testing_profile.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... chrome/test/base/testing_profile.cc:425: #if defined(ENABLE_SUPERVISED_USERS) On 2016/06/03 09:45:55, mamir wrote: > On 2016/05/24 09:54:58, Marc Treib wrote: > > Is it necessary to move this up here? > > It used to happen after > > browser_context_dependency_manager_->CreateBrowserContextServicesForTest, > doing > > it before that seems like it might mess things up... > > Yes, it is. > Because CreatePrefServiceForSupervisedUser() requires the > SupervisedUserSettingsService to be initialized (specifically to have a pref > store) And moving all the PrefService stuff down, after the dependency manager is initialized, is not an option? https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1619: EXPECT_FALSE(registry()->enabled_extensions().Contains(extension->id())); EXPECT_TRUE(...disabled_extensions()...) ? https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: if (version.IsValid()) { Can it ever not be valid? https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1082: auto extention_it = approved_extensions_map_.find(extension.id()); extension_it https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1086: return ExtensionState::REQUIRE_APPROVAL; The body is the same as the previous one, so just make it one if (as in, "if (condition1 || condition2) return ..." https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:81: public extensions::ExtensionRegistryObserver { This should go into the ENABLE_EXTENSIONS above https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:155: void UpdateApprovedVersion(const std::string& extension_id, UpdateApprovedExtensionVersion? https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:408: void OnExtensionInstalled(content::BrowserContext* browser_context, This should go into the ENABLE_EXTENSIONS above; EnableExtensionIfPossible probably too.
https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/browser/supervis... chrome/browser/supervised_user/supervised_user_service.h:430: // Stores a map from extension_id -> latest approved version by the custodian. On 2016/05/24 09:54:58, Marc Treib wrote: > It's not really *latest* approved version, but rather exact approved version, > right? > Is the version here ever updated? What about extension updates that don't add > new permissions? > Also it's only relevant for SU-initiated installs. Done. https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... File chrome/test/base/testing_profile.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... chrome/test/base/testing_profile.cc:425: #if defined(ENABLE_SUPERVISED_USERS) On 2016/06/03 13:24:13, Marc Treib wrote: > On 2016/06/03 09:45:55, mamir wrote: > > On 2016/05/24 09:54:58, Marc Treib wrote: > > > Is it necessary to move this up here? > > > It used to happen after > > > browser_context_dependency_manager_->CreateBrowserContextServicesForTest, > > doing > > > it before that seems like it might mess things up... > > > > Yes, it is. > > Because CreatePrefServiceForSupervisedUser() requires the > > SupervisedUserSettingsService to be initialized (specifically to have a pref > > store) > > And moving all the PrefService stuff down, after the dependency manager is > initialized, is not an option? I checked but couldn't be 100% sure whether it causes problems as currently implemented. This is anyway a TestingProfile and all tests pass, so, we should be relatively fine.! https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1619: EXPECT_FALSE(registry()->enabled_extensions().Contains(extension->id())); On 2016/06/03 13:24:13, Marc Treib wrote: > EXPECT_TRUE(...disabled_extensions()...) > ? Done. https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: if (version.IsValid()) { On 2016/06/03 13:24:14, Marc Treib wrote: > Can it ever not be valid? Probably not. Done. https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1082: auto extention_it = approved_extensions_map_.find(extension.id()); On 2016/06/03 13:24:14, Marc Treib wrote: > extension_it Done. https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1086: return ExtensionState::REQUIRE_APPROVAL; On 2016/06/03 13:24:14, Marc Treib wrote: > The body is the same as the previous one, so just make it one if (as in, "if > (condition1 || condition2) return ..." Done. https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:81: public extensions::ExtensionRegistryObserver { On 2016/06/03 13:24:14, Marc Treib wrote: > This should go into the ENABLE_EXTENSIONS above Done. https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:155: void UpdateApprovedVersion(const std::string& extension_id, On 2016/06/03 13:24:14, Marc Treib wrote: > UpdateApprovedExtensionVersion? Done. https://codereview.chromium.org/2004043002/diff/140001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:408: void OnExtensionInstalled(content::BrowserContext* browser_context, On 2016/06/03 13:24:14, Marc Treib wrote: > This should go into the ENABLE_EXTENSIONS above; EnableExtensionIfPossible > probably too. Done.
https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... File chrome/test/base/testing_profile.cc (right): https://codereview.chromium.org/2004043002/diff/20002/chrome/test/base/testin... chrome/test/base/testing_profile.cc:425: #if defined(ENABLE_SUPERVISED_USERS) On 2016/06/06 15:01:36, mamir wrote: > On 2016/06/03 13:24:13, Marc Treib wrote: > > On 2016/06/03 09:45:55, mamir wrote: > > > On 2016/05/24 09:54:58, Marc Treib wrote: > > > > Is it necessary to move this up here? > > > > It used to happen after > > > > browser_context_dependency_manager_->CreateBrowserContextServicesForTest, > > > doing > > > > it before that seems like it might mess things up... > > > > > > Yes, it is. > > > Because CreatePrefServiceForSupervisedUser() requires the > > > SupervisedUserSettingsService to be initialized (specifically to have a pref > > > store) > > > > And moving all the PrefService stuff down, after the dependency manager is > > initialized, is not an option? > > I checked but couldn't be 100% sure whether it causes problems as currently > implemented. > This is anyway a TestingProfile and all tests pass, so, we should be relatively > fine.! Acknowledged. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:74: #include "chrome/browser/extensions/extension_sync_service.h" Not needed? https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: approved_extensions_map_[extension_id] = version; wrong indent https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: approved_extensions_map_[extension_id] = version; You also need to update the corresponding SU setting in Sync. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:959: base::Version version = base::Version(version_str); Just base::Version version(version_str); https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:963: LOG(ERROR) << "Invalid version number " << version_str; DLOG(WARNING) should be enough https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:995: // This calls is responsible only for updating the approved version "This call" https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1004: // If the extensions is disabled because it requires parent approval, "the extension" https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1012: UpdateApprovedExtensionVersion(id, *extension->version()); When exactly do we get here? When do we have CUSTODIAN_APPROVAL_REQUIRED but not PERMISSIONS_INCREASE? Shouldn't the approved version be updated independently of CUSTODIAN_APPROVAL_REQUIRED? https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1065: return ExtensionState::BLOCKED; Braces please (the condition isn't on one line) https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1068: auto extension_it = approved_extensions_map_.find(extension.id()); Either use the |id| var here, or just remove it and use extension.id() everywhere. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1073: ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile_); nit: empty line before, not after. Or just inline into the if. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1077: return ExtensionState::REQUIRE_APPROVAL; Also here, braces please https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:154: // approved_extensions_map_. Misleading comment: If it only did that, it wouldn't really need its own method. However, it also re-enables the extension if the version now matches.
mamir@chromium.org changed reviewers: + rdevlin.cronin@chromium.org
rdevlin.cronin@chromium.org: Please review this CL and give me your feedback. Thank you. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:74: #include "chrome/browser/extensions/extension_sync_service.h" On 2016/06/07 10:27:03, Marc Treib wrote: > Not needed? Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: approved_extensions_map_[extension_id] = version; On 2016/06/07 10:27:03, Marc Treib wrote: > wrong indent Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: approved_extensions_map_[extension_id] = version; On 2016/06/07 10:27:04, Marc Treib wrote: > You also need to update the corresponding SU setting in Sync. Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:959: base::Version version = base::Version(version_str); On 2016/06/07 10:27:03, Marc Treib wrote: > Just > base::Version version(version_str); Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:963: LOG(ERROR) << "Invalid version number " << version_str; On 2016/06/07 10:27:04, Marc Treib wrote: > DLOG(WARNING) should be enough Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:995: // This calls is responsible only for updating the approved version On 2016/06/07 10:27:04, Marc Treib wrote: > "This call" Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1004: // If the extensions is disabled because it requires parent approval, On 2016/06/07 10:27:04, Marc Treib wrote: > "the extension" Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1012: UpdateApprovedExtensionVersion(id, *extension->version()); On 2016/06/07 10:27:04, Marc Treib wrote: > When exactly do we get here? When do we have CUSTODIAN_APPROVAL_REQUIRED but not > PERMISSIONS_INCREASE? > Shouldn't the approved version be updated independently of > CUSTODIAN_APPROVAL_REQUIRED? We get here when SupervisedUserService.MustRemainDisabeled disables the extension due to non-matching approved and installed versions. And returns the "CUSTODIAN_APPROVAL_REQUIRED" disable reason. But you are right, the approved version should be updated independently of the CUSTODIAN_APPROVAL_REQUIRED! https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1065: return ExtensionState::BLOCKED; On 2016/06/07 10:27:03, Marc Treib wrote: > Braces please (the condition isn't on one line) Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1068: auto extension_it = approved_extensions_map_.find(extension.id()); On 2016/06/07 10:27:04, Marc Treib wrote: > Either use the |id| var here, or just remove it and use extension.id() > everywhere. Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1073: ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile_); On 2016/06/07 10:27:03, Marc Treib wrote: > nit: empty line before, not after. Or just inline into the if. Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1077: return ExtensionState::REQUIRE_APPROVAL; On 2016/06/07 10:27:04, Marc Treib wrote: > Also here, braces please Done. https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.h (right): https://codereview.chromium.org/2004043002/diff/160001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.h:154: // approved_extensions_map_. On 2016/06/07 10:27:04, Marc Treib wrote: > Misleading comment: If it only did that, it wouldn't really need its own method. > However, it also re-enables the extension if the version now matches. Done.
Please add a CL description and bug number. https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:285: approved_extensions_map_[extension_id] = version; Hm, should probably make sure that the approved version can never get smaller? https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1012: // it has been approved before. This comment is inaccurate, no parent approval involved really. https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_settings_service.cc (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_settings_service.cc:172: dict->SetWithoutPathExpansion(key_suffix, value.release()); Not your doing, but could you use std::move(value) instead of value.release()? The raw-pointer version of SetWithoutPathExpansion is deprecated. https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_settings_service.h (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_settings_service.h:115: // Updates supervised user settings and uploads it to the Sync server if they grammar: singular please. Also the "if they..." part is inaccurate; this method doesn't check anything of the sort.
Description was changed from ========== BUG= ========== to ========== Supervised users can installs apps and extensions and send to their custodian asking for approval. Apps and extensions are disabled until approved by the custodian. If the custodian denies the request, the corresponding extension is uninstalled. BUG=608290 ==========
https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:285: approved_extensions_map_[extension_id] = version; On 2016/06/08 12:08:24, Marc Treib wrote: > Hm, should probably make sure that the approved version can never get smaller? omm, well, probably yes. But I don't think we should check here. Let's keep this method for always updating the approved version. I will check before calling it. https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1012: // it has been approved before. On 2016/06/08 12:08:24, Marc Treib wrote: > This comment is inaccurate, no parent approval involved really. Sorry, that was before I removed this check but I forgot to update the comment accordingly. https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_settings_service.h (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_settings_service.h:115: // Updates supervised user settings and uploads it to the Sync server if they On 2016/06/08 12:08:25, Marc Treib wrote: > grammar: singular please. Also the "if they..." part is inaccurate; this method > doesn't check anything of the sort. Done.
https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:285: approved_extensions_map_[extension_id] = version; On 2016/06/09 12:14:10, mamir wrote: > On 2016/06/08 12:08:24, Marc Treib wrote: > > Hm, should probably make sure that the approved version can never get smaller? > > omm, well, probably yes. > But I don't think we should check here. > Let's keep this method for always updating the approved version. > I will check before calling it. Hm, UpdateApprovedExtensionVersion is called in only one place, might as well inline it there. That removes the question about where to check the version. Also, right now we have UpdateApprovedExtensions and UpdateApprovedExtensionVersion - they sound similar, but do very different things. https://codereview.chromium.org/2004043002/diff/220001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/220001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1012: id, Extension::DISABLE_PERMISSIONS_INCREASE) wrong indent?
https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:285: approved_extensions_map_[extension_id] = version; On 2016/06/09 13:44:09, Marc Treib wrote: > On 2016/06/09 12:14:10, mamir wrote: > > On 2016/06/08 12:08:24, Marc Treib wrote: > > > Hm, should probably make sure that the approved version can never get > smaller? > > > > omm, well, probably yes. > > But I don't think we should check here. > > Let's keep this method for always updating the approved version. > > I will check before calling it. > > Hm, UpdateApprovedExtensionVersion is called in only one place, might as well > inline it there. That removes the question about where to check the version. > Also, right now we have UpdateApprovedExtensions and > UpdateApprovedExtensionVersion - they sound similar, but do very different > things. Done. https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_settings_service.cc (right): https://codereview.chromium.org/2004043002/diff/180001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_settings_service.cc:172: dict->SetWithoutPathExpansion(key_suffix, value.release()); On 2016/06/08 12:08:25, Marc Treib wrote: > Not your doing, but could you use std::move(value) instead of value.release()? > The raw-pointer version of SetWithoutPathExpansion is deprecated. Done. https://codereview.chromium.org/2004043002/diff/220001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/220001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1012: id, Extension::DISABLE_PERMISSIONS_INCREASE) On 2016/06/09 13:44:09, Marc Treib wrote: > wrong indent? According to eclipse, not. According to git cl format, yes. ;-) Done.
https://codereview.chromium.org/2004043002/diff/240001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/240001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:296: service->EnableExtension(extension_id); Ah, so you remove the CUSTODIAN_APPROVAL_REQUIRED reason unconditionally, and rely on the ManagementPolicy to add it back if necessary? I feel like that deserves an extra comment above where you remove the disable reason...
https://codereview.chromium.org/2004043002/diff/240001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/240001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:296: service->EnableExtension(extension_id); On 2016/06/09 15:47:36, Marc Treib wrote: > Ah, so you remove the CUSTODIAN_APPROVAL_REQUIRED reason unconditionally, and > rely on the ManagementPolicy to add it back if necessary? I feel like that > deserves an extra comment above where you remove the disable reason... Done.
Still catching up after being away for a couple days, and probably want to take another look at the tests, but a few things I noticed. https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1735: InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)}; nitty nit: I think style would be to have closing bracket on a newline (if the opening bracket isn't on the same line as an item). https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:254: callback, 0); git cl format https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:291: // from service->EnableExtension() below) will add it back if necessary. This is true, but is pretty inefficient. Is there a reason to not do something like: EnableExtensionIfAllowed(id) { if (GetExtensionState() in [BLOCKED, REQUIRE_APPROVAL]) return; // Extension must remain disabled if (!prefs->HasDisableReason(APPROVAL_REQUIRED)) return; // Disabled for other reasons prefs->RemoveDisableReason(APPROVAL_REQUIRED); if (!prefs->GetDisableReasons()) service->EnableExtension() } It seems a little more straight forward, and less likely to cause something wacky with the intersection of policy providers. As an example of something wacky to avoid, what happens if: Extension A is disabled with approval required We call into here and remove the disable reason We enter EnableExtension() Another PolicyProvider (let's say blacklist) is asked *first* and says the extension must remain disabled. The extension will be disabled with reason blacklist, but not reason approval required. Obviously, slim chance of this happening (it would have to be added to the blacklist after being disabled, etc), but removing disable reasons and hoping we catch it just sounds risky to me in general. https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:546: extensions::ExtensionRegistry::Get(profile)->AddObserver(this); Don't we need to remove this when it's dtored? (Note: ScopedObservers are great for this.)
Thank you very much Devlin for your useful feedback/comments. https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1735: InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)}; On 2016/06/10 00:09:44, Devlin wrote: > nitty nit: I think style would be to have closing bracket on a newline (if the > opening bracket isn't on the same line as an item). Done. https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:254: callback, 0); On 2016/06/10 00:09:44, Devlin wrote: > git cl format git cl format is fine with this part. Do you have any specific concern? https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:291: // from service->EnableExtension() below) will add it back if necessary. On 2016/06/10 00:09:44, Devlin wrote: > This is true, but is pretty inefficient. Is there a reason to not do something > like: > EnableExtensionIfAllowed(id) { > if (GetExtensionState() in [BLOCKED, REQUIRE_APPROVAL]) > return; // Extension must remain disabled > if (!prefs->HasDisableReason(APPROVAL_REQUIRED)) > return; // Disabled for other reasons > prefs->RemoveDisableReason(APPROVAL_REQUIRED); > if (!prefs->GetDisableReasons()) > service->EnableExtension() > } > > It seems a little more straight forward, and less likely to cause something > wacky with the intersection of policy providers. > > As an example of something wacky to avoid, what happens if: > Extension A is disabled with approval required > We call into here and remove the disable reason > We enter EnableExtension() > Another PolicyProvider (let's say blacklist) is asked *first* and says the > extension must remain disabled. > > The extension will be disabled with reason blacklist, but not reason approval > required. Obviously, slim chance of this happening (it would have to be added > to the blacklist after being disabled, etc), but removing disable reasons and > hoping we catch it just sounds risky to me in general. Done. https://codereview.chromium.org/2004043002/diff/260001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:546: extensions::ExtensionRegistry::Get(profile)->AddObserver(this); On 2016/06/10 00:09:44, Devlin wrote: > Don't we need to remove this when it's dtored? (Note: ScopedObservers are great > for this.) Done.
Mostly just nits https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1777: extensions::ExtensionPrefs* extension_prefs = no extensions:: prefix (anywhere in this file) https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2067: EXPECT_NE(extension->VersionString(), old_version); nit: might be a little bit better to store the base::Version, and then do EXPECT_EQ(1, extension->version().CompareTo(old_version)); to ensure the version increased. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_features.cc (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_features.cc:1: // Copyright (c) 2016 The Chromium Authors. All rights reserved. nit: no (c) https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_features.cc:11: base::FEATURE_DISABLED_BY_DEFAULT}; nit: \n https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_features.h (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_features.h:12: extern const base::Feature kSupervisedUserInitiatedExtensionInstall; nit: \n after this line. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:290: if ((state == ExtensionState::BLOCKED) || nit: extra parens unnecessary on this line and line below https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:303: if (!extension_prefs->GetDisableReasons(extension_id)) { nitty nit: since DisableReasons are enums, this might be slightly better as GetDisableReasons == Extension::DISABLE_NONE https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1117: // While the following check allows the SU to modify the settings and enable do we use SU elsewhere in this code/comments? Will it be immediately understandable to a reader? https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1122: bool may_modify = (result != ExtensionState::FORCED); parens unnecessary https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1146: bool must_remain_disabled = (state == ExtensionState::BLOCKED) || parens unnecessary
Please also update your CL description: [Title] [Description] BUG=[bug] Each wrapped to 72 chars. I know I'm a stickler for this, but it makes the output look so much cleaner. :)
Description was changed from ========== Supervised users can installs apps and extensions and send to their custodian asking for approval. Apps and extensions are disabled until approved by the custodian. If the custodian denies the request, the corresponding extension is uninstalled. BUG=608290 ========== to ========== Supervised users initiated extensions installs Supervised users can install apps and extension. The extension will be installed in a disabled state and an approval request will be sent to their custodian. If the custodian approves the request, the extension will be enabled. If the custodian denies the request, the extension will be uninstalled. BUG=619526 ==========
https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1777: extensions::ExtensionPrefs* extension_prefs = On 2016/06/13 15:37:22, Devlin wrote: > no extensions:: prefix (anywhere in this file) Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2067: EXPECT_NE(extension->VersionString(), old_version); On 2016/06/13 15:37:22, Devlin wrote: > nit: might be a little bit better to store the base::Version, and then do > EXPECT_EQ(1, extension->version().CompareTo(old_version)); > to ensure the version increased. Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_features.cc (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_features.cc:1: // Copyright (c) 2016 The Chromium Authors. All rights reserved. On 2016/06/13 15:37:22, Devlin wrote: > nit: no (c) Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_features.cc:11: base::FEATURE_DISABLED_BY_DEFAULT}; On 2016/06/13 15:37:22, Devlin wrote: > nit: \n Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_features.h (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_features.h:12: extern const base::Feature kSupervisedUserInitiatedExtensionInstall; On 2016/06/13 15:37:22, Devlin wrote: > nit: \n after this line. Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:290: if ((state == ExtensionState::BLOCKED) || On 2016/06/13 15:37:22, Devlin wrote: > nit: extra parens unnecessary on this line and line below Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:303: if (!extension_prefs->GetDisableReasons(extension_id)) { On 2016/06/13 15:37:23, Devlin wrote: > nitty nit: since DisableReasons are enums, this might be slightly better as > GetDisableReasons == Extension::DISABLE_NONE Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1117: // While the following check allows the SU to modify the settings and enable On 2016/06/13 15:37:23, Devlin wrote: > do we use SU elsewhere in this code/comments? Will it be immediately > understandable to a reader? Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1122: bool may_modify = (result != ExtensionState::FORCED); On 2016/06/13 15:37:22, Devlin wrote: > parens unnecessary Done. https://codereview.chromium.org/2004043002/diff/280001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1146: bool must_remain_disabled = (state == ExtensionState::BLOCKED) || On 2016/06/13 15:37:23, Devlin wrote: > parens unnecessary Done.
https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:53: #include "extensions/browser/extension_registry.h" This needs to go into the #ifdef ENABLE_EXTENSIONS below https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:75: #include "chrome/browser/supervised_user/supervised_user_service_factory.h" This, OTOH, can go out into the regular includes. (Not feeling too strongly, but IMO it's less confusing that way) https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:90: using extensions::ExtensionSystem; These also need to go into an #ifdef https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: const Extension* extension = registry_->GetInstalledExtension(extension_id); Can extension be null? Seems like it could be, if we get an approval before it's actually installed/loaded? (If that's correct, then our test coverage is clearly not where it should be yet ;P) https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:304: == Extension::DISABLE_NONE) { Is this correctly aligned? https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:306: // properly enable the extension if possible. This comment seems out of place now - we've already checked that our ManagementPolicy implementation doesn't want to keep it disabled. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1082: extension_it->second != *(extension.version())) { nit: parens around extension.version() aren't necessary https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1158: *reason = Extension::DISABLE_PERMISSIONS_INCREASE; You probably also need to set error here? https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1162: *reason = Extension::DISABLE_CUSTODIAN_APPROVAL_REQUIRED; Hm, this is confusing. Can we ever get here if SU-initiated installs are not enabled?
Apart from Marc's comments, I don't see anything here. But I'll take another look once they're addressed.
https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:53: #include "extensions/browser/extension_registry.h" On 2016/06/14 13:53:34, Marc Treib wrote: > This needs to go into the #ifdef ENABLE_EXTENSIONS below Done. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:75: #include "chrome/browser/supervised_user/supervised_user_service_factory.h" On 2016/06/14 13:53:34, Marc Treib wrote: > This, OTOH, can go out into the regular includes. (Not feeling too strongly, but > IMO it's less confusing that way) Done. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:90: using extensions::ExtensionSystem; On 2016/06/14 13:53:34, Marc Treib wrote: > These also need to go into an #ifdef Done. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:286: const Extension* extension = registry_->GetInstalledExtension(extension_id); On 2016/06/14 13:53:34, Marc Treib wrote: > Can extension be null? Seems like it could be, if we get an approval before it's > actually installed/loaded? > (If that's correct, then our test coverage is clearly not where it should be yet > ;P) Fixed and added a proper unit test ;-) Done! https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:304: == Extension::DISABLE_NONE) { On 2016/06/14 13:53:34, Marc Treib wrote: > Is this correctly aligned? Done. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:306: // properly enable the extension if possible. On 2016/06/14 13:53:34, Marc Treib wrote: > This comment seems out of place now - we've already checked that our > ManagementPolicy implementation doesn't want to keep it disabled. The comment is intended to refer to other ManagementPolicies. Still seems out of place? https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1082: extension_it->second != *(extension.version())) { On 2016/06/14 13:53:34, Marc Treib wrote: > nit: parens around extension.version() aren't necessary Done. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1158: *reason = Extension::DISABLE_PERMISSIONS_INCREASE; On 2016/06/14 13:53:34, Marc Treib wrote: > You probably also need to set error here? Done. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1162: *reason = Extension::DISABLE_CUSTODIAN_APPROVAL_REQUIRED; On 2016/06/14 13:53:34, Marc Treib wrote: > Hm, this is confusing. Can we ever get here if SU-initiated installs are not > enabled? Not really, because if SU-initiated installs are not enabled, the extensions will be blocked and "UserMayLoad" will return false. (I assume MustRemainDisabled is called only for loaded extensions)
https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:304: == Extension::DISABLE_NONE) { On 2016/06/15 09:40:11, mamir wrote: > On 2016/06/14 13:53:34, Marc Treib wrote: > > Is this correctly aligned? > > Done. git cl formatted now? Still looks weird, but oh well. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:306: // properly enable the extension if possible. On 2016/06/15 09:40:11, mamir wrote: > On 2016/06/14 13:53:34, Marc Treib wrote: > > This comment seems out of place now - we've already checked that our > > ManagementPolicy implementation doesn't want to keep it disabled. > > The comment is intended to refer to other ManagementPolicies. > Still seems out of place? Yes, because it's not really relevant - we don't expect any interference from other policies. Of course it could still happen, but that's just a property of EnableExtension. I don't see a reason to specifically call it out here. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1162: *reason = Extension::DISABLE_CUSTODIAN_APPROVAL_REQUIRED; On 2016/06/15 09:40:11, mamir wrote: > On 2016/06/14 13:53:34, Marc Treib wrote: > > Hm, this is confusing. Can we ever get here if SU-initiated installs are not > > enabled? > > Not really, because if SU-initiated installs are not enabled, the extensions > will be blocked and "UserMayLoad" will return false. > (I assume MustRemainDisabled is called only for loaded extensions) If it can't happen, then the code shouldn't handle it. Add a DCHECK instead? (Not sure in what circumstances MustRemainDisabled can be called..) https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1640: // extensions. It doesn't change the disable reasons. Is it particularly relevant that this doesn't change disable reasons? If so, should you check it? nitty nit: only one space after "." https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1802: RequestId(good_crx, version), testing::_)) I'd just use testing::_ instead of an explicit request id - we don't expect any request at all. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1819: ExtensionApprovalBeforeInstallation) { nit: fits on the previous line I think https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1830: const std::string version("1.0.0.0"); nit: Why is one const and the other isn't? (Don't really care which, but please be consistent) https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2111: UpdateSUInitiatedInstallWithPermissionIncrease) { This test name suggests that it's the counterpart to the above one, but the code is actually very different. Why? https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2118: const std::string version("1"); Also here: please try to be consistent with consts https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2130: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); Also check the disable reasons? https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2131: } Please extend the test with an incoming approval after the update and make sure the extension gets re-enabled. Also extend the test (or add new ones) for other cases: - Approval with mismatching version (extension should remain disabled). - Approval comes in before the extension update (extension should be temporarily disabled in the meantime). https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:287: extensions::ExtensionRegistry* registry_ = This should be registry (no trailing underscore). optional: You could add a "using" declaration above, so you don't have to say "extensions::", like for the other things in that namespace https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1167: if (error) nit: braces if the body doesn't fit on one line.
https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:304: == Extension::DISABLE_NONE) { On 2016/06/15 12:31:07, Marc Treib wrote: > On 2016/06/15 09:40:11, mamir wrote: > > On 2016/06/14 13:53:34, Marc Treib wrote: > > > Is this correctly aligned? > > > > Done. > > git cl formatted now? Still looks weird, but oh well. Yup :-) https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:306: // properly enable the extension if possible. On 2016/06/15 12:31:07, Marc Treib wrote: > On 2016/06/15 09:40:11, mamir wrote: > > On 2016/06/14 13:53:34, Marc Treib wrote: > > > This comment seems out of place now - we've already checked that our > > > ManagementPolicy implementation doesn't want to keep it disabled. > > > > The comment is intended to refer to other ManagementPolicies. > > Still seems out of place? > > Yes, because it's not really relevant - we don't expect any interference from > other policies. Of course it could still happen, but that's just a property of > EnableExtension. I don't see a reason to specifically call it out here. Done. https://codereview.chromium.org/2004043002/diff/300001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1162: *reason = Extension::DISABLE_CUSTODIAN_APPROVAL_REQUIRED; On 2016/06/15 12:31:07, Marc Treib wrote: > On 2016/06/15 09:40:11, mamir wrote: > > On 2016/06/14 13:53:34, Marc Treib wrote: > > > Hm, this is confusing. Can we ever get here if SU-initiated installs are not > > > enabled? > > > > Not really, because if SU-initiated installs are not enabled, the extensions > > will be blocked and "UserMayLoad" will return false. > > (I assume MustRemainDisabled is called only for loaded extensions) > > If it can't happen, then the code shouldn't handle it. Add a DCHECK instead? > (Not sure in what circumstances MustRemainDisabled can be called..) Sorry, I was wrong. It can actually reach this part for pre-installed extensions if SU-initiated installs aren't enabled. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1640: // extensions. It doesn't change the disable reasons. On 2016/06/15 12:31:07, Marc Treib wrote: > Is it particularly relevant that this doesn't change disable reasons? If so, > should you check it? > > nitty nit: only one space after "." The idea is: this method is responsible only for getting a extension approval SUSetting sync entity. It doesn't simulate any change in the extension disable reasons. Makes sense? I have rephrased the comment. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1802: RequestId(good_crx, version), testing::_)) On 2016/06/15 12:31:07, Marc Treib wrote: > I'd just use testing::_ instead of an explicit request id - we don't expect any > request at all. Done. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1819: ExtensionApprovalBeforeInstallation) { On 2016/06/15 12:31:07, Marc Treib wrote: > nit: fits on the previous line I think Done. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1830: const std::string version("1.0.0.0"); On 2016/06/15 12:31:07, Marc Treib wrote: > nit: Why is one const and the other isn't? (Don't really care which, but please > be consistent) Done. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2111: UpdateSUInitiatedInstallWithPermissionIncrease) { On 2016/06/15 12:31:07, Marc Treib wrote: > This test name suggests that it's the counterpart to the above one, but the code > is actually very different. Why? Because they test different flows. The first tests this flow: 1- kid initiates an install. 2- custodian approves it. 3- extension updates without permission increase. 4- approved version automatically updates. The second tests this flow: 1- kid initiates an install. 2- custodian approves it. 3- extension updates with permission increase. 4- extension is disabled. The rest of the flow is already thoroughly covered in multiple other test cases (matching version, non-matching version ...etc.) https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2118: const std::string version("1"); On 2016/06/15 12:31:07, Marc Treib wrote: > Also here: please try to be consistent with consts Done. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2130: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); On 2016/06/15 12:31:07, Marc Treib wrote: > Also check the disable reasons? Done. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2131: } On 2016/06/15 12:31:07, Marc Treib wrote: > Please extend the test with an incoming approval after the update and make sure > the extension gets re-enabled. Also extend the test (or add new ones) for other > cases: > - Approval with mismatching version (extension should remain disabled). > - Approval comes in before the extension update (extension should be temporarily > disabled in the meantime). But this would be duplicating other tests covering the same situation for cusotidan installed extension. IIUC, the only difference is in the initial steps of how we reach this stage of an extension disabled due to permission increase. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:287: extensions::ExtensionRegistry* registry_ = On 2016/06/15 12:31:07, Marc Treib wrote: > This should be registry (no trailing underscore). > optional: You could add a "using" declaration above, so you don't have to say > "extensions::", like for the other things in that namespace Done. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1167: if (error) On 2016/06/15 12:31:07, Marc Treib wrote: > nit: braces if the body doesn't fit on one line. Done.
https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1640: // extensions. It doesn't change the disable reasons. On 2016/06/15 17:30:03, mamir wrote: > On 2016/06/15 12:31:07, Marc Treib wrote: > > Is it particularly relevant that this doesn't change disable reasons? If so, > > should you check it? > > > > nitty nit: only one space after "." > > The idea is: this method is responsible only for getting a extension approval > SUSetting sync entity. It doesn't simulate any change in the extension disable > reasons. > Makes sense? > I have rephrased the comment. Acknowledged. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2111: UpdateSUInitiatedInstallWithPermissionIncrease) { On 2016/06/15 17:30:03, mamir wrote: > On 2016/06/15 12:31:07, Marc Treib wrote: > > This test name suggests that it's the counterpart to the above one, but the > code > > is actually very different. Why? > > Because they test different flows. > The first tests this flow: > 1- kid initiates an install. > 2- custodian approves it. > 3- extension updates without permission increase. > 4- approved version automatically updates. > > The second tests this flow: > 1- kid initiates an install. > 2- custodian approves it. > 3- extension updates with permission increase. > 4- extension is disabled. > The rest of the flow is already thoroughly covered in multiple other test cases > (matching version, non-matching version ...etc.) > So, steps 1 and 2 are identical, and step 3 is identical except for the content of the extension. Yet the code looks very different. That's confusing at best. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2131: } On 2016/06/15 17:30:03, mamir wrote: > On 2016/06/15 12:31:07, Marc Treib wrote: > > Please extend the test with an incoming approval after the update and make > sure > > the extension gets re-enabled. Also extend the test (or add new ones) for > other > > cases: > > - Approval with mismatching version (extension should remain disabled). > > - Approval comes in before the extension update (extension should be > temporarily > > disabled in the meantime). > > But this would be duplicating other tests covering the same situation for > cusotidan installed extension. > IIUC, the only difference is in the initial steps of how we reach this stage of > an extension disabled due to permission increase. The way that approval and re-enabling work are very different for custodian-installed vs. SU-initiated, so the tests should cover both. In particular, for SU-initiated installs, there are a few variations that simply don't exist in the custodian-installed case, e.g. whether the extension update or the approval arrives first.
https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2111: UpdateSUInitiatedInstallWithPermissionIncrease) { On 2016/06/16 08:26:54, Marc Treib wrote: > On 2016/06/15 17:30:03, mamir wrote: > > On 2016/06/15 12:31:07, Marc Treib wrote: > > > This test name suggests that it's the counterpart to the above one, but the > > code > > > is actually very different. Why? > > > > Because they test different flows. > > The first tests this flow: > > 1- kid initiates an install. > > 2- custodian approves it. > > 3- extension updates without permission increase. > > 4- approved version automatically updates. > > > > The second tests this flow: > > 1- kid initiates an install. > > 2- custodian approves it. > > 3- extension updates with permission increase. > > 4- extension is disabled. > > The rest of the flow is already thoroughly covered in multiple other test > cases > > (matching version, non-matching version ...etc.) > > > > So, steps 1 and 2 are identical, and step 3 is identical except for the content > of the extension. Yet the code looks very different. That's confusing at best. As discussed offline, in order to unify both tests, I have to touch the existing similar tests for custodian installed extension. I will unify all test for custodian installed and supervised user initiated installed for both no permission increase and permission increase. https://codereview.chromium.org/2004043002/diff/320001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2131: } On 2016/06/16 08:26:54, Marc Treib wrote: > On 2016/06/15 17:30:03, mamir wrote: > > On 2016/06/15 12:31:07, Marc Treib wrote: > > > Please extend the test with an incoming approval after the update and make > > sure > > > the extension gets re-enabled. Also extend the test (or add new ones) for > > other > > > cases: > > > - Approval with mismatching version (extension should remain disabled). > > > - Approval comes in before the extension update (extension should be > > temporarily > > > disabled in the meantime). > > > > But this would be duplicating other tests covering the same situation for > > cusotidan installed extension. > > IIUC, the only difference is in the initial steps of how we reach this stage > of > > an extension disabled due to permission increase. > > The way that approval and re-enabling work are very different for > custodian-installed vs. SU-initiated, so the tests should cover both. In > particular, for SU-initiated installs, there are a few variations that simply > don't exist in the custodian-installed case, e.g. whether the extension update > or the approval arrives first. Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (left): https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1690: base::FilePath base_path = data_dir().AppendASCII("autoupdate"); As discussed offline with Marc, we decided to unify tests with/without permission increase for both custodian installed and kid-initiated installs. Hence touching this part of the code for custodian-installed extensions.
https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1644: int creation_flags = 0; Ah, so this will now require a rebase onto the other CL... https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2078: ASSERT_EQ(id, good_crx); nit: I'd just ASSERT_EQ(extension->id(), good_crx) and use good_crx below https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2079: ASSERT_TRUE(extension); This needs to go before dereferencing extension https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2098: std::string version("1"); nit: version1, since there's also a version2 below https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2137: std::string version("1"); version1 https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2180: std::string version("1"); version1 https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2190: const Extension* extension = service()->GetInstalledExtension(id); Seems to be unused? https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2192: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); EXPECT_TRUE(..disabled..Contains..) https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:300: ExtensionState state = GetExtensionState(*extension); Early-out if the state is FORCED? (Won't change anything, but IMO makes things a bit clearer) https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:302: if (state == ExtensionState::BLOCKED || I think for BLOCKED extensions we don't want to add the disable reason? They should already be disabled/unloaded anyway. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:306: return; // Extension must remain disabled. nit: comment is now inaccurate (I'd just remove it) https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:317: return; "return" not required https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1020: ChangeExtensionStateIfNecessary(id); Could we just call this unconditionally at the end of the method? https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1098: } else { nit: no "else" after "return"
https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1644: int creation_flags = 0; On 2016/06/17 16:55:12, Marc Treib wrote: > Ah, so this will now require a rebase onto the other CL... Assuming both CLs will be eventually submitted ;-) https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2078: ASSERT_EQ(id, good_crx); On 2016/06/17 16:55:12, Marc Treib wrote: > nit: I'd just ASSERT_EQ(extension->id(), good_crx) and use good_crx below Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2079: ASSERT_TRUE(extension); On 2016/06/17 16:55:12, Marc Treib wrote: > This needs to go before dereferencing extension Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2098: std::string version("1"); On 2016/06/17 16:55:12, Marc Treib wrote: > nit: version1, since there's also a version2 below Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2137: std::string version("1"); On 2016/06/17 16:55:12, Marc Treib wrote: > version1 Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2180: std::string version("1"); On 2016/06/17 16:55:12, Marc Treib wrote: > version1 Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2190: const Extension* extension = service()->GetInstalledExtension(id); On 2016/06/17 16:55:12, Marc Treib wrote: > Seems to be unused? Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2192: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); On 2016/06/17 16:55:12, Marc Treib wrote: > EXPECT_TRUE(..disabled..Contains..) Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:300: ExtensionState state = GetExtensionState(*extension); On 2016/06/17 16:55:13, Marc Treib wrote: > Early-out if the state is FORCED? (Won't change anything, but IMO makes things a > bit clearer) Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:302: if (state == ExtensionState::BLOCKED || On 2016/06/17 16:55:13, Marc Treib wrote: > I think for BLOCKED extensions we don't want to add the disable reason? They > should already be disabled/unloaded anyway. Not really. This is called when we get a new approved version from Sync. This is what actually disables the extension in case of non-matching approved/installed versions. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:306: return; // Extension must remain disabled. On 2016/06/17 16:55:13, Marc Treib wrote: > nit: comment is now inaccurate (I'd just remove it) Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:317: return; On 2016/06/17 16:55:13, Marc Treib wrote: > "return" not required Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1020: ChangeExtensionStateIfNecessary(id); On 2016/06/17 16:55:13, Marc Treib wrote: > Could we just call this unconditionally at the end of the method? Done. https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1098: } else { On 2016/06/17 16:55:13, Marc Treib wrote: > nit: no "else" after "return" Done.
https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:302: if (state == ExtensionState::BLOCKED || On 2016/06/19 12:40:14, mamir wrote: > On 2016/06/17 16:55:13, Marc Treib wrote: > > I think for BLOCKED extensions we don't want to add the disable reason? They > > should already be disabled/unloaded anyway. > > Not really. > This is called when we get a new approved version from Sync. This is what > actually disables the extension in case of non-matching approved/installed > versions. But in that case, it won't be BLOCKED, but REQUIRE_APPROVAL, right?
https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/360001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:302: if (state == ExtensionState::BLOCKED || On 2016/06/20 12:44:18, Marc Treib wrote: > On 2016/06/19 12:40:14, mamir wrote: > > On 2016/06/17 16:55:13, Marc Treib wrote: > > > I think for BLOCKED extensions we don't want to add the disable reason? They > > > should already be disabled/unloaded anyway. > > > > Not really. > > This is called when we get a new approved version from Sync. This is what > > actually disables the extension in case of non-matching approved/installed > > versions. > > But in that case, it won't be BLOCKED, but REQUIRE_APPROVAL, right? ooops, sorry. You are right.
Looking good now! One last comment :) https://codereview.chromium.org/2004043002/diff/400001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/400001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:301: if (state == ExtensionState::FORCED) Add BLOCKED here, to make it obvious that we're not touching these here? And maybe add a comment explaining why it's not necessary to do anything about FORCED and BLOCKED extensions here.
https://codereview.chromium.org/2004043002/diff/400001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/400001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:301: if (state == ExtensionState::FORCED) On 2016/06/20 15:48:06, Marc Treib wrote: > Add BLOCKED here, to make it obvious that we're not touching these here? And > maybe add a comment explaining why it's not necessary to do anything about > FORCED and BLOCKED extensions here. Done.
https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1620: EXPECT_TRUE(registry()->disabled_extensions().Contains(extension->id())); nit: to be thorough, maybe also check disabled reasons? https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1644: int creation_flags = 0; lines 1644 - 1663 and 1606 - 1624 look identical % the dir/pem path. Can you make a helper method that passes those in? https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1666: const std::string& version, why not just pass in a base::Version here? (and other similar places) https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2080: EXPECT_FALSE(registry()->enabled_extensions().Contains(good_crx)); nit: probably enough to just check the disabled set. https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1115: bool may_load = (result != ExtensionState::BLOCKED); nit: no parens needed https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1174: if (error) this is the same as line 1168, right? Can we just put one common call on line 1160?
lgtm
https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1620: EXPECT_TRUE(registry()->disabled_extensions().Contains(extension->id())); On 2016/06/20 17:32:28, Devlin wrote: > nit: to be thorough, maybe also check disabled reasons? Done. https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1644: int creation_flags = 0; On 2016/06/20 17:32:28, Devlin wrote: > lines 1644 - 1663 and 1606 - 1624 look identical % the dir/pem path. Can you > make a helper method that passes those in? Done. https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1666: const std::string& version, On 2016/06/20 17:32:28, Devlin wrote: > why not just pass in a base::Version here? (and other similar places) Because it is used to build the bath, and hence we need to string to make sure we get the exact required path. (i.e. 1 vs 1.0) https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2080: EXPECT_FALSE(registry()->enabled_extensions().Contains(good_crx)); On 2016/06/20 17:32:28, Devlin wrote: > nit: probably enough to just check the disabled set. Done. https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1115: bool may_load = (result != ExtensionState::BLOCKED); On 2016/06/20 17:32:28, Devlin wrote: > nit: no parens needed Done. https://codereview.chromium.org/2004043002/diff/420001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1174: if (error) On 2016/06/20 17:32:28, Devlin wrote: > this is the same as line 1168, right? Can we just put one common call on line > 1160? Done.
mamir@chromium.org changed reviewers: + phajdan.jr@chromium.org
phajdan.jr@chromium.org: Please review changes in chrome/test/base/testing_profile.cc chrome/test/base/testing_profile.h chrome/test/DEPS
mamir@chromium.org changed reviewers: + holte@chromium.org
Hi holte@chromium.org Please, review changes in tools/metrics/histograms/histograms.xml
lgtm https://codereview.chromium.org/2004043002/diff/440001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/440001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1615: const base::FilePath& base_path = data_dir().AppendASCII("autoupdate"); nit: these shouldn't be const&, since they are ctored here. I think the compiler is smart enough to save us, but better to just have them be base::FilePath.
histograms lgtm
Patchset #29 (id:540001) has been deleted
Hi Marc and Devlin, Please, have a another look after rebasing to the other CL of switching the WAS_INSTALLED_BY_CUSTODIAN creation flag to a pref. I think it's worth checking because the merge wasn't super trivial. In addition, please, have a look on my comment in extension_util.cc. I have strong feeling that I am missing something. Thank you. https://codereview.chromium.org/2004043002/diff/440001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/440001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1615: const base::FilePath& base_path = data_dir().AppendASCII("autoupdate"); On 2016/06/21 16:54:37, Devlin wrote: > nit: these shouldn't be const&, since they are ctored here. I think the > compiler is smart enough to save us, but better to just have them be > base::FilePath. Done. https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); Marc, Devlin, I had to add this call because the test ExtensionServiceTestSupervised.DelegatedAndPreinstalledExtensionIsSUFirst was failing. The reason is we now added MustRemainDisabled call back to Superviseduser Service, which is returning false before reloading the extension, and doesn't get called during reloading the extension. So even after reloading, the extension stayed disabled. Is it fine like that? I don't think so. Advise, please!
The CQ bit was checked by mamir@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2004043002/560001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: chromeos_amd64-generic_chromium_compile_only_ng on tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/chromeos_amd64-...)
The CQ bit was checked by mamir@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2004043002/570001
chrome/test LGTM
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: linux_android_rel_ng on tryserver.chromium.android (JOB_FAILED, https://build.chromium.org/p/tryserver.chromium.android/builders/linux_androi...)
The CQ bit was checked by mamir@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2004043002/590001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: android_compile_dbg on tryserver.chromium.android (JOB_FAILED, https://build.chromium.org/p/tryserver.chromium.android/builders/android_comp...)
The CQ bit was checked by mamir@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2004043002/630001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: linux_chromium_chromeos_ozone_rel_ng on tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...)
https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); ? I'm pretty sure we don't want to do this. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1125: // upon extension update if it doesn't require extra permission. nit: This isn't really accurate anymore. It's also responsible for disabling/re-enabling the extension as required. I'd just reformulate it to just refer to extension updates. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1134: // new permissions, we update the approved_version and re-enable it. nit: I'd remove the "and re-enable it" part (and maybe add a comment to the ChangeExtensionStateIfNecessary call below) https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1166: ChangeExtensionStateIfNecessary(extensions_entry.first); Ah, one more thing here: If an approval was removed, we might have to disable the extension, but here we only update the ones that still have approvals (matching or not). https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1175: // When it gets installed, GetExtensionState() will return ALLOWED, hence IMO this isn't really accurate, GetExtensionState might return anything. I'd just say that things will be handled after installation. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1182: ExtensionSystem::Get(profile_)->extension_service(); nit: You could move both of these to later in the method. (Obsolete if you use a switch) https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1187: if (state == ExtensionState::BLOCKED || state == ExtensionState::FORCED) nit: This might be easier to read as a switch instead of a series of ifs?
https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:239: const Extension* extension = registry->GetInstalledExtension(extension_id); nit: Move getting registry and extension down to where you actually need it. https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:243: // If the installed_by_custodian flag is reset, do nothing. Inaccurate, you *do* do something. https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); On 2016/06/23 11:43:20, mamir wrote: > Marc, Devlin, > I had to add this call because the test > ExtensionServiceTestSupervised.DelegatedAndPreinstalledExtensionIsSUFirst > was failing. > > The reason is we now added MustRemainDisabled call back to Superviseduser > Service, which is returning false before reloading the extension, and doesn't > get called during reloading the extension. > So even after reloading, the extension stayed disabled. > > Is it fine like that? I don't think so. > Advise, please! Why does MustRemainDisabled keep it disabled? If we have a matching approval, then the state should be ExtensionState::ALLOWED and everything should be fine? In any case, just unconditionally enabling here is definitely not the way to go.
https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:239: const Extension* extension = registry->GetInstalledExtension(extension_id); On 2016/06/24 12:46:33, Marc Treib wrote: > nit: Move getting registry and extension down to where you actually need it. Done. https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:243: // If the installed_by_custodian flag is reset, do nothing. On 2016/06/24 12:46:33, Marc Treib wrote: > Inaccurate, you *do* do something. Done. https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); On 2016/06/24 12:46:33, Marc Treib wrote: > On 2016/06/23 11:43:20, mamir wrote: > > Marc, Devlin, > > I had to add this call because the test > > ExtensionServiceTestSupervised.DelegatedAndPreinstalledExtensionIsSUFirst > > was failing. > > > > The reason is we now added MustRemainDisabled call back to Superviseduser > > Service, which is returning false before reloading the extension, and doesn't > > get called during reloading the extension. > > So even after reloading, the extension stayed disabled. > > > > Is it fine like that? I don't think so. > > Advise, please! > > Why does MustRemainDisabled keep it disabled? If we have a matching approval, > then the state should be ExtensionState::ALLOWED and everything should be fine? > In any case, just unconditionally enabling here is definitely not the way to go. hmm, this is for extension installed by custodian, right? So it should actually return FORCED. After adding log statements, MustRemainDisabled is called before calling SetWasInstalledByCustodian. And hence it reads the old value and returns true. This flags the extension to stay disabled even after we reload it. I completely agree that we cannot just unconditionally enable it. And I hence asked for input in case you have better ways in mind. Otherwise, I will keep investigating. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); On 2016/06/24 10:58:55, Marc Treib wrote: > ? > I'm pretty sure we don't want to do this. For the record, discussed in patchset 29 https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1125: // upon extension update if it doesn't require extra permission. On 2016/06/24 10:58:55, Marc Treib wrote: > nit: This isn't really accurate anymore. It's also responsible for > disabling/re-enabling the extension as required. I'd just reformulate it to just > refer to extension updates. Done. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1134: // new permissions, we update the approved_version and re-enable it. On 2016/06/24 10:58:55, Marc Treib wrote: > nit: I'd remove the "and re-enable it" part (and maybe add a comment to the > ChangeExtensionStateIfNecessary call below) Done. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1166: ChangeExtensionStateIfNecessary(extensions_entry.first); On 2016/06/24 10:58:55, Marc Treib wrote: > Ah, one more thing here: If an approval was removed, we might have to disable > the extension, but here we only update the ones that still have approvals > (matching or not). Well-spotted, thank you! Done and I have updated the tests to cover this as well. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1175: // When it gets installed, GetExtensionState() will return ALLOWED, hence On 2016/06/24 10:58:55, Marc Treib wrote: > IMO this isn't really accurate, GetExtensionState might return anything. I'd > just say that things will be handled after installation. Done. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1182: ExtensionSystem::Get(profile_)->extension_service(); On 2016/06/24 10:58:55, Marc Treib wrote: > nit: You could move both of these to later in the method. (Obsolete if you use a > switch) Done. https://codereview.chromium.org/2004043002/diff/630001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1187: if (state == ExtensionState::BLOCKED || state == ExtensionState::FORCED) On 2016/06/24 10:58:55, Marc Treib wrote: > nit: This might be easier to read as a switch instead of a series of ifs? Done.
The CQ bit was checked by mamir@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); On 2016/06/24 14:43:07, mamir wrote: > On 2016/06/24 12:46:33, Marc Treib wrote: > > On 2016/06/23 11:43:20, mamir wrote: > > > Marc, Devlin, > > > I had to add this call because the test > > > ExtensionServiceTestSupervised.DelegatedAndPreinstalledExtensionIsSUFirst > > > was failing. > > > > > > The reason is we now added MustRemainDisabled call back to Superviseduser > > > Service, which is returning false before reloading the extension, and > doesn't > > > get called during reloading the extension. > > > So even after reloading, the extension stayed disabled. > > > > > > Is it fine like that? I don't think so. > > > Advise, please! > > > > Why does MustRemainDisabled keep it disabled? If we have a matching approval, > > then the state should be ExtensionState::ALLOWED and everything should be > fine? > > In any case, just unconditionally enabling here is definitely not the way to > go. > > hmm, this is for extension installed by custodian, right? > So it should actually return FORCED. > > After adding log statements, MustRemainDisabled is called before calling > SetWasInstalledByCustodian. And hence it reads the old value and returns true. But it should be called again afterwards, no? That's the whole reason we're calling ReloadExtensions here after changing the pref. Clearly we're missing something, but from the top of my head I can't tell what. > This flags the extension to stay disabled even after we reload it. > > I completely agree that we cannot just unconditionally enable it. And I hence > asked for input in case you have better ways in mind. Otherwise, I will keep > investigating.
https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1158: for (auto imap : approved_extensions_map_) nit: what's "imap"? Also, const&
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: linux_chromium_chromeos_ozone_rel_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...)
https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); On 2016/06/24 15:00:59, Marc Treib wrote: > On 2016/06/24 14:43:07, mamir wrote: > > On 2016/06/24 12:46:33, Marc Treib wrote: > > > On 2016/06/23 11:43:20, mamir wrote: > > > > Marc, Devlin, > > > > I had to add this call because the test > > > > ExtensionServiceTestSupervised.DelegatedAndPreinstalledExtensionIsSUFirst > > > > was failing. > > > > > > > > The reason is we now added MustRemainDisabled call back to Superviseduser > > > > Service, which is returning false before reloading the extension, and > > doesn't > > > > get called during reloading the extension. > > > > So even after reloading, the extension stayed disabled. > > > > > > > > Is it fine like that? I don't think so. > > > > Advise, please! > > > > > > Why does MustRemainDisabled keep it disabled? If we have a matching > approval, > > > then the state should be ExtensionState::ALLOWED and everything should be > > fine? > > > In any case, just unconditionally enabling here is definitely not the way to > > go. > > > > hmm, this is for extension installed by custodian, right? > > So it should actually return FORCED. > > > > After adding log statements, MustRemainDisabled is called before calling > > SetWasInstalledByCustodian. And hence it reads the old value and returns > true. > > But it should be called again afterwards, no? That's the whole reason we're > calling ReloadExtensions here after changing the pref. > Clearly we're missing something, but from the top of my head I can't tell what. > > > This flags the extension to stay disabled even after we reload it. > > > > I completely agree that we cannot just unconditionally enable it. And I hence > > asked for input in case you have better ways in mind. Otherwise, I will keep > > investigating. > I would have also thought that calling Reload() would put it in the proper state. Have you checked that the supervised user service is hit during the reload call, or if not, why not? https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1644: const base::Version version("1"); Define this closer to its use, or maybe just inline it. https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1893: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); Maybe make a helper function IsDisabledForApproval(id) that checks the registry's disabled set and the disable reason. https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2209: EXPECT_EQ(0, I think we can just EXPECT_EQ(base::Version(approved_version), extension->version()) https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1018: const std::string& id = extension.id(); just inline id https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1072: bool may_not_uninstall = (result == ExtensionState::FORCED); no need for parens
https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1644: const base::Version version("1"); On 2016/06/24 16:09:40, Devlin wrote: > Define this closer to its use, or maybe just inline it. Done. https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1893: EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); On 2016/06/24 16:09:39, Devlin wrote: > Maybe make a helper function IsDisabledForApproval(id) that checks the > registry's disabled set and the disable reason. Done. https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:2209: EXPECT_EQ(0, On 2016/06/24 16:09:40, Devlin wrote: > I think we can just EXPECT_EQ(base::Version(approved_version), > extension->version()) Yup, sorry! Done! https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1018: const std::string& id = extension.id(); On 2016/06/24 16:09:40, Devlin wrote: > just inline id Done. https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1072: bool may_not_uninstall = (result == ExtensionState::FORCED); On 2016/06/24 16:09:40, Devlin wrote: > no need for parens Done. https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1158: for (auto imap : approved_extensions_map_) On 2016/06/24 15:04:05, Marc Treib wrote: > nit: what's "imap"? Also, const& Done.
https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1158: for (auto imap : approved_extensions_map_) On 2016/06/27 11:48:54, mamir wrote: > On 2016/06/24 15:04:05, Marc Treib wrote: > > nit: what's "imap"? Also, const& > > Done. nit^2: it's not an iterator, so ".._it" is kinda misleading https://codereview.chromium.org/2004043002/diff/670001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/670001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1703: EXPECT_FALSE(registry()->enabled_extensions().Contains(extension_id)); I find this super confusing to read... it shouldn't be enabled either way, so pull that out of the if? And if it's not expected to be loaded, shouldn't you check registry->GetInstalledExtension?
https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... File chrome/browser/extensions/extension_util.cc (right): https://codereview.chromium.org/2004043002/diff/560001/chrome/browser/extensi... chrome/browser/extensions/extension_util.cc:260: service->EnableExtension(extension_id); On 2016/06/24 16:09:39, Devlin wrote: > On 2016/06/24 15:00:59, Marc Treib wrote: > > On 2016/06/24 14:43:07, mamir wrote: > > > On 2016/06/24 12:46:33, Marc Treib wrote: > > > > On 2016/06/23 11:43:20, mamir wrote: > > > > > Marc, Devlin, > > > > > I had to add this call because the test > > > > > > ExtensionServiceTestSupervised.DelegatedAndPreinstalledExtensionIsSUFirst > > > > > was failing. > > > > > > > > > > The reason is we now added MustRemainDisabled call back to > Superviseduser > > > > > Service, which is returning false before reloading the extension, and > > > doesn't > > > > > get called during reloading the extension. > > > > > So even after reloading, the extension stayed disabled. > > > > > > > > > > Is it fine like that? I don't think so. > > > > > Advise, please! > > > > > > > > Why does MustRemainDisabled keep it disabled? If we have a matching > > approval, > > > > then the state should be ExtensionState::ALLOWED and everything should be > > > fine? > > > > In any case, just unconditionally enabling here is definitely not the way > to > > > go. > > > > > > hmm, this is for extension installed by custodian, right? > > > So it should actually return FORCED. > > > > > > After adding log statements, MustRemainDisabled is called before calling > > > SetWasInstalledByCustodian. And hence it reads the old value and returns > > true. > > > > But it should be called again afterwards, no? That's the whole reason we're > > calling ReloadExtensions here after changing the pref. > > Clearly we're missing something, but from the top of my head I can't tell > what. > > > > > This flags the extension to stay disabled even after we reload it. > > > > > > I completely agree that we cannot just unconditionally enable it. And I > hence > > > asked for input in case you have better ways in mind. Otherwise, I will > keep > > > investigating. > > > > I would have also thought that calling Reload() would put it in the proper > state. Have you checked that the supervised user service is hit during the > reload call, or if not, why not? OK, here is how it works. The way reload works is it disables the extension if required. But doesn't do the opposite. This is done at InstalledLoader::Load. If the extension is enabled, and the policy::MustRemainDisabled is true, it disables the extension, not the other way around. enableExtension fixed it because it does exactly what we need, if the extension is disabled and the policy::MustRemainDisabled is false, it enables it. However, after further investigation I think the issue is we both unloaded and disabled BLOCKED extensions when we got the information this is a Supervised User who isn't allowed to install apps. Instead, we should only unload it, not disable it. To support this hypothesis, if we disable the extension, we need to assign it a disable reasons. What would be a suitable disable reason for a BLOCKED extension? So, I adjusted the code and added a comment in the SUService::MustRemainDisabled. All tests pass now https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/650001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1158: for (auto imap : approved_extensions_map_) On 2016/06/27 11:56:35, Marc Treib wrote: > On 2016/06/27 11:48:54, mamir wrote: > > On 2016/06/24 15:04:05, Marc Treib wrote: > > > nit: what's "imap"? Also, const& > > > > Done. > > nit^2: it's not an iterator, so ".._it" is kinda misleading Done. https://codereview.chromium.org/2004043002/diff/670001/chrome/browser/extensi... File chrome/browser/extensions/extension_service_sync_unittest.cc (right): https://codereview.chromium.org/2004043002/diff/670001/chrome/browser/extensi... chrome/browser/extensions/extension_service_sync_unittest.cc:1703: EXPECT_FALSE(registry()->enabled_extensions().Contains(extension_id)); On 2016/06/27 11:56:35, Marc Treib wrote: > I find this super confusing to read... it shouldn't be enabled either way, so > pull that out of the if? And if it's not expected to be loaded, shouldn't you > check registry->GetInstalledExtension? Modified as discussed offline. Done!
LGTM with some more nits! https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1081: // Only extensions that requires approval should be disabled. s/requires/require https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1082: // Blocked extensions should be loaded all together, and are taken care of should NOT be loaded AT ALL https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1083: // at "UserMayLoad". nit: no quotes
https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1081: // Only extensions that requires approval should be disabled. On 2016/06/27 14:32:59, Marc Treib wrote: > s/requires/require Done. https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1082: // Blocked extensions should be loaded all together, and are taken care of On 2016/06/27 14:32:59, Marc Treib wrote: > should NOT be loaded AT ALL Done. https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1083: // at "UserMayLoad". On 2016/06/27 14:32:59, Marc Treib wrote: > nit: no quotes Done.
The CQ bit was checked by mamir@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... File chrome/browser/supervised_user/supervised_user_service.cc (right): https://codereview.chromium.org/2004043002/diff/710001/chrome/browser/supervi... chrome/browser/supervised_user/supervised_user_service.cc:1082: // Blocked extensions should be loaded all together, and are taken care of On 2016/06/27 14:58:13, mamir wrote: > On 2016/06/27 14:32:59, Marc Treib wrote: > > should NOT be loaded AT ALL > > Done. I didn't mean you should write in all caps, just highlighting the things that should be changed ;)
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: linux_chromium_chromeos_ozone_rel_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...)
lgtm once all Marc's comments are addressed.
The CQ bit was checked by mamir@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from holte@chromium.org, phajdan.jr@chromium.org, treib@chromium.org, rdevlin.cronin@chromium.org Link to the patchset: https://codereview.chromium.org/2004043002/#ps770001 (title: "Fixing the build again!")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Try jobs failed on following builders: chromium_presubmit on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/chromium_presub...)
mamir@chromium.org changed reviewers: + pavely@chromium.org
Hi Pavel, I need your LGTM because I added a sync dependency to chrome/test/DEPS. Thank you
chrome/test LGTM
chrome/test/DEPS lgtm
The CQ bit was checked by mamir@chromium.org
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Message was sent while issue was closed.
Description was changed from ========== Supervised users initiated extensions installs Supervised users can install apps and extension. The extension will be installed in a disabled state and an approval request will be sent to their custodian. If the custodian approves the request, the extension will be enabled. If the custodian denies the request, the extension will be uninstalled. BUG=619526 ========== to ========== Supervised users initiated extensions installs Supervised users can install apps and extension. The extension will be installed in a disabled state and an approval request will be sent to their custodian. If the custodian approves the request, the extension will be enabled. If the custodian denies the request, the extension will be uninstalled. BUG=619526 ==========
Message was sent while issue was closed.
Committed patchset #40 (id:770001)
Message was sent while issue was closed.
Description was changed from ========== Supervised users initiated extensions installs Supervised users can install apps and extension. The extension will be installed in a disabled state and an approval request will be sent to their custodian. If the custodian approves the request, the extension will be enabled. If the custodian denies the request, the extension will be uninstalled. BUG=619526 ========== to ========== Supervised users initiated extensions installs Supervised users can install apps and extension. The extension will be installed in a disabled state and an approval request will be sent to their custodian. If the custodian approves the request, the extension will be enabled. If the custodian denies the request, the extension will be uninstalled. BUG=619526 Committed: https://crrev.com/e960964b7ea2caff5289d4a2f40488af7613389d Cr-Commit-Position: refs/heads/master@{#402570} ==========
Message was sent while issue was closed.
Patchset 40 (id:??) landed as https://crrev.com/e960964b7ea2caff5289d4a2f40488af7613389d Cr-Commit-Position: refs/heads/master@{#402570} |