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

Side by Side Diff: services/authentication/accounts_db_manager.cc

Issue 1466733002: Google OAuth Device Flow support for FNL (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Rebased to master Created 4 years, 9 months 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
OLDNEW
(Empty)
1 // Copyright 2016 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 "services/authentication/accounts_db_manager.h"
6
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "base/strings/string_tokenizer.h"
11 #include "mojo/public/cpp/bindings/array.h"
12 #include "mojo/public/cpp/bindings/type_converter.h"
13 #include "mojo/services/files/interfaces/files.mojom.h"
14 #include "services/authentication/authentication_impl_db.mojom.h"
15 #include "services/authentication/credentials_impl_db.mojom.h"
16
17 namespace authentication {
18
19 char kAccountsDbFileName[] = "creds_db";
20 char kAuthDbFileName[] = "auth_db";
21 const uint32 kAuthDbVersion = 1;
22 const uint32 kCredsDbVersion = 1;
23
24 AccountsDbManager::AccountsDbManager(const mojo::files::DirectoryPtr directory)
25 : creds_db_file_(nullptr), auth_db_file_(nullptr) {
26 // Initialize in-memory contents from existing DB file
27 directory->OpenFile(
28 kAccountsDbFileName, GetProxy(&creds_db_file_),
29 mojo::files::kOpenFlagCreate | mojo::files::kOpenFlagRead |
30 mojo::files::kOpenFlagWrite,
31 [this](mojo::files::Error error) {
32 if (mojo::files::Error::OK != error) {
33 LOG(ERROR) << "Open() error on credentials db:" << error;
34 error_ = CREDENTIALS_DB_READ_ERROR;
35 return;
36 }
37 });
38 directory->OpenFile(kAuthDbFileName, GetProxy(&auth_db_file_),
39 mojo::files::kOpenFlagCreate |
40 mojo::files::kOpenFlagRead |
41 mojo::files::kOpenFlagWrite,
42 [this](mojo::files::Error error) {
43 if (mojo::files::Error::OK != error) {
44 LOG(ERROR) << "Open() error on auth db:" << error;
45 error_ = AUTHORIZATIONS_DB_READ_ERROR;
46 return;
47 }
48 });
49
50 Initialize();
51 }
52
53 AccountsDbManager::~AccountsDbManager() {}
54
55 bool AccountsDbManager::Validate() {
56 return error_ == NONE;
57 }
58
59 authentication::CredentialsPtr AccountsDbManager::GetCredentials(
60 const mojo::String& username) {
61 ensureCredentialsDbInit();
62
63 authentication::CredentialsPtr creds = authentication::Credentials::New();
64 if (username.is_null()) {
65 return creds.Pass();
66 }
67
68 auto it = creds_store_.credentials.find(username);
69 if (it != creds_store_.credentials.end()) {
70 creds->token = it.GetValue()->token;
71 creds->auth_provider = it.GetValue()->auth_provider;
72 creds->scopes = it.GetValue()->scopes;
73 creds->credential_type = it.GetValue()->credential_type;
74 }
75 return creds.Pass();
76 }
77
78 mojo::Array<mojo::String> AccountsDbManager::GetAllUsers() {
79 ensureCredentialsDbInit();
80
81 mojo::Array<mojo::String> users =
82 mojo::Array<mojo::String>::New(creds_store_.credentials.size());
83 size_t i = 0;
84
85 for (auto it = creds_store_.credentials.begin();
86 it != creds_store_.credentials.end(); it++) {
87 users[i++] = it.GetKey().get();
88 }
89
90 return users.Pass();
91 }
92
93 void AccountsDbManager::UpdateCredentials(
94 const mojo::String& username,
95 const authentication::CredentialsPtr creds) {
96 ensureCredentialsDbInit();
97
98 if (username.is_null()) {
99 return;
100 }
101
102 // Update contents cache with new data
103 creds_store_.credentials[username] = authentication::Credentials::New();
104 creds_store_.credentials[username]->token = creds->token;
105 creds_store_.credentials[username]->auth_provider = creds->auth_provider;
106 creds_store_.credentials[username]->scopes = creds->scopes;
107 creds_store_.credentials[username]->credential_type = creds->credential_type;
108
109 size_t buf_size = creds_store_.GetSerializedSize();
110 auto bytes_to_write = mojo::Array<uint8_t>::New(buf_size);
111 MOJO_CHECK(creds_store_.Serialize(&bytes_to_write.front(), buf_size));
112
113 mojo::files::Whence whence;
114 whence = mojo::files::Whence::FROM_START;
115 creds_db_file_->Write(
116 bytes_to_write.Pass(), 0, whence,
117 [this](mojo::files::Error error, uint32_t num_bytes_written) {
118 this->OnCredentialsFileWriteResponse(error, num_bytes_written);
119 });
120 }
121
122 void AccountsDbManager::OnCredentialsFileWriteResponse(
123 const mojo::files::Error error,
124 const uint32_t num_bytes_written) {
125 if (mojo::files::Error::OK != error) {
126 LOG(ERROR) << "Write() error on accounts db:" << error;
127 error_ = CREDENTIALS_DB_WRITE_ERROR;
qsr 2016/03/18 10:52:22 Maybe CHECK or DCHECK or error at the start of eve
ukode 2016/03/18 18:25:23 Done.
128 return;
129 }
130 }
131
132 void AccountsDbManager::ensureCredentialsDbInit() {
133 if ((db_init_option_ & CREDENTIALS_DB_INIT_SUCCESS) !=
134 CREDENTIALS_DB_INIT_SUCCESS) {
135 CHECK(creds_db_file_.WaitForIncomingResponse());
136 }
137 }
138
139 void AccountsDbManager::ensureAuthorizationsDbInit() {
140 if ((db_init_option_ & AUTHORIZATIONS_DB_INIT_SUCCESS) !=
141 AUTHORIZATIONS_DB_INIT_SUCCESS) {
142 CHECK(auth_db_file_.WaitForIncomingResponse());
143 }
144 }
145
146 void AccountsDbManager::Initialize() {
147 const size_t kMaxReadSize = 1 * 1024 * 1024;
148 mojo::Array<uint8_t> cred_bytes_read;
149 creds_db_file_->Read(
150 kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
151 [this](mojo::files::Error error, mojo::Array<uint8_t> cred_bytes_read) {
152 this->OnCredentialsFileReadResponse(error, cred_bytes_read.Pass());
153 });
154
155 mojo::Array<uint8_t> auth_bytes_read;
156 auth_db_file_->Read(
157 kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
158 [this](mojo::files::Error error, mojo::Array<uint8_t> auth_bytes_read) {
159 this->OnAuthorizationsFileReadResponse(error, auth_bytes_read.Pass());
160 });
161 }
162
163 void AccountsDbManager::OnCredentialsFileReadResponse(
164 const mojo::files::Error error,
165 const mojo::Array<uint8_t> bytes_read) {
166 if (error != mojo::files::Error::OK) {
167 LOG(ERROR) << "Read() error on accounts db: " << error;
168 error_ = CREDENTIALS_DB_READ_ERROR;
169 return;
170 }
171
172 if (bytes_read.size() != 0) {
173 // Deserialize data from file
174 const char* data = reinterpret_cast<const char*>(&bytes_read[0]);
175
176 // Validate the file contents before deserializing
177 mojo::internal::BoundsChecker bounds_checker(data, bytes_read.size(), 0);
178 std::string error;
179 mojo::internal::ValidationError verror =
180 internal::CredentialStore_Data::Validate(data, &bounds_checker, &error);
181 if (verror != mojo::internal::ValidationError::NONE) {
182 LOG(ERROR) << "Validation() error on accounts db ["
183 << ValidationErrorToString(verror) << "][" << error << "]";
184 error_ = CREDENTIALS_DB_VALIDATE_ERROR;
185 return;
186 }
187
188 creds_store_.Deserialize((void*)data);
189 // When we have multiple versions, this is not a fatal error, but a sign
190 // that we need to update (or reinitialize) the db.
191 CHECK_EQ(creds_store_.version, kCredsDbVersion);
192 } else {
193 creds_store_.version = kCredsDbVersion;
194 }
195
196 db_init_option_ |= CREDENTIALS_DB_INIT_SUCCESS;
197 }
198
199 void AccountsDbManager::OnAuthorizationsFileReadResponse(
200 const mojo::files::Error error,
201 const mojo::Array<uint8_t> bytes_read) {
202 if (error != mojo::files::Error::OK) {
203 LOG(ERROR) << "Read() error on auth db: " << error;
204 error_ = AUTHORIZATIONS_DB_READ_ERROR;
205 return;
206 }
207
208 if (bytes_read.size() != 0) {
209 // Deserialize data from file
210 const char* data = reinterpret_cast<const char*>(&bytes_read[0]);
211
212 // Validate the file contents before deserializing
213 mojo::internal::BoundsChecker bounds_checker(data, bytes_read.size(), 0);
214 if (internal::Db_Data::Validate(data, &bounds_checker, nullptr) !=
215 mojo::internal::ValidationError::NONE) {
216 LOG(ERROR) << "Validation() error on auth db.";
217 error_ = AUTHORIZATIONS_DB_VALIDATE_ERROR;
218 return;
219 }
220
221 auth_grants_.Deserialize((void*)data);
222 // When we have multiple versions, this is not a fatal error, but a sign
223 // that we need to update (or reinitialize) the db.
224 CHECK_EQ(auth_grants_.version, kAuthDbVersion);
225 } else {
226 auth_grants_.version = kAuthDbVersion;
227 }
228
229 db_init_option_ |= AUTHORIZATIONS_DB_INIT_SUCCESS;
230 }
231
232 mojo::String AccountsDbManager::GetAuthorizedUserForApp(mojo::String app_url) {
233 ensureAuthorizationsDbInit();
234
235 if (app_url.is_null()) {
236 return nullptr;
237 }
238 auto it = auth_grants_.last_selected_accounts.find(app_url);
239 if (it == auth_grants_.last_selected_accounts.end()) {
240 return nullptr;
241 }
242 return mojo::String(it.GetValue());
243 }
244
245 void AccountsDbManager::UpdateAuthorization(mojo::String app_url,
246 mojo::String username) {
247 ensureAuthorizationsDbInit();
248
249 if (app_url.is_null() || username.is_null()) {
250 return;
251 }
252 auth_grants_.last_selected_accounts[app_url] = username;
253
254 size_t buf_size = auth_grants_.GetSerializedSize();
255 auto bytes_to_write = mojo::Array<uint8_t>::New(buf_size);
256 MOJO_CHECK(auth_grants_.Serialize(&bytes_to_write.front(), buf_size));
257
258 mojo::files::Whence whence;
259 whence = mojo::files::Whence::FROM_START;
260 auth_db_file_->Write(
261 bytes_to_write.Pass(), 0, whence,
262 [this](mojo::files::Error error, uint32_t num_bytes_written) {
263 this->OnAuthorizationsFileWriteResponse(error, num_bytes_written);
264 });
265 }
266
267 void AccountsDbManager::OnAuthorizationsFileWriteResponse(
268 const mojo::files::Error error,
269 const uint32_t num_bytes_written) {
270 if (mojo::files::Error::OK != error) {
271 LOG(ERROR) << "Write() error on auth db:" << error;
272 error_ = AUTHORIZATIONS_DB_WRITE_ERROR;
273 return;
274 }
275 }
276
277 } // namespace authentication
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698