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