1 // Copyright 2015 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/login/users/affiliation.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/command_line.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/browser_process_platform_part.h"
12 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
13 #include "chrome/browser/chromeos/policy/device_local_account.h"
14 #include "chrome/browser/chromeos/settings/device_settings_service.h"
15 #include "components/account_id/account_id.h"
16 #include "components/policy/core/common/policy_switches.h"
17 #include "components/policy/proto/device_management_backend.pb.h"
18 #include "google_apis/gaia/gaia_auth_util.h"
19
20 namespace chromeos {
21
22 namespace {
23
GetDeviceDMTokenIfAffiliated(const AccountId & account_id,const std::vector<std::string> & user_affiliation_ids)24 std::string GetDeviceDMTokenIfAffiliated(
25 const AccountId& account_id,
26 const std::vector<std::string>& user_affiliation_ids) {
27 const AffiliationIDSet set_of_user_affiliation_ids(
28 user_affiliation_ids.begin(), user_affiliation_ids.end());
29 const policy::BrowserPolicyConnectorChromeOS* connector =
30 g_browser_process->platform_part()->browser_policy_connector_chromeos();
31 DCHECK(connector);
32 const bool is_affiliated = IsUserAffiliated(
33 set_of_user_affiliation_ids, connector->GetDeviceAffiliationIDs(),
34 account_id.GetUserEmail());
35 if (is_affiliated) {
36 const enterprise_management::PolicyData* policy_data =
37 DeviceSettingsService::Get()->policy_data();
38 CHECK(policy_data);
39 return policy_data->request_token();
40 }
41 return std::string();
42 }
43
44 } // namespace
45
HaveCommonElement(const std::set<std::string> & set1,const std::set<std::string> & set2)46 bool HaveCommonElement(const std::set<std::string>& set1,
47 const std::set<std::string>& set2) {
48 std::set<std::string>::const_iterator it1 = set1.begin();
49 std::set<std::string>::const_iterator it2 = set2.begin();
50
51 while (it1 != set1.end() && it2 != set2.end()) {
52 if (*it1 == *it2)
53 return true;
54 if (*it1 < *it2) {
55 ++it1;
56 } else {
57 ++it2;
58 }
59 }
60 return false;
61 }
62
IsUserAffiliated(const AffiliationIDSet & user_affiliation_ids,const AffiliationIDSet & device_affiliation_ids,const std::string & email)63 bool IsUserAffiliated(const AffiliationIDSet& user_affiliation_ids,
64 const AffiliationIDSet& device_affiliation_ids,
65 const std::string& email) {
66 // An empty username means incognito user in case of Chrome OS and no
67 // logged-in user in case of Chrome (SigninService). Many tests use nonsense
68 // email addresses (e.g. 'test') so treat those as non-enterprise users.
69 if (email.empty() || email.find('@') == std::string::npos) {
70 return false;
71 }
72
73 if (policy::IsDeviceLocalAccountUser(email, NULL)) {
74 return true;
75 }
76
77 // Not all test servers correctly support affiliation ids so far, so
78 // this is a work-around.
79 // TODO(antrim): remove this once all test servers support affiliation ids.
80 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
81 if (command_line->HasSwitch(policy::switches::kUserAlwaysAffiliated)) {
82 return true;
83 }
84
85 if (!device_affiliation_ids.empty() && !user_affiliation_ids.empty()) {
86 return HaveCommonElement(user_affiliation_ids, device_affiliation_ids);
87 }
88
89 return false;
90 }
91
92 base::RepeatingCallback<std::string(const std::vector<std::string>&)>
GetDeviceDMTokenForUserPolicyGetter(const AccountId & account_id)93 GetDeviceDMTokenForUserPolicyGetter(const AccountId& account_id) {
94 return base::BindRepeating(&GetDeviceDMTokenIfAffiliated, account_id);
95 }
96
97 } // namespace chromeos
98