summaryrefslogtreecommitdiffstats
path: root/chrome/browser/policy/device_token_fetcher.h
blob: 0501433ed5885b9eea26a1d639f649dec239d88b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_
#define CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_
#pragma once

#include <string>

#include "base/observer_list.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
#include "chrome/browser/policy/device_management_backend.h"

namespace policy {

class CloudPolicyCache;
class DeviceManagementService;

namespace em = enterprise_management;

// Fetches the device token that can be used for policy requests with the device
// management server, either from disk if it already has been successfully
// requested, otherwise from the device management server. An instance of the
// fetcher is shared as a singleton by all users of the device management token
// to ensure they all get the same token.
class DeviceTokenFetcher
    : public DeviceManagementBackend::DeviceRegisterResponseDelegate {
 public:
  class Observer {
   public:
    virtual ~Observer() {}
    virtual void OnDeviceTokenAvailable() = 0;
  };

  // |service| is used to talk to the device management service and |cache| is
  // used to persist whether the device is unmanaged.
  DeviceTokenFetcher(DeviceManagementService* service,
                     CloudPolicyCache* cache);
  // Version for tests that allows to set timing paramters.
  DeviceTokenFetcher(DeviceManagementService* service,
                     CloudPolicyCache* cache,
                     int64 token_fetch_error_delay_ms,
                     int64 unmanaged_device_refresh_rate_ms);
  virtual ~DeviceTokenFetcher();

  // Starts fetching a token.
  // Declared virtual so it can be overridden by mocks.
  virtual void FetchToken(const std::string& auth_token,
                          const std::string& device_id);

  // Returns the device management token or the empty string if not available.
  // Declared virtual so it can be overridden by mocks.
  virtual const std::string& GetDeviceToken();

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // DeviceManagementBackend::DeviceRegisterResponseDelegate method overrides:
  virtual void HandleRegisterResponse(
      const em::DeviceRegisterResponse& response);
  virtual void OnError(DeviceManagementBackend::ErrorCode code);

 private:
  friend class DeviceTokenFetcherTest;

  // The different states that the fetcher can be in during the process of
  // getting the device token. |state_| is initialized to INACTIVE, depending
  // on the result of a token fetching attempt can transition to either of
  // TOKEN_AVAILABLE, UNMANAGED, or ERROR. The first attempt must be triggered
  // externally. When |state_| is UNMANAGED, a new fetching attempt is
  // performed every |unmanaged_device_refresh_rate_ms_|; when it's ERROR,
  // a new attempt is done after |effective_token_fetch_error_delay_ms_|.
  enum FetcherState {
    // Fetcher inactive.
    STATE_INACTIVE,
    // Token available.
    STATE_TOKEN_AVAILABLE,
    // Device unmanaged.
    STATE_UNMANAGED,
    // Error, retry later.
    STATE_ERROR,
  };

  // Common initialization helper.
  void Initialize(DeviceManagementService* service,
                  CloudPolicyCache* cache,
                  int64 token_fetch_error_delay_ms,
                  int64 unmanaged_device_refresh_rate_ms);

  // Moves the fetcher into a new state.
  void SetState(FetcherState state);

  // Resets |backend_|, then uses |auth_token_| and |device_id_| to perform
  // an actual token fetch.
  void FetchTokenInternal();

  // Called back from the |retry_task_|.
  void ExecuteRetryTask();

  // Cancels the |retry_task_|.
  void CancelRetryTask();

  // Service and backend. A new backend is created whenever the fetcher gets
  // reset.
  DeviceManagementService* service_;  // weak
  scoped_ptr<DeviceManagementBackend> backend_;

  // Reference to the cache. Used to persist and read unmanaged state.
  CloudPolicyCache* cache_;

  // Refresh parameters.
  int64 token_fetch_error_delay_ms_;
  int64 effective_token_fetch_error_delay_ms_;
  int64 unmanaged_device_refresh_rate_ms_;

  // State the fetcher is currently in.
  FetcherState state_;

  // Current device token.
  std::string device_token_;

  // Contains the AuthToken for the device management server.
  std::string auth_token_;
  // Device identifier to send to the server.
  std::string device_id_;

  // Task that has been scheduled to retry fetching a token.
  CancelableTask* retry_task_;

  ScopedRunnableMethodFactory<DeviceTokenFetcher> method_factory_;

  ObserverList<Observer, true> observer_list_;
};

}  // namespace policy

#endif  // CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_