Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: components/signin/core/account_id/account_id.cc

Issue 2529103002: Add account_type into AccountId (Closed)
Patch Set: more tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/signin/core/account_id/account_id.h ('k') | components/user_manager/known_user.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/signin/core/account_id/account_id.h" 5 #include "components/signin/core/account_id/account_id.h"
6 6
7 #include <functional> 7 #include <functional>
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
12 #include "base/memory/singleton.h" 12 #include "base/memory/singleton.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "google_apis/gaia/gaia_auth_util.h" 15 #include "google_apis/gaia/gaia_auth_util.h"
16 16
17 namespace { 17 namespace {
18 18
19 // Known account types.
20 const char kGoogle[] = "google";
21
22 // Serialization keys 19 // Serialization keys
23 const char kGaiaIdKey[] = "gaia_id"; 20 const char kGaiaIdKey[] = "gaia_id";
24 const char kEmailKey[] = "email"; 21 const char kEmailKey[] = "email";
22 const char kObjGuid[] = "obj_guid";
23 const char kAccountTypeKey[] = "account_type";
24
25 // Serialization values for account type.
26 const std::string kGoogle = "google";
27 const std::string kAd = "ad";
25 28
26 // Prefix for GetAccountIdKey(). 29 // Prefix for GetAccountIdKey().
27 const char kKeyGaiaIdPrefix[] = "g-"; 30 const char kKeyGaiaIdPrefix[] = "g-";
28 31 const char kKeyAdIdPrefix[] = "a-";
29 struct GoogleStringSingleton {
30 GoogleStringSingleton() : google(kGoogle) {}
31
32 static GoogleStringSingleton* GetInstance() {
33 return base::Singleton<GoogleStringSingleton>::get();
34 }
35
36 const std::string google;
37 };
38 32
39 } // anonymous namespace 33 } // anonymous namespace
40 34
41 struct AccountId::EmptyAccountId { 35 struct AccountId::EmptyAccountId {
42 EmptyAccountId() : user_id() {} 36 EmptyAccountId() : user_id() {}
43 const AccountId user_id; 37 const AccountId user_id;
44 38
45 static EmptyAccountId* GetInstance() { 39 static EmptyAccountId* GetInstance() {
46 return base::Singleton<EmptyAccountId>::get(); 40 return base::Singleton<EmptyAccountId>::get();
47 } 41 }
48 }; 42 };
49 43
50 AccountId::AccountId() {} 44 AccountId::AccountId() {}
51 45
52 AccountId::AccountId(const std::string& gaia_id, const std::string& user_email) 46 AccountId::AccountId(const std::string& id,
53 : gaia_id_(gaia_id), user_email_(user_email) { 47 const std::string& user_email,
48 const AccountType& account_type)
49 : id_(id), user_email_(user_email), account_type_(account_type) {
50 DCHECK(account_type != AccountType::UNKNOWN || id.empty());
51 DCHECK(account_type != AccountType::ACTIVE_DIRECTORY || !id.empty());
54 // Fail if e-mail looks similar to GaiaIdKey. 52 // Fail if e-mail looks similar to GaiaIdKey.
55 LOG_ASSERT(!base::StartsWith(user_email, kKeyGaiaIdPrefix, 53 LOG_ASSERT(account_type != AccountType::GOOGLE ||
54 !base::StartsWith(user_email, kKeyGaiaIdPrefix,
56 base::CompareCase::SENSITIVE) || 55 base::CompareCase::SENSITIVE) ||
57 user_email.find('@') != std::string::npos) 56 user_email.find('@') != std::string::npos)
58 << "Bad e-mail: '" << user_email << "' with gaia_id='" << gaia_id << "'"; 57 << "Bad e-mail: '" << user_email << "' with gaia_id='" << id << "'";
59 58
60 // TODO(alemate): DCHECK(!email.empty()); 59 // TODO(alemate): DCHECK(!email.empty());
61 // TODO(alemate): check gaia_id is not empty once it is required. 60 // TODO(alemate): check gaia_id is not empty once it is required.
62 } 61 }
63 62
64 AccountId::AccountId(const AccountId& other) 63 AccountId::AccountId(const AccountId& other)
65 : gaia_id_(other.gaia_id_), user_email_(other.user_email_) {} 64 : id_(other.id_),
65 user_email_(other.user_email_),
66 account_type_(other.account_type_) {}
66 67
67 bool AccountId::operator==(const AccountId& other) const { 68 bool AccountId::operator==(const AccountId& other) const {
68 return (this == &other) || 69 if (this == &other)
69 (gaia_id_ == other.gaia_id_ && user_email_ == other.user_email_) || 70 return true;
70 (!gaia_id_.empty() && gaia_id_ == other.gaia_id_) || 71 if (account_type_ == AccountType::UNKNOWN ||
Andrew T Wilson (Slow) 2016/12/15 19:03:24 This behavior is complex enough you really need to
Roman Sorokin (ftl) 2016/12/21 17:15:21 Done.
71 (!user_email_.empty() && user_email_ == other.user_email_); 72 other.account_type_ == AccountType::UNKNOWN)
73 return user_email_ == other.user_email_;
74 if (account_type_ != other.account_type_)
75 return false;
76 switch (account_type_) {
77 case AccountType::GOOGLE:
78 return (id_ == other.id_ && user_email_ == other.user_email_) ||
79 (!id_.empty() && id_ == other.id_) ||
80 (!user_email_.empty() && user_email_ == other.user_email_);
81 case AccountType::ACTIVE_DIRECTORY:
82 return id_ == other.id_ && user_email_ == other.user_email_;
83 default:
84 NOTREACHED() << "Unknown account type";
85 }
86 return false;
72 } 87 }
73 88
74 bool AccountId::operator!=(const AccountId& other) const { 89 bool AccountId::operator!=(const AccountId& other) const {
75 return !operator==(other); 90 return !operator==(other);
76 } 91 }
77 92
78 bool AccountId::operator<(const AccountId& right) const { 93 bool AccountId::operator<(const AccountId& right) const {
79 // TODO(alemate): update this once all AccountId members are filled. 94 // TODO(alemate): update this once all AccountId members are filled.
80 return user_email_ < right.user_email_; 95 return user_email_ < right.user_email_;
81 } 96 }
82 97
83 bool AccountId::empty() const { 98 bool AccountId::empty() const {
84 return gaia_id_.empty() && user_email_.empty(); 99 return id_.empty() && user_email_.empty() &&
100 account_type_ == AccountType::UNKNOWN;
85 } 101 }
86 102
87 bool AccountId::is_valid() const { 103 bool AccountId::is_valid() const {
88 return /* !gaia_id_.empty() && */ !user_email_.empty(); 104 switch (account_type_) {
105 case AccountType::GOOGLE:
106 return /* !id_.empty() && */ !user_email_.empty();
107 case AccountType::ACTIVE_DIRECTORY:
108 return !id_.empty() && !user_email_.empty();
109 case AccountType::UNKNOWN:
110 return id_.empty() && !user_email_.empty();
111 }
112 NOTREACHED();
113 return false;
89 } 114 }
90 115
91 void AccountId::clear() { 116 void AccountId::clear() {
92 gaia_id_.clear(); 117 id_.clear();
93 user_email_.clear(); 118 user_email_.clear();
119 account_type_ = AccountType::UNKNOWN;
94 } 120 }
95 121
96 const std::string& AccountId::GetAccountType() const { 122 AccountType AccountId::GetAccountType() const {
97 return GoogleStringSingleton::GetInstance()->google; 123 return account_type_;
98 } 124 }
99 125
100 const std::string& AccountId::GetGaiaId() const { 126 const std::string& AccountId::GetGaiaId() const {
101 return gaia_id_; 127 if (account_type_ != AccountType::GOOGLE)
128 NOTIMPLEMENTED() << "Failed to get gaia_id for non-Google account.";
129 return id_;
130 }
131
132 const std::string& AccountId::GetObjGuid() const {
133 if (account_type_ != AccountType::ACTIVE_DIRECTORY)
134 NOTIMPLEMENTED()
135 << "Failed to get obj_guid for non-Active Directory account.";
136 return id_;
102 } 137 }
103 138
104 const std::string& AccountId::GetUserEmail() const { 139 const std::string& AccountId::GetUserEmail() const {
105 return user_email_; 140 return user_email_;
106 } 141 }
107 142
143 bool AccountId::HasAccountIdKey() const {
144 return account_type_ != AccountType::UNKNOWN && !id_.empty();
145 }
146
108 const std::string AccountId::GetAccountIdKey() const { 147 const std::string AccountId::GetAccountIdKey() const {
109 #ifdef NDEBUG 148 #ifdef NDEBUG
110 if (gaia_id_.empty()) 149 if (id_.empty())
111 LOG(FATAL) << "GetAccountIdKey(): no gaia id for " << Serialize(); 150 LOG(FATAL) << "GetAccountIdKey(): no id for " << Serialize();
112
113 #else 151 #else
114 CHECK(!gaia_id_.empty()); 152 CHECK(!id_.empty());
115 #endif 153 #endif
116 154 switch (GetAccountType()) {
117 return std::string(kKeyGaiaIdPrefix) + gaia_id_; 155 case AccountType::GOOGLE:
118 } 156 return std::string(kKeyGaiaIdPrefix) + id_;
119 157 case AccountType::ACTIVE_DIRECTORY:
120 void AccountId::SetGaiaId(const std::string& gaia_id) { 158 return std::string(kKeyAdIdPrefix) + id_;
121 DCHECK(!gaia_id.empty()); 159 default:
122 gaia_id_ = gaia_id; 160 NOTREACHED() << "Unknown account type";
161 }
162 return std::string();
123 } 163 }
124 164
125 void AccountId::SetUserEmail(const std::string& email) { 165 void AccountId::SetUserEmail(const std::string& email) {
126 DCHECK(!email.empty()); 166 DCHECK(!email.empty());
127 user_email_ = email; 167 user_email_ = email;
128 } 168 }
129 169
130 // static 170 // static
131 AccountId AccountId::FromUserEmail(const std::string& email) { 171 AccountId AccountId::FromUserEmail(const std::string& email) {
132 // TODO(alemate): DCHECK(!email.empty()); 172 // TODO(alemate): DCHECK(!email.empty());
133 return AccountId(std::string() /* gaia_id */, email); 173 return AccountId(std::string() /* id */, email, AccountType::UNKNOWN);
134 } 174 }
135 175
176 // static
136 AccountId AccountId::FromGaiaId(const std::string& gaia_id) { 177 AccountId AccountId::FromGaiaId(const std::string& gaia_id) {
137 DCHECK(!gaia_id.empty()); 178 DCHECK(!gaia_id.empty());
138 return AccountId(gaia_id, std::string() /* email */); 179 return AccountId(gaia_id, std::string() /* email */, AccountType::GOOGLE);
139 } 180 }
140 181
141 // static 182 // static
142 AccountId AccountId::FromUserEmailGaiaId(const std::string& email, 183 AccountId AccountId::FromUserEmailGaiaId(const std::string& email,
143 const std::string& gaia_id) { 184 const std::string& gaia_id) {
144 DCHECK(!(email.empty() && gaia_id.empty())); 185 DCHECK(!(email.empty() && gaia_id.empty()));
145 return AccountId(gaia_id, email); 186 return AccountId(gaia_id, email, AccountType::GOOGLE);
187 }
188
189 // static
190 AccountId AccountId::AdFromUserEmailObjGuid(const std::string& email,
191 const std::string& obj_guid) {
192 DCHECK(!email.empty() && !obj_guid.empty());
193 return AccountId(obj_guid, email, AccountType::ACTIVE_DIRECTORY);
194 }
195
196 // static
197 AccountId AccountId::AdFromObjGuid(const std::string& obj_guid) {
198 DCHECK(!obj_guid.empty());
199 return AccountId(obj_guid, std::string() /* email */,
200 AccountType::ACTIVE_DIRECTORY);
201 }
202
203 // static
204 AccountType AccountId::StringToAccountType(
205 const std::string& account_type_string) {
206 if (account_type_string == kGoogle)
207 return AccountType::GOOGLE;
208 if (account_type_string == kAd)
209 return AccountType::ACTIVE_DIRECTORY;
210 NOTREACHED() << "Unknown account type " << account_type_string;
211 return AccountType::UNKNOWN;
212 }
213
214 // static
215 std::string AccountId::AccountTypeToString(const AccountType& account_type) {
216 switch (account_type) {
217 case AccountType::GOOGLE:
218 return kGoogle;
219 case AccountType::ACTIVE_DIRECTORY:
220 return kAd;
221 default:
222 NOTREACHED() << "Unknown account type";
223 }
224 return std::string();
146 } 225 }
147 226
148 std::string AccountId::Serialize() const { 227 std::string AccountId::Serialize() const {
149 base::DictionaryValue value; 228 base::DictionaryValue value;
150 value.SetString(kGaiaIdKey, gaia_id_); 229 switch (GetAccountType()) {
230 case AccountType::UNKNOWN:
231 case AccountType::GOOGLE:
232 value.SetString(kGaiaIdKey, id_);
233 value.SetString(kAccountTypeKey,
234 AccountTypeToString(AccountType::GOOGLE));
235 break;
236 case AccountType::ACTIVE_DIRECTORY:
237 value.SetString(kObjGuid, id_);
238 value.SetString(kAccountTypeKey, AccountTypeToString(GetAccountType()));
239 break;
240 }
151 value.SetString(kEmailKey, user_email_); 241 value.SetString(kEmailKey, user_email_);
152 242
153 std::string serialized; 243 std::string serialized;
154 base::JSONWriter::Write(value, &serialized); 244 base::JSONWriter::Write(value, &serialized);
155 return serialized; 245 return serialized;
156 } 246 }
157 247
158 // static 248 // static
159 bool AccountId::Deserialize(const std::string& serialized, 249 bool AccountId::Deserialize(const std::string& serialized,
160 AccountId* account_id) { 250 AccountId* account_id) {
161 base::JSONReader reader; 251 base::JSONReader reader;
162 std::unique_ptr<const base::Value> value(reader.Read(serialized)); 252 std::unique_ptr<const base::Value> value(reader.Read(serialized));
163 const base::DictionaryValue* dictionary_value = NULL; 253 const base::DictionaryValue* dictionary_value = NULL;
164 254
165 if (!value || !value->GetAsDictionary(&dictionary_value)) 255 if (!value || !value->GetAsDictionary(&dictionary_value))
166 return false; 256 return false;
167 257
168 std::string gaia_id; 258 std::string gaia_id;
169 std::string user_email; 259 std::string user_email;
260 std::string obj_guid;
261 std::string account_type_string;
262 AccountType account_type = AccountType::GOOGLE;
170 263
171 const bool found_gaia_id = dictionary_value->GetString(kGaiaIdKey, &gaia_id); 264 const bool found_gaia_id = dictionary_value->GetString(kGaiaIdKey, &gaia_id);
172 const bool found_user_email = 265 const bool found_user_email =
173 dictionary_value->GetString(kEmailKey, &user_email); 266 dictionary_value->GetString(kEmailKey, &user_email);
267 const bool found_obj_guid = dictionary_value->GetString(kObjGuid, &obj_guid);
268 const bool found_account_type =
269 dictionary_value->GetString(kAccountTypeKey, &account_type_string);
270 if (found_account_type)
271 account_type = StringToAccountType(account_type_string);
174 272
175 if (!found_gaia_id) 273 switch (account_type) {
176 LOG(ERROR) << "gaia_id is not found in '" << serialized << "'"; 274 case AccountType::GOOGLE:
275 if (found_obj_guid)
276 LOG(ERROR) << "AccountType is 'google' but obj_guid is found in '"
277 << serialized << "'";
177 278
178 if (!found_user_email) 279 if (!found_gaia_id)
179 LOG(ERROR) << "user_email is not found in '" << serialized << "'"; 280 LOG(ERROR) << "gaia_id is not found in '" << serialized << "'";
180 281
181 if (!found_gaia_id && !found_user_email) 282 if (!found_user_email)
182 return false; 283 LOG(ERROR) << "user_email is not found in '" << serialized << "'";
183 284
184 *account_id = FromUserEmailGaiaId(user_email, gaia_id); 285 if (!found_gaia_id && !found_user_email)
286 return false;
185 287
186 return true; 288 *account_id = FromUserEmailGaiaId(user_email, gaia_id);
289 return true;
290
291 case AccountType::ACTIVE_DIRECTORY:
292 if (found_gaia_id)
293 LOG(ERROR)
294 << "AccountType is 'active directory' but gaia_id is found in '"
295 << serialized << "'";
296
297 if (!found_obj_guid) {
298 LOG(ERROR) << "obj_guid is not found in '" << serialized << "'";
299 return false;
300 }
301
302 if (!found_user_email) {
303 LOG(ERROR) << "user_email is not found in '" << serialized << "'";
304 }
305
306 if (!found_obj_guid || !found_user_email)
307 return false;
308
309 *account_id = AdFromUserEmailObjGuid(user_email, obj_guid);
310 return true;
311
312 default:
313 NOTREACHED() << "Unknown account type";
314 return false;
315 }
187 } 316 }
188 317
189 const AccountId& EmptyAccountId() { 318 const AccountId& EmptyAccountId() {
190 return AccountId::EmptyAccountId::GetInstance()->user_id; 319 return AccountId::EmptyAccountId::GetInstance()->user_id;
191 } 320 }
192 321
193 namespace BASE_HASH_NAMESPACE { 322 namespace BASE_HASH_NAMESPACE {
194 323
195 std::size_t hash<AccountId>::operator()(const AccountId& user_id) const { 324 std::size_t hash<AccountId>::operator()(const AccountId& user_id) const {
196 return hash<std::string>()(user_id.GetUserEmail()); 325 return hash<std::string>()(user_id.GetUserEmail());
197 } 326 }
198 327
199 } // namespace BASE_HASH_NAMESPACE 328 } // namespace BASE_HASH_NAMESPACE
OLDNEW
« no previous file with comments | « components/signin/core/account_id/account_id.h ('k') | components/user_manager/known_user.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698