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 13 namespace { 14 const char kUserDMTokenKey[] = "user_dmtoken"; 15 const char kUserPolicyTokenKey[] = "user_policy_token"; 16 const char kVerificationKeyHashKey[] = "verification_key_id"; 17 } 18 19 namespace policy { 20 21 PolicyHeaderService::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 35 PolicyHeaderService::~PolicyHeaderService() { 36 user_policy_store_->RemoveObserver(this); 37 if (device_policy_store_) 38 device_policy_store_->RemoveObserver(this); 39 } 40 41 scoped_ptr<PolicyHeaderIOHelper> 42 PolicyHeaderService::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 51 std::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 86 void 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 97 void PolicyHeaderService::OnStoreError(CloudPolicyStore* store) { 98 // Do nothing on errors. 99 } 100 101 std::vector<PolicyHeaderIOHelper*> PolicyHeaderService::GetHelpersForTest() { 102 return helpers_; 103 } 104 105 } // namespace policy 106