1 // Copyright 2018 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_CHROMEOS_POLICY_COMPONENT_ACTIVE_DIRECTORY_POLICY_SERVICE_H_
6 #define CHROME_BROWSER_CHROMEOS_POLICY_COMPONENT_ACTIVE_DIRECTORY_POLICY_SERVICE_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/macros.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/sequence_checker.h"
16 #include "chrome/browser/chromeos/policy/component_active_directory_policy_retriever.h"
17 #include "components/policy/core/common/policy_namespace.h"
18 #include "components/policy/core/common/policy_types.h"
19 #include "components/policy/core/common/schema_registry.h"
20 
21 namespace policy {
22 
23 class PolicyBundle;
24 
25 // Manages Active Directory policy for components (currently used for policy for
26 // extensions)
27 class ComponentActiveDirectoryPolicyService : public SchemaRegistry::Observer {
28  public:
29   class Delegate {
30    public:
31     virtual ~Delegate();
32 
33     virtual void OnComponentActiveDirectoryPolicyUpdated() = 0;
34   };
35 
36   // |scope| specifies whether the component policy is fetched along with user
37   // or device policy.
38   //
39   // |domain| specifies the domain for which policy is loaded. Must be
40   // POLICY_DOMAIN_EXTENSIONS or POLICY_DOMAIN_SIGNIN_EXTENSIONS.
41   //
42   // |account_type| and |account_id| specify the Session Manager store from
43   // which policy is retrieved. |account_id| must be the user's cryptohome id
44   // for ACCOUNT_TYPE_USER and empty for ACCOUNT_TYPE_DEVICE. Not suppored yet
45   // are ACCOUNT_TYPE_SESSIONLESS_USER and ACCOUNT_TYPE_DEVICE_LOCAL_ACCOUNT.
46   //
47   // Usually, |scope|, |domain|, |account_type| and |account_id| are coupled:
48   // For user-level policy, use:
49   //   POLICY_SCOPE_USER,
50   //   POLICY_DOMAIN_EXTENSIONS,
51   //   ACCOUNT_TYPE_USER,
52   //   <user's cryptohome id>
53   // For device-level policy, use:
54   //   POLICY_SCOPE_DEVICE
55   //   POLICY_DOMAIN_SIGNIN_EXTENSIONS
56   //   ACCOUNT_TYPE_DEVICE
57   //   <empty string>
58   //
59   // |delegate| is the object that gets notified when new policy is available.
60   //
61   // |schema_registry| contains the schemas used to validate extension policy.
62   ComponentActiveDirectoryPolicyService(
63       PolicyScope scope,
64       PolicyDomain domain,
65       login_manager::PolicyAccountType account_type,
66       const std::string& account_id,
67       Delegate* delegate,
68       SchemaRegistry* schema_registry);
69   ~ComponentActiveDirectoryPolicyService() override;
70 
71   // Retrieves policies from Session Manager, validates schemas and signals
72   // OnComponentActiveDirectoryPolicyUpdated() in the |delegate_|. Does not
73   // cancel in-flight retrieval request, but schedules a new retrieval request
74   // when the current one finishes.
75   void RetrievePolicies();
76 
77   // Returns the current policies for components or nullptr if the policies have
78   // not been loaded yet.
policy()79   PolicyBundle* policy() const { return policy_.get(); }
80 
81  private:
82   // SchemaRegistry::Observer implementation:
83   void OnSchemaRegistryReady() override;
84   void OnSchemaRegistryUpdated(bool has_new_schemas) override;
85 
86   // Called when the schema registry changed.
87   void UpdateFromSchemaRegistry();
88 
89   // Called when policies have been retrieved from SessionManager. Parses the
90   // JSON policy strings and calls FilterAndInstallPolicy().
91   void OnPolicyRetrieved(
92       std::vector<ComponentActiveDirectoryPolicyRetriever::RetrieveResult>
93           results);
94 
95   // Does a schema validation of |policy| using |current_schema_map_|, then
96   // sends the policy off to |delegate_|, where it's installed.
97   void FilterAndInstallPolicy(std::unique_ptr<PolicyBundle> policy);
98 
99   // Constructor parameters.
100   const PolicyScope scope_;
101   const PolicyDomain domain_;
102   const login_manager::PolicyAccountType account_type_;
103   const std::string account_id_;
104   Delegate* const delegate_;
105   SchemaRegistry* const schema_registry_;
106 
107   // Schema map from the |schema_registry_|. Set as soon as the registry is
108   // ready.
109   scoped_refptr<SchemaMap> current_schema_map_;
110 
111   // Contains component policy for all namespaces in |domain_| that have a
112   // registered schema. Set by RefreshPolicies() if the schema registry is
113   // ready.
114   std::unique_ptr<PolicyBundle> policy_;
115 
116   // Tracks policy retrieval requests to Session Manager.
117   std::unique_ptr<ComponentActiveDirectoryPolicyRetriever> policy_retriever_;
118 
119   // If RetrievePolicies() is called while a requests is in-flight, the request
120   // is deferred until the current one finishes. This flag keeps track of that.
121   bool should_retrieve_again_ = false;
122 
123   SEQUENCE_CHECKER(sequence_checker_);
124 
125   base::WeakPtrFactory<ComponentActiveDirectoryPolicyService> weak_ptr_factory_{
126       this};
127   DISALLOW_COPY_AND_ASSIGN(ComponentActiveDirectoryPolicyService);
128 };
129 
130 }  // namespace policy
131 
132 #endif  // CHROME_BROWSER_CHROMEOS_POLICY_COMPONENT_ACTIVE_DIRECTORY_POLICY_SERVICE_H_
133