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