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

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 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 "services/authentication/accounts_db_manager.h"
6
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/strings/string_tokenizer.h"
12 #include "mojo/public/cpp/bindings/array.h"
13 #include "mojo/public/cpp/bindings/type_converter.h"
14 #include "mojo/services/files/interfaces/files.mojom.h"
15 #include "services/authentication/authentication_impl_db.mojom.h"
16 #include "services/authentication/credentials_impl_db.mojom.h"
17
18 namespace authentication {
19
20 char kAccountsDbFileName[] = "creds_db";
21 char kAuthDbFileName[] = "auth_db";
22 const uint32 kAuthDbVersion = 1;
23 const uint32 kCredsDbVersion = 1;
24
25 AccountsDbManager::AccountsDbManager(const mojo::files::DirectoryPtr directory)
26 : creds_db_file_(nullptr), auth_db_file_(nullptr), weak_ptr_factory_(this) {
27 // Initialize in-memory contents from existing DB file
28 directory->OpenFile(
29 kAccountsDbFileName, GetProxy(&creds_db_file_),
30 mojo::files::kOpenFlagCreate | mojo::files::kOpenFlagRead |
31 mojo::files::kOpenFlagWrite,
32 [this](mojo::files::Error error) {
33 if (mojo::files::Error::OK != error) {
34 LOG(ERROR) << "Open() error on credentials db:" << error;
35 delete this;
36 return;
37 }
38 });
39 directory->OpenFile(kAuthDbFileName, GetProxy(&auth_db_file_),
40 mojo::files::kOpenFlagCreate |
41 mojo::files::kOpenFlagRead |
42 mojo::files::kOpenFlagWrite,
43 [this](mojo::files::Error error) {
44 if (mojo::files::Error::OK != error) {
45 LOG(ERROR) << "Open() error on auth db:" << error;
46 delete this;
47 return;
48 }
49 });
50 Initialize();
51 }
52
53 AccountsDbManager::~AccountsDbManager() {
54 weak_ptr_factory_.InvalidateWeakPtrs();
55 delete this;
56 }
57
58 base::WeakPtr<AccountsDbManager> AccountsDbManager::GetWeakPtr() {
59 return weak_ptr_factory_.GetWeakPtr();
60 }
61
62 authentication::CredentialsPtr AccountsDbManager::GetCredentials(
63 const mojo::String& username) {
64 ensureCredsDbInit();
65
66 authentication::CredentialsPtr creds = authentication::Credentials::New();
67 if (username.is_null()) {
68 return creds.Pass();
69 }
70
71 auto it = creds_store_.credentials.find(username);
72 if (it != creds_store_.credentials.end()) {
73 creds->token = it.GetValue()->token;
74 creds->auth_provider = it.GetValue()->auth_provider;
75 creds->scopes = it.GetValue()->scopes;
76 creds->credential_type = it.GetValue()->credential_type;
77 }
78 return creds.Pass();
79 }
80
81 mojo::Array<mojo::String> AccountsDbManager::GetAllUsers() {
82 ensureCredsDbInit();
83
84 mojo::Array<mojo::String> users =
85 mojo::Array<mojo::String>::New(creds_store_.credentials.size());
86 size_t i = 0;
87 for (auto it = creds_store_.credentials.begin();
88 it != creds_store_.credentials.end(); it++) {
qsr 2016/03/04 15:06:45 Why not use a for each loop? Doesn't it work on mo
ukode 2016/03/11 22:48:52 I get this error on using for each: indirection re
89 users[i++] = it.GetKey().get();
90 }
91 return users.Pass();
92 }
93
94 void AccountsDbManager::UpdateCredentials(
95 const mojo::String& username,
96 const authentication::CredentialsPtr creds) {
97 ensureCredsDbInit();
98
99 if (username.is_null()) {
100 return;
101 }
102
103 // Set the creds db version
104 if (!creds_store_.version) {
105 creds_store_.version = kCredsDbVersion;
qsr 2016/03/04 15:06:45 This should be done during init.
ukode 2016/03/11 22:48:51 Done.
106 }
107
108 // Update contents cache with new data
109 creds_store_.credentials[username] = authentication::Credentials::New();
110 creds_store_.credentials[username]->token = creds->token;
111 creds_store_.credentials[username]->auth_provider = creds->auth_provider;
112 creds_store_.credentials[username]->scopes = creds->scopes;
113 creds_store_.credentials[username]->credential_type = creds->credential_type;
114
115 size_t buf_size = creds_store_.GetSerializedSize();
116 char buf[buf_size];
117 MOJO_CHECK(creds_store_.Serialize(buf, buf_size));
118
119 std::vector<uint8_t> bytes_to_write(buf, buf + buf_size);
120 mojo::files::Whence whence;
121 whence = mojo::files::Whence::FROM_START;
122
123 creds_db_file_->Write(
124 mojo::Array<uint8_t>::From(bytes_to_write), 0, whence,
125 [this](mojo::files::Error error, uint32_t num_bytes_written) {
126 this->OnCredFileWriteResponse(error, num_bytes_written);
127 });
128 }
129
130 void AccountsDbManager::OnCredFileWriteResponse(
131 const mojo::files::Error error,
132 const uint32_t num_bytes_written) {
133 if (mojo::files::Error::OK != error) {
134 LOG(ERROR) << "Write() error on accounts db:" << error;
135 delete this;
136 return;
137 }
138 }
139
140 void AccountsDbManager::ensureCredsDbInit() {
141 if ((db_init_option_ & CREDS_DB_INIT_SUCCESS) != CREDS_DB_INIT_SUCCESS) {
142 CHECK(creds_db_file_.WaitForIncomingResponse());
143 }
144 }
145
146 void AccountsDbManager::ensureAuthDbInit() {
147 if ((db_init_option_ & AUTH_DB_INIT_SUCCESS) != AUTH_DB_INIT_SUCCESS) {
148 CHECK(auth_db_file_.WaitForIncomingResponse());
149 }
150 }
151
152 void AccountsDbManager::Initialize() {
153 auth_grants_.version = kAuthDbVersion;
qsr 2016/03/04 15:06:45 Why is this necessary? Shouldn't you do this when
ukode 2016/03/11 22:48:51 Done, moved it below inside file read operation.
154
155 const size_t kMaxReadSize = 1 * 1024 * 1024;
156 mojo::Array<uint8_t> cred_bytes_read;
157 creds_db_file_->Read(
158 kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
159 [this](mojo::files::Error error, mojo::Array<uint8_t> cred_bytes_read) {
160 this->OnCredFileReadResponse(error, cred_bytes_read.Pass());
161 });
162
163 mojo::Array<uint8_t> auth_bytes_read;
164 auth_db_file_->Read(
165 kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
166 [this](mojo::files::Error error, mojo::Array<uint8_t> auth_bytes_read) {
167 this->OnAuthFileReadResponse(error, auth_bytes_read.Pass());
168 });
169 }
170
171 void AccountsDbManager::OnCredFileReadResponse(
172 const mojo::files::Error error,
173 const mojo::Array<uint8_t> bytes_read) {
174 if (error != mojo::files::Error::OK) {
175 LOG(ERROR) << "Read() error on accounts db: " << error;
176 delete this;
177 return;
178 }
179
180 if (bytes_read.size() != 0) {
181 // Deserialize data from file
182 const char* data = reinterpret_cast<const char*>(&bytes_read[0]);
183 creds_store_.Deserialize((void*)data);
184 CHECK_EQ(creds_store_.version, kCredsDbVersion);
qsr 2016/03/04 15:06:45 Maybe put a comment that when we have multiple ver
ukode 2016/03/11 22:48:51 Acknowledged.
185 CHECK(creds_store_.credentials.size() > 0);
qsr 2016/03/04 15:06:45 Why do you have this check? Isn't it possible that
ukode 2016/03/11 22:48:52 Good catch. Yes, that's possible. Removed the chec
186 }
187
188 db_init_option_ |= CREDS_DB_INIT_SUCCESS;
189 }
190
191 void AccountsDbManager::OnAuthFileReadResponse(
192 const mojo::files::Error error,
193 const mojo::Array<uint8_t> bytes_read) {
194 if (error != mojo::files::Error::OK) {
195 LOG(ERROR) << "Read() error on auth db: " << error;
196 delete this;
197 return;
198 }
199
200 if (bytes_read.size() != 0) {
201 // Deserialize data from file
202 const char* data = reinterpret_cast<const char*>(&bytes_read[0]);
203 auth_grants_.Deserialize((void*)data);
qsr 2016/03/04 15:06:45 You want to use Validate before calling Deserializ
ukode 2016/03/11 22:48:52 Done.
204 CHECK_EQ(auth_grants_.version, kAuthDbVersion);
205 CHECK(!auth_grants_.last_selected_accounts.is_null());
206 }
207
208 db_init_option_ |= AUTH_DB_INIT_SUCCESS;
209 }
210
211 mojo::String AccountsDbManager::GetAuthorizedUserForApp(mojo::String app_url) {
212 ensureAuthDbInit();
213
214 if (app_url.is_null()) {
215 return nullptr;
216 }
217 auto it = auth_grants_.last_selected_accounts.find(app_url);
218 if (it == auth_grants_.last_selected_accounts.end()) {
219 return nullptr;
220 }
221 return mojo::String(it.GetValue());
222 }
223
224 void AccountsDbManager::UpdateAuthorization(mojo::String app_url,
225 mojo::String username) {
226 if (app_url.is_null() || username.is_null()) {
227 return;
228 }
229 auth_grants_.last_selected_accounts[app_url] = username;
230
231 size_t buf_size = auth_grants_.GetSerializedSize();
232 char buf[buf_size];
qsr 2016/03/04 15:06:45 Why not directly creating a mojo::Array<uint8_t> o
ukode 2016/03/11 22:48:51 Done.
233 MOJO_CHECK(auth_grants_.Serialize(buf, buf_size));
234
235 std::vector<uint8_t> bytes_to_write(buf, buf + buf_size);
236 mojo::files::Whence whence;
237 whence = mojo::files::Whence::FROM_START;
238
239 auth_db_file_->Write(
240 mojo::Array<uint8_t>::From(bytes_to_write), 0, whence,
241 [this](mojo::files::Error error, uint32_t num_bytes_written) {
242 this->OnAuthFileWriteResponse(error, num_bytes_written);
243 });
244 }
245
246 void AccountsDbManager::OnAuthFileWriteResponse(
247 const mojo::files::Error error,
248 const uint32_t num_bytes_written) {
249 if (mojo::files::Error::OK != error) {
250 LOG(ERROR) << "Write() error on auth db:" << error;
251 delete this;
252 return;
253 }
254 }
255
256 } // namespace authentication
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698