1// Copyright (c) 2011 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_POLICY_DEVICE_TOKEN_FETCHER_H_
6#define CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_
7#pragma once
8
9#include <string>
10
11#include "base/memory/scoped_ptr.h"
12#include "base/observer_list.h"
13#include "base/task.h"
14#include "chrome/browser/policy/device_management_backend.h"
15#include "chrome/browser/policy/policy_notifier.h"
16#include "chrome/browser/policy/proto/device_management_backend.pb.h"
17
18namespace policy {
19
20class CloudPolicyCacheBase;
21class DeviceManagementService;
22
23namespace em = enterprise_management;
24
25// Fetches the device token that can be used for policy requests with the device
26// management server, either from disk if it already has been successfully
27// requested, otherwise from the device management server. An instance of the
28// fetcher is shared as a singleton by all users of the device management token
29// to ensure they all get the same token.
30class DeviceTokenFetcher
31    : public DeviceManagementBackend::DeviceRegisterResponseDelegate {
32 public:
33  class Observer {
34   public:
35    virtual ~Observer() {}
36    virtual void OnDeviceTokenAvailable() = 0;
37  };
38
39  // |service| is used to talk to the device management service and |cache| is
40  // used to persist whether the device is unmanaged.
41  DeviceTokenFetcher(DeviceManagementService* service,
42                     CloudPolicyCacheBase* cache,
43                     PolicyNotifier* notifier);
44  // Version for tests that allows to set timing parameters.
45  DeviceTokenFetcher(DeviceManagementService* service,
46                     CloudPolicyCacheBase* cache,
47                     PolicyNotifier* notifier,
48                     int64 token_fetch_error_delay_ms,
49                     int64 token_fetch_error_max_delay_ms,
50                     int64 unmanaged_device_refresh_rate_ms);
51  virtual ~DeviceTokenFetcher();
52
53  // Starts fetching a token.
54  // Declared virtual so it can be overridden by mocks.
55  virtual void FetchToken(const std::string& auth_token,
56                          const std::string& device_id,
57                          em::DeviceRegisterRequest_Type policy_type,
58                          const std::string& machine_id,
59                          const std::string& machine_model);
60
61  virtual void SetUnmanagedState();
62
63  // Returns the device management token or the empty string if not available.
64  // Declared virtual so it can be overridden by mocks.
65  virtual const std::string& GetDeviceToken();
66
67  // Disables the auto-retry-on-error behavior of this token fetcher.
68  void StopAutoRetry();
69
70  void AddObserver(Observer* observer);
71  void RemoveObserver(Observer* observer);
72
73  // DeviceManagementBackend::DeviceRegisterResponseDelegate method overrides:
74  virtual void HandleRegisterResponse(
75      const em::DeviceRegisterResponse& response);
76  virtual void OnError(DeviceManagementBackend::ErrorCode code);
77
78 private:
79  friend class DeviceTokenFetcherTest;
80
81  // The different states that the fetcher can be in during the process of
82  // getting the device token. |state_| is initialized to INACTIVE, depending
83  // on the result of a token fetching attempt can transition to either of
84  // TOKEN_AVAILABLE, UNMANAGED, or ERROR. The first attempt must be triggered
85  // externally. When |state_| is UNMANAGED, a new fetching attempt is
86  // performed every |unmanaged_device_refresh_rate_ms_|; when it's ERROR,
87  // a new attempt is done after |effective_token_fetch_error_delay_ms_|.
88  enum FetcherState {
89    // Fetcher inactive.
90    STATE_INACTIVE,
91    // Token available.
92    STATE_TOKEN_AVAILABLE,
93    // Device unmanaged.
94    STATE_UNMANAGED,
95    // Error, retry later.
96    STATE_ERROR,
97    // Temporary error. Retry sooner.
98    STATE_TEMPORARY_ERROR,
99    // Server rejected the auth token.
100    STATE_BAD_AUTH
101  };
102
103  // Common initialization helper.
104  void Initialize(DeviceManagementService* service,
105                  CloudPolicyCacheBase* cache,
106                  PolicyNotifier* notifier,
107                  int64 token_fetch_error_delay_ms,
108                  int64 token_fetch_error_max_delay_ms,
109                  int64 unmanaged_device_refresh_rate_ms);
110
111  // Moves the fetcher into a new state.
112  void SetState(FetcherState state);
113
114  // Resets |backend_|, then uses |auth_token_| and |device_id_| to perform
115  // an actual token fetch.
116  void FetchTokenInternal();
117
118  // Called back from the |retry_task_|.
119  void ExecuteRetryTask();
120
121  // Cancels the |retry_task_|.
122  void CancelRetryTask();
123
124  // Service and backend. A new backend is created whenever the fetcher gets
125  // reset.
126  DeviceManagementService* service_;  // weak
127  scoped_ptr<DeviceManagementBackend> backend_;
128
129  // Reference to the cache. Used to persist and read unmanaged state.
130  CloudPolicyCacheBase* cache_;
131
132  PolicyNotifier* notifier_;
133
134  // Refresh parameters.
135  int64 token_fetch_error_delay_ms_;
136  int64 token_fetch_error_max_delay_ms_;
137  int64 effective_token_fetch_error_delay_ms_;
138  int64 unmanaged_device_refresh_rate_ms_;
139
140  // State the fetcher is currently in.
141  FetcherState state_;
142
143  // Current device token.
144  std::string device_token_;
145
146  // Contains the AuthToken for the device management server.
147  std::string auth_token_;
148  // Device identifier to send to the server.
149  std::string device_id_;
150  // Contains policy type to send to the server.
151  em::DeviceRegisterRequest_Type policy_type_;
152  // Contains physical machine id to send to the server.
153  std::string machine_id_;
154  // Contains physical machine model to send to server.
155  std::string machine_model_;
156
157  // Task that has been scheduled to retry fetching a token.
158  CancelableTask* retry_task_;
159
160  ScopedRunnableMethodFactory<DeviceTokenFetcher> method_factory_;
161
162  ObserverList<Observer, true> observer_list_;
163};
164
165}  // namespace policy
166
167#endif  // CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_
168