1 // Copyright 2014 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/user_manager/user.h"
6
7 #include <stddef.h>
8
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "base/metrics/histogram_macros.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "components/account_id/account_id.h"
17 #include "components/user_manager/known_user.h"
18 #include "components/user_manager/user_manager.h"
19 #include "google_apis/gaia/gaia_auth_util.h"
20
21 namespace user_manager {
22
23 namespace {
24
25 // Must be in sync with histogram enum UserTypeChanged in enums.xml.
26 // The values must never be changed (only new ones can be added) as they
27 // are stored in UMA logs.
28 enum class UserTypeChangeHistogram {
29 UNKNOWN_FATAL = 0,
30 REGULAR_TO_CHILD = 1,
31 CHILD_TO_REGULAR = 2,
32 COUNT, // Not a value, just a count of other values.
33 };
UMAUserTypeChanged(const UserTypeChangeHistogram value)34 void UMAUserTypeChanged(const UserTypeChangeHistogram value) {
35 UMA_HISTOGRAM_ENUMERATION("UserManager.UserTypeChanged", value,
36 UserTypeChangeHistogram::COUNT);
37 }
38
39 // Returns account name portion of an email.
GetUserName(const std::string & email)40 std::string GetUserName(const std::string& email) {
41 std::string::size_type i = email.find('@');
42 if (i == 0 || i == std::string::npos) {
43 return email;
44 }
45 return email.substr(0, i);
46 }
47
48 } // namespace
49
50 // static
TypeHasGaiaAccount(UserType user_type)51 bool User::TypeHasGaiaAccount(UserType user_type) {
52 return user_type == USER_TYPE_REGULAR ||
53 user_type == USER_TYPE_CHILD;
54 }
55
56 // Also used for regular supervised users.
57 class RegularUser : public User {
58 public:
59 RegularUser(const AccountId& account_id, const UserType user_type);
60 ~RegularUser() override;
61
62 // Overridden from User:
63 UserType GetType() const override;
64 void UpdateType(UserType user_type) override;
65 bool CanSyncImage() const override;
66
67 private:
68 bool is_child_;
69
70 DISALLOW_COPY_AND_ASSIGN(RegularUser);
71 };
72
73 class ActiveDirectoryUser : public RegularUser {
74 public:
75 explicit ActiveDirectoryUser(const AccountId& account_id);
76 ~ActiveDirectoryUser() override;
77 // Overridden from User:
78 UserType GetType() const override;
79 bool CanSyncImage() const override;
80 };
81
82 class GuestUser : public User {
83 public:
84 explicit GuestUser(const AccountId& guest_account_id);
85 ~GuestUser() override;
86
87 // Overridden from User:
88 UserType GetType() const override;
89
90 private:
91 DISALLOW_COPY_AND_ASSIGN(GuestUser);
92 };
93
94 class DeviceLocalAccountUserBase : public User {
95 public:
96 // User:
97 bool IsAffiliated() const override;
98
99 protected:
100 explicit DeviceLocalAccountUserBase(const AccountId& account_id);
101 ~DeviceLocalAccountUserBase() override;
102 // User:
103 void SetAffiliation(bool) override;
104 bool IsDeviceLocalAccount() const override;
105
106 private:
107 DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountUserBase);
108 };
109
110 class KioskAppUser : public DeviceLocalAccountUserBase {
111 public:
112 explicit KioskAppUser(const AccountId& kiosk_app_account_id);
113 ~KioskAppUser() override;
114
115 // Overridden from User:
116 UserType GetType() const override;
117
118 private:
119 DISALLOW_COPY_AND_ASSIGN(KioskAppUser);
120 };
121
122 class ArcKioskAppUser : public DeviceLocalAccountUserBase {
123 public:
124 explicit ArcKioskAppUser(const AccountId& arc_kiosk_account_id);
125 ~ArcKioskAppUser() override;
126
127 // Overridden from User:
128 UserType GetType() const override;
129
130 private:
131 DISALLOW_COPY_AND_ASSIGN(ArcKioskAppUser);
132 };
133
134 class WebKioskAppUser : public DeviceLocalAccountUserBase {
135 public:
136 explicit WebKioskAppUser(const AccountId& web_kiosk_account_id);
137 ~WebKioskAppUser() override;
138
139 // Overridden from User:
140 UserType GetType() const override;
141
142 private:
143 DISALLOW_COPY_AND_ASSIGN(WebKioskAppUser);
144 };
145
146 class SupervisedUser : public User {
147 public:
148 explicit SupervisedUser(const AccountId& account_id);
149 ~SupervisedUser() override;
150
151 // Overridden from User:
152 UserType GetType() const override;
153 std::string display_email() const override;
154
155 private:
156 DISALLOW_COPY_AND_ASSIGN(SupervisedUser);
157 };
158
159 class PublicAccountUser : public DeviceLocalAccountUserBase {
160 public:
161 explicit PublicAccountUser(const AccountId& account_id);
162 ~PublicAccountUser() override;
163
164 // Overridden from User:
165 UserType GetType() const override;
166
167 private:
168 DISALLOW_COPY_AND_ASSIGN(PublicAccountUser);
169 };
170
User(const AccountId & account_id)171 User::User(const AccountId& account_id)
172 : account_id_(account_id), user_image_(new UserImage) {}
173
~User()174 User::~User() {}
175
GetDisplayEmail() const176 std::string User::GetDisplayEmail() const {
177 return display_email();
178 }
179
GetDisplayName() const180 base::string16 User::GetDisplayName() const {
181 // Fallback to the email account name in case display name haven't been set.
182 return display_name_.empty() ? base::UTF8ToUTF16(GetAccountName(true))
183 : display_name_;
184 }
185
GetGivenName() const186 base::string16 User::GetGivenName() const {
187 return given_name_;
188 }
189
GetImage() const190 const gfx::ImageSkia& User::GetImage() const {
191 return user_image_->image();
192 }
193
GetAccountId() const194 const AccountId& User::GetAccountId() const {
195 return account_id_;
196 }
197
UpdateType(UserType user_type)198 void User::UpdateType(UserType user_type) {
199 UMAUserTypeChanged(UserTypeChangeHistogram::UNKNOWN_FATAL);
200 LOG(FATAL) << "Unsupported user type change " << GetType() << "=>"
201 << user_type;
202 }
203
HasGaiaAccount() const204 bool User::HasGaiaAccount() const {
205 return TypeHasGaiaAccount(GetType());
206 }
207
IsActiveDirectoryUser() const208 bool User::IsActiveDirectoryUser() const {
209 return GetType() == user_manager::USER_TYPE_ACTIVE_DIRECTORY;
210 }
211
IsSupervised() const212 bool User::IsSupervised() const {
213 UserType type = GetType();
214 return type == USER_TYPE_SUPERVISED ||
215 type == USER_TYPE_CHILD;
216 }
217
IsChild() const218 bool User::IsChild() const {
219 return GetType() == USER_TYPE_CHILD;
220 }
221
GetAccountName(bool use_display_email) const222 std::string User::GetAccountName(bool use_display_email) const {
223 if (use_display_email && !display_email_.empty())
224 return GetUserName(display_email_);
225 else
226 return GetUserName(account_id_.GetUserEmail());
227 }
228
HasDefaultImage() const229 bool User::HasDefaultImage() const {
230 return UserManager::Get()->IsValidDefaultUserImageId(image_index_);
231 }
232
CanSyncImage() const233 bool User::CanSyncImage() const {
234 return false;
235 }
236
display_email() const237 std::string User::display_email() const {
238 return display_email_;
239 }
240
can_lock() const241 bool User::can_lock() const {
242 return can_lock_;
243 }
244
username_hash() const245 std::string User::username_hash() const {
246 return username_hash_;
247 }
248
is_logged_in() const249 bool User::is_logged_in() const {
250 return is_logged_in_;
251 }
252
is_active() const253 bool User::is_active() const {
254 return is_active_;
255 }
256
has_gaia_account() const257 bool User::has_gaia_account() const {
258 static_assert(user_manager::NUM_USER_TYPES == 10,
259 "NUM_USER_TYPES should equal 10");
260 switch (GetType()) {
261 case user_manager::USER_TYPE_REGULAR:
262 case user_manager::USER_TYPE_CHILD:
263 return true;
264 case user_manager::USER_TYPE_GUEST:
265 case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
266 case user_manager::USER_TYPE_SUPERVISED:
267 case user_manager::USER_TYPE_KIOSK_APP:
268 case user_manager::USER_TYPE_ARC_KIOSK_APP:
269 case user_manager::USER_TYPE_ACTIVE_DIRECTORY:
270 case user_manager::USER_TYPE_WEB_KIOSK_APP:
271 return false;
272 default:
273 NOTREACHED();
274 }
275 return false;
276 }
277
AddProfileCreatedObserver(base::OnceClosure on_profile_created)278 void User::AddProfileCreatedObserver(base::OnceClosure on_profile_created) {
279 if (profile_is_created_)
280 std::move(on_profile_created).Run();
281 else
282 on_profile_created_observers_.push_back(std::move(on_profile_created));
283 }
284
IsAffiliated() const285 bool User::IsAffiliated() const {
286 return is_affiliated_;
287 }
288
SetProfileIsCreated()289 void User::SetProfileIsCreated() {
290 profile_is_created_ = true;
291 for (auto& callback : on_profile_created_observers_)
292 std::move(callback).Run();
293 on_profile_created_observers_.clear();
294 }
295
SetAffiliation(bool is_affiliated)296 void User::SetAffiliation(bool is_affiliated) {
297 is_affiliated_ = is_affiliated;
298 }
299
IsDeviceLocalAccount() const300 bool User::IsDeviceLocalAccount() const {
301 return false;
302 }
303
IsKioskType() const304 bool User::IsKioskType() const {
305 UserType type = GetType();
306 return type == USER_TYPE_KIOSK_APP || type == USER_TYPE_ARC_KIOSK_APP ||
307 type == USER_TYPE_WEB_KIOSK_APP;
308 }
309
CreateRegularUser(const AccountId & account_id,const UserType user_type)310 User* User::CreateRegularUser(const AccountId& account_id,
311 const UserType user_type) {
312 if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY)
313 return new ActiveDirectoryUser(account_id);
314 return new RegularUser(account_id, user_type);
315 }
316
CreateGuestUser(const AccountId & guest_account_id)317 User* User::CreateGuestUser(const AccountId& guest_account_id) {
318 return new GuestUser(guest_account_id);
319 }
320
CreateKioskAppUser(const AccountId & kiosk_app_account_id)321 User* User::CreateKioskAppUser(const AccountId& kiosk_app_account_id) {
322 return new KioskAppUser(kiosk_app_account_id);
323 }
324
CreateArcKioskAppUser(const AccountId & arc_kiosk_account_id)325 User* User::CreateArcKioskAppUser(const AccountId& arc_kiosk_account_id) {
326 return new ArcKioskAppUser(arc_kiosk_account_id);
327 }
328
CreateWebKioskAppUser(const AccountId & web_kiosk_account_id)329 User* User::CreateWebKioskAppUser(const AccountId& web_kiosk_account_id) {
330 return new WebKioskAppUser(web_kiosk_account_id);
331 }
332
CreateSupervisedUser(const AccountId & account_id)333 User* User::CreateSupervisedUser(const AccountId& account_id) {
334 return new SupervisedUser(account_id);
335 }
336
CreatePublicAccountUser(const AccountId & account_id,bool is_using_saml)337 User* User::CreatePublicAccountUser(const AccountId& account_id,
338 bool is_using_saml) {
339 User* user = new PublicAccountUser(account_id);
340 user->set_using_saml(is_using_saml);
341 return user;
342 }
343
SetAccountLocale(const std::string & resolved_account_locale)344 void User::SetAccountLocale(const std::string& resolved_account_locale) {
345 account_locale_.reset(new std::string(resolved_account_locale));
346 }
347
SetImage(std::unique_ptr<UserImage> user_image,int image_index)348 void User::SetImage(std::unique_ptr<UserImage> user_image, int image_index) {
349 user_image_ = std::move(user_image);
350 image_index_ = image_index;
351 image_is_stub_ = false;
352 image_is_loading_ = false;
353 DCHECK(HasDefaultImage() || user_image_->has_image_bytes());
354 }
355
SetImageURL(const GURL & image_url)356 void User::SetImageURL(const GURL& image_url) {
357 user_image_->set_url(image_url);
358 }
359
SetStubImage(std::unique_ptr<UserImage> stub_user_image,int image_index,bool is_loading)360 void User::SetStubImage(std::unique_ptr<UserImage> stub_user_image,
361 int image_index,
362 bool is_loading) {
363 user_image_ = std::move(stub_user_image);
364 image_index_ = image_index;
365 image_is_stub_ = true;
366 image_is_loading_ = is_loading;
367 }
368
GetType() const369 UserType ActiveDirectoryUser::GetType() const {
370 return user_manager::USER_TYPE_ACTIVE_DIRECTORY;
371 }
372
CanSyncImage() const373 bool ActiveDirectoryUser::CanSyncImage() const {
374 return false;
375 }
376
RegularUser(const AccountId & account_id,const UserType user_type)377 RegularUser::RegularUser(const AccountId& account_id, const UserType user_type)
378 : User(account_id), is_child_(user_type == USER_TYPE_CHILD) {
379 if (user_type != USER_TYPE_CHILD && user_type != USER_TYPE_REGULAR &&
380 user_type != USER_TYPE_ACTIVE_DIRECTORY) {
381 LOG(FATAL) << "Invalid user type " << user_type;
382 }
383
384 set_can_lock(true);
385 set_display_email(account_id.GetUserEmail());
386 }
387
ActiveDirectoryUser(const AccountId & account_id)388 ActiveDirectoryUser::ActiveDirectoryUser(const AccountId& account_id)
389 : RegularUser(account_id, user_manager::USER_TYPE_ACTIVE_DIRECTORY) {}
390
~RegularUser()391 RegularUser::~RegularUser() {
392 }
393
~ActiveDirectoryUser()394 ActiveDirectoryUser::~ActiveDirectoryUser() {}
395
GetType() const396 UserType RegularUser::GetType() const {
397 return is_child_ ? user_manager::USER_TYPE_CHILD :
398 user_manager::USER_TYPE_REGULAR;
399 }
400
UpdateType(UserType user_type)401 void RegularUser::UpdateType(UserType user_type) {
402 const UserType current_type = GetType();
403 // Can only change between regular and child.
404 if ((user_type == user_manager::USER_TYPE_CHILD ||
405 user_type == user_manager::USER_TYPE_REGULAR) &&
406 (current_type == user_manager::USER_TYPE_CHILD ||
407 current_type == user_manager::USER_TYPE_REGULAR)) {
408 // We want all the other type changes to crash, that is why this check is
409 // not at the top level.
410 if (user_type == current_type)
411 return;
412 const bool old_is_child = is_child_;
413 is_child_ = user_type == user_manager::USER_TYPE_CHILD;
414
415 // Clear information about profile policy requirements to enforce setting it
416 // again for the new account type.
417 user_manager::known_user::ClearProfileRequiresPolicy(GetAccountId());
418
419 LOG(WARNING) << "User type has changed: " << current_type
420 << " (is_child=" << old_is_child << ") => " << user_type
421 << " (is_child=" << is_child_ << ")";
422 UMAUserTypeChanged(is_child_ ? UserTypeChangeHistogram::REGULAR_TO_CHILD
423 : UserTypeChangeHistogram::CHILD_TO_REGULAR);
424 return;
425 }
426 // Fail with LOG(FATAL).
427 User::UpdateType(user_type);
428 }
429
CanSyncImage() const430 bool RegularUser::CanSyncImage() const {
431 return true;
432 }
433
GuestUser(const AccountId & guest_account_id)434 GuestUser::GuestUser(const AccountId& guest_account_id)
435 : User(guest_account_id) {
436 set_display_email(std::string());
437 }
438
~GuestUser()439 GuestUser::~GuestUser() {
440 }
441
GetType() const442 UserType GuestUser::GetType() const {
443 return user_manager::USER_TYPE_GUEST;
444 }
445
DeviceLocalAccountUserBase(const AccountId & account_id)446 DeviceLocalAccountUserBase::DeviceLocalAccountUserBase(
447 const AccountId& account_id) : User(account_id) {
448 }
449
~DeviceLocalAccountUserBase()450 DeviceLocalAccountUserBase::~DeviceLocalAccountUserBase() {
451 }
452
IsAffiliated() const453 bool DeviceLocalAccountUserBase::IsAffiliated() const {
454 return true;
455 }
456
SetAffiliation(bool)457 void DeviceLocalAccountUserBase::SetAffiliation(bool) {
458 // Device local accounts are always affiliated. No affiliation modification
459 // must happen.
460 NOTREACHED();
461 }
462
IsDeviceLocalAccount() const463 bool DeviceLocalAccountUserBase::IsDeviceLocalAccount() const {
464 return true;
465 }
466
KioskAppUser(const AccountId & kiosk_app_account_id)467 KioskAppUser::KioskAppUser(const AccountId& kiosk_app_account_id)
468 : DeviceLocalAccountUserBase(kiosk_app_account_id) {
469 set_display_email(kiosk_app_account_id.GetUserEmail());
470 }
471
~KioskAppUser()472 KioskAppUser::~KioskAppUser() {
473 }
474
GetType() const475 UserType KioskAppUser::GetType() const {
476 return user_manager::USER_TYPE_KIOSK_APP;
477 }
478
ArcKioskAppUser(const AccountId & arc_kiosk_account_id)479 ArcKioskAppUser::ArcKioskAppUser(const AccountId& arc_kiosk_account_id)
480 : DeviceLocalAccountUserBase(arc_kiosk_account_id) {
481 set_display_email(arc_kiosk_account_id.GetUserEmail());
482 }
483
~ArcKioskAppUser()484 ArcKioskAppUser::~ArcKioskAppUser() {
485 }
486
GetType() const487 UserType ArcKioskAppUser::GetType() const {
488 return user_manager::USER_TYPE_ARC_KIOSK_APP;
489 }
490
WebKioskAppUser(const AccountId & web_kiosk_account_id)491 WebKioskAppUser::WebKioskAppUser(const AccountId& web_kiosk_account_id)
492 : DeviceLocalAccountUserBase(web_kiosk_account_id) {
493 set_display_email(web_kiosk_account_id.GetUserEmail());
494 }
495
~WebKioskAppUser()496 WebKioskAppUser::~WebKioskAppUser() {}
497
GetType() const498 UserType WebKioskAppUser::GetType() const {
499 return user_manager::USER_TYPE_WEB_KIOSK_APP;
500 }
501
SupervisedUser(const AccountId & account_id)502 SupervisedUser::SupervisedUser(const AccountId& account_id) : User(account_id) {
503 set_can_lock(true);
504 }
505
~SupervisedUser()506 SupervisedUser::~SupervisedUser() {
507 }
508
GetType() const509 UserType SupervisedUser::GetType() const {
510 return user_manager::USER_TYPE_SUPERVISED;
511 }
512
display_email() const513 std::string SupervisedUser::display_email() const {
514 return base::UTF16ToUTF8(display_name());
515 }
516
PublicAccountUser(const AccountId & account_id)517 PublicAccountUser::PublicAccountUser(const AccountId& account_id)
518 : DeviceLocalAccountUserBase(account_id) {
519 // Public accounts do not have a real email address, so they do not set
520 // |display_email_|.
521 }
522
~PublicAccountUser()523 PublicAccountUser::~PublicAccountUser() {
524 }
525
GetType() const526 UserType PublicAccountUser::GetType() const {
527 return user_manager::USER_TYPE_PUBLIC_ACCOUNT;
528 }
529
530 } // namespace user_manager
531