device_local_account.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
1// Copyright (c) 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 "chrome/browser/chromeos/policy/device_local_account.h" 6 7#include <set> 8 9#include "base/logging.h" 10#include "base/memory/scoped_ptr.h" 11#include "base/strings/string_number_conversions.h" 12#include "base/strings/string_util.h" 13#include "base/values.h" 14#include "chrome/browser/chromeos/settings/cros_settings.h" 15#include "chrome/browser/chromeos/settings/cros_settings_names.h" 16#include "google_apis/gaia/gaia_auth_util.h" 17 18namespace policy { 19 20namespace { 21 22const char kPublicAccountDomainPrefix[] = "public-accounts"; 23const char kKioskAppAccountDomainPrefix[] = "kiosk-apps"; 24const char kDeviceLocalAccountDomainSuffix[] = ".device-local.localhost"; 25 26} // namespace 27 28DeviceLocalAccount::DeviceLocalAccount(Type type, 29 const std::string& account_id, 30 const std::string& kiosk_app_id) 31 : type(type), 32 account_id(account_id), 33 user_id(GenerateDeviceLocalAccountUserId(account_id, type)), 34 kiosk_app_id(kiosk_app_id) { 35} 36 37DeviceLocalAccount::~DeviceLocalAccount() { 38} 39 40std::string GenerateDeviceLocalAccountUserId(const std::string& account_id, 41 DeviceLocalAccount::Type type) { 42 std::string domain_prefix; 43 switch (type) { 44 case DeviceLocalAccount::TYPE_PUBLIC_SESSION: 45 domain_prefix = kPublicAccountDomainPrefix; 46 break; 47 case DeviceLocalAccount::TYPE_KIOSK_APP: 48 domain_prefix = kKioskAppAccountDomainPrefix; 49 break; 50 case DeviceLocalAccount::TYPE_COUNT: 51 NOTREACHED(); 52 break; 53 } 54 return gaia::CanonicalizeEmail( 55 base::HexEncode(account_id.c_str(), account_id.size()) + "@" + 56 domain_prefix + kDeviceLocalAccountDomainSuffix); 57} 58 59bool IsDeviceLocalAccountUser(const std::string& user_id) { 60 return EndsWith(gaia::ExtractDomainName(user_id), 61 kDeviceLocalAccountDomainSuffix, 62 true); 63} 64 65bool IsKioskAppUser(const std::string& user_id) { 66 return gaia::ExtractDomainName(user_id) == 67 std::string(kKioskAppAccountDomainPrefix) + 68 kDeviceLocalAccountDomainSuffix; 69} 70 71void SetDeviceLocalAccounts( 72 chromeos::CrosSettings* cros_settings, 73 const std::vector<DeviceLocalAccount>& accounts) { 74 base::ListValue list; 75 for (std::vector<DeviceLocalAccount>::const_iterator it = accounts.begin(); 76 it != accounts.end(); ++it) { 77 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); 78 entry->SetStringWithoutPathExpansion( 79 chromeos::kAccountsPrefDeviceLocalAccountsKeyId, 80 it->account_id); 81 entry->SetIntegerWithoutPathExpansion( 82 chromeos::kAccountsPrefDeviceLocalAccountsKeyType, 83 it->type); 84 if (it->type == DeviceLocalAccount::TYPE_KIOSK_APP) { 85 entry->SetStringWithoutPathExpansion( 86 chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 87 it->kiosk_app_id); 88 } 89 list.Append(entry.release()); 90 } 91 92 cros_settings->Set(chromeos::kAccountsPrefDeviceLocalAccounts, list); 93} 94 95std::vector<DeviceLocalAccount> GetDeviceLocalAccounts( 96 chromeos::CrosSettings* cros_settings) { 97 std::vector<DeviceLocalAccount> accounts; 98 99 const base::ListValue* list = NULL; 100 cros_settings->GetList(chromeos::kAccountsPrefDeviceLocalAccounts, &list); 101 if (!list) 102 return accounts; 103 104 std::set<std::string> account_ids; 105 for (size_t i = 0; i < list->GetSize(); ++i) { 106 const base::DictionaryValue* entry = NULL; 107 if (!list->GetDictionary(i, &entry)) { 108 LOG(ERROR) << "Corrupt entry in device-local account list at index " << i 109 << "."; 110 continue; 111 } 112 113 std::string account_id; 114 if (!entry->GetStringWithoutPathExpansion( 115 chromeos::kAccountsPrefDeviceLocalAccountsKeyId, &account_id) || 116 account_id.empty()) { 117 LOG(ERROR) << "Missing account ID in device-local account list at index " 118 << i << "."; 119 continue; 120 } 121 122 int type; 123 if (!entry->GetIntegerWithoutPathExpansion( 124 chromeos::kAccountsPrefDeviceLocalAccountsKeyType, &type) || 125 type < 0 || type >= DeviceLocalAccount::TYPE_COUNT) { 126 LOG(ERROR) << "Missing or invalid account type in device-local account " 127 << "list at index " << i << "."; 128 continue; 129 } 130 131 std::string kiosk_app_id; 132 if (type == DeviceLocalAccount::TYPE_KIOSK_APP) { 133 if (!entry->GetStringWithoutPathExpansion( 134 chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 135 &kiosk_app_id)) { 136 LOG(ERROR) << "Missing app ID in device-local account entry at index " 137 << i << "."; 138 continue; 139 } 140 } 141 142 if (!account_ids.insert(account_id).second) { 143 LOG(ERROR) << "Duplicate entry in device-local account list at index " 144 << i << ": " << account_id << "."; 145 continue; 146 } 147 148 accounts.push_back(DeviceLocalAccount( 149 static_cast<DeviceLocalAccount::Type>(type), account_id, kiosk_app_id)); 150 } 151 return accounts; 152} 153 154} // namespace policy 155