policy_header_service.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2013 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#include "components/policy/core/common/cloud/policy_header_service.h"
6
7#include "base/base64.h"
8#include "base/json/json_writer.h"
9#include "base/values.h"
10#include "components/policy/core/common/cloud/cloud_policy_store.h"
11#include "components/policy/core/common/cloud/policy_header_io_helper.h"
12
13namespace {
14const char kUserDMTokenKey[] = "user_dmtoken";
15const char kUserPolicyTokenKey[] = "user_policy_token";
16const char kVerificationKeyHashKey[] = "verification_key_id";
17}
18
19namespace policy {
20
21PolicyHeaderService::PolicyHeaderService(
22    const std::string& server_url,
23    const std::string& verification_key_hash,
24    CloudPolicyStore* user_policy_store,
25    CloudPolicyStore* device_policy_store)
26    : server_url_(server_url),
27      verification_key_hash_(verification_key_hash),
28      user_policy_store_(user_policy_store),
29      device_policy_store_(device_policy_store) {
30  user_policy_store_->AddObserver(this);
31  if (device_policy_store_)
32    device_policy_store_->AddObserver(this);
33}
34
35PolicyHeaderService::~PolicyHeaderService() {
36  user_policy_store_->RemoveObserver(this);
37  if (device_policy_store_)
38    device_policy_store_->RemoveObserver(this);
39}
40
41scoped_ptr<PolicyHeaderIOHelper>
42PolicyHeaderService::CreatePolicyHeaderIOHelper(
43    scoped_refptr<base::SequencedTaskRunner> task_runner) {
44  std::string initial_header_value = CreateHeaderValue();
45  scoped_ptr<PolicyHeaderIOHelper> helper = make_scoped_ptr(
46      new PolicyHeaderIOHelper(server_url_, initial_header_value, task_runner));
47  helpers_.push_back(helper.get());
48  return helper.Pass();
49}
50
51std::string PolicyHeaderService::CreateHeaderValue() {
52  // If we have no user policy or no token, return an empty header.
53  if (!user_policy_store_->has_policy() ||
54      !user_policy_store_->policy()->has_request_token()) {
55    return "";
56  }
57
58  // Generate a Base64-encoded header of the form:
59  // {
60  //   user_dmtoken: <dm_token>
61  //   user_policy_token: <policy_token>
62  //   verification_key_hash: <key_hash>
63  // }
64  std::string user_dm_token = user_policy_store_->policy()->request_token();
65  base::DictionaryValue value;
66  value.SetString(kUserDMTokenKey, user_dm_token);
67  if (user_policy_store_->policy()->has_policy_token()) {
68    value.SetString(kUserPolicyTokenKey,
69                    user_policy_store_->policy()->policy_token());
70  }
71  if (!verification_key_hash_.empty())
72    value.SetString(kVerificationKeyHashKey, verification_key_hash_);
73
74  // TODO(atwilson): add user_policy_token once the server starts sending it
75  // down (http://crbug.com/326799).
76  std::string json;
77  base::JSONWriter::Write(&value, &json);
78  DCHECK(!json.empty());
79
80  // Base64-encode the result so we can include it in a header.
81  std::string encoded;
82  base::Base64Encode(json, &encoded);
83  return encoded;
84}
85
86void PolicyHeaderService::OnStoreLoaded(CloudPolicyStore* store) {
87  // If we have a PolicyHeaderIOHelper, notify it of the new header value.
88  if (!helpers_.empty()) {
89    std::string new_header = CreateHeaderValue();
90    for (std::vector<PolicyHeaderIOHelper*>::const_iterator it =
91             helpers_.begin(); it != helpers_.end(); ++it) {
92      (*it)->UpdateHeader(new_header);
93    }
94  }
95}
96
97void PolicyHeaderService::OnStoreError(CloudPolicyStore* store) {
98  // Do nothing on errors.
99}
100
101}  // namespace policy
102