1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_ALLOWLIST_SERVICE_H_
6 #define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_ALLOWLIST_SERVICE_H_
7 
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/strings/string16.h"
17 #include "chrome/browser/supervised_user/supervised_users.h"
18 #include "components/sync/model/syncable_service.h"
19 
20 class PrefService;
21 class SupervisedUserSiteList;
22 
23 namespace base {
24 class DictionaryValue;
25 class FilePath;
26 }  // namespace base
27 
28 namespace component_updater {
29 class SupervisedUserWhitelistInstaller;
30 }
31 
32 namespace user_prefs {
33 class PrefRegistrySyncable;
34 }
35 
36 namespace sync_pb {
37 class ManagedUserWhitelistSpecifics;
38 }
39 
40 class SupervisedUserAllowlistService : public syncer::SyncableService {
41  public:
42   typedef base::Callback<void(
43       const std::vector<scoped_refptr<SupervisedUserSiteList>>&)>
44       SiteListsChangedCallback;
45 
46   SupervisedUserAllowlistService(
47       PrefService* prefs,
48       component_updater::SupervisedUserWhitelistInstaller* installer,
49       const std::string& client_id);
50   ~SupervisedUserAllowlistService() override;
51 
52   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
53 
54   void Init();
55 
56   // Adds a callback to be called when the list of loaded site lists changes.
57   // The callback will also be called immediately, to get the current
58   // site lists.
59   void AddSiteListsChangedCallback(const SiteListsChangedCallback& callback);
60 
61   // Returns a map (from CRX ID to name) of allowlists to be installed,
62   // specified on the command line.
63   static std::map<std::string, std::string> GetAllowlistsFromCommandLine();
64 
65   // Loads an already existing allowlist on disk (i.e. without downloading it as
66   // a component).
67   void LoadAllowlistForTesting(const std::string& id,
68                                const base::string16& title,
69                                const base::FilePath& path);
70 
71   // Unloads a allowlist. Public for testing.
72   void UnloadAllowlist(const std::string& id);
73 
74   // Creates Sync data for a allowlist with the given |id| and |name|.
75   // Public for testing.
76   static syncer::SyncData CreateAllowlistSyncData(const std::string& id,
77                                                   const std::string& name);
78 
79   // SyncableService implementation:
80   void WaitUntilReadyToSync(base::OnceClosure done) override;
81   base::Optional<syncer::ModelError> MergeDataAndStartSyncing(
82       syncer::ModelType type,
83       const syncer::SyncDataList& initial_sync_data,
84       std::unique_ptr<syncer::SyncChangeProcessor> sync_processor,
85       std::unique_ptr<syncer::SyncErrorFactory> error_handler) override;
86   void StopSyncing(syncer::ModelType type) override;
87   base::Optional<syncer::ModelError> ProcessSyncChanges(
88       const base::Location& from_here,
89       const syncer::SyncChangeList& change_list) override;
90 
91   syncer::SyncDataList GetAllSyncDataForTesting(syncer::ModelType type) const;
92 
93  private:
94   // The following methods handle allowlist additions, updates and removals,
95   // usually coming from Sync.
96   void AddNewAllowlist(base::DictionaryValue* pref_dict,
97                        const sync_pb::ManagedUserWhitelistSpecifics& allowlist);
98   void SetAllowlistProperties(
99       base::DictionaryValue* pref_dict,
100       const sync_pb::ManagedUserWhitelistSpecifics& allowlist);
101   void RemoveAllowlist(base::DictionaryValue* pref_dict, const std::string& id);
102 
103   enum AllowlistSource {
104     FROM_SYNC,
105     FROM_COMMAND_LINE,
106   };
107 
108   // Registers a new or existing allowlist.
109   void RegisterAllowlist(const std::string& id,
110                          const std::string& name,
111                          AllowlistSource source);
112 
113   void GetLoadedAllowlists(
114       std::vector<scoped_refptr<SupervisedUserSiteList>>* allowlists);
115 
116   void NotifyAllowlistsChanged();
117 
118   void OnAllowlistReady(const std::string& id,
119                         const base::string16& title,
120                         const base::FilePath& large_icon_path,
121                         const base::FilePath& allowlist_path);
122   void OnAllowlistLoaded(
123       const std::string& id,
124       const scoped_refptr<SupervisedUserSiteList>& allowlist);
125 
126   PrefService* prefs_;
127   component_updater::SupervisedUserWhitelistInstaller* installer_;
128 
129   std::string client_id_;
130   std::vector<SiteListsChangedCallback> site_lists_changed_callbacks_;
131 
132   // The set of registered allowlists. A allowlist might be registered but not
133   // loaded yet, in which case it will not be in |loaded_allowlists_| yet.
134   // On the other hand, every loaded allowlist has to be registered.
135   std::set<std::string> registered_allowlists_;
136   std::map<std::string, scoped_refptr<SupervisedUserSiteList>>
137       loaded_allowlists_;
138 
139   base::WeakPtrFactory<SupervisedUserAllowlistService> weak_ptr_factory_{this};
140 
141   DISALLOW_COPY_AND_ASSIGN(SupervisedUserAllowlistService);
142 };
143 
144 #endif  // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_ALLOWLIST_SERVICE_H_
145