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

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: Created 4 years, 10 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/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
16 namespace authentication {
17
18 char kAccountsDbFileName[] = "creds_db";
19 char kAuthDbFileName[] = "auth_db";
20 const uint32 kAuthDbVersion = 1;
21
22 AccountsDbManager::AccountsDbManager()
23 : creds_db_file_(nullptr), auth_db_file_(nullptr), contents_(nullptr) {}
24
25 AccountsDbManager::AccountsDbManager(
26 const mojo::files::DirectoryPtr directory) {
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
55 mojo::String AccountsDbManager::GetUpdatedDbContents(
56 const mojo::String& username,
57 const mojo::String& new_account_data,
58 bool user_exists) {
59 if (username.is_null() || new_account_data.is_null()) {
60 return nullptr;
61 }
62 std::string buffer;
63 if (user_exists) {
64 // Remove existing user record
65 base::StringTokenizer lines(contents_, "\n");
66 std::string user_record;
67 while (lines.GetNext()) {
qsr 2016/02/16 14:17:06 Please comment that you are removing the entry for
ukode 2016/02/26 21:35:49 Had the same comment two lines above. Moved it dow
68 user_record = lines.token();
69 std::size_t pos = user_record.find(username.get() + ",");
70 if ((pos == std::string::npos) || (pos != 0)) {
qsr 2016/02/16 14:17:06 std::string::npos will not be 0, so pos != 0 is en
ukode 2016/02/26 21:35:49 Acknowledged.
71 buffer += user_record;
72 buffer += "\n";
73 }
74 }
75 } else {
76 if (!contents_.empty()) { // first account
77 buffer += "\n";
78 }
79 }
80 buffer += new_account_data;
81 return mojo::String(buffer);
82 }
83
84 void AccountsDbManager::UpdateAccount(const mojo::String& username,
85 const mojo::String& new_account_data) {
86 if (username.is_null() || new_account_data.is_null()) {
87 return;
88 }
89 bool user_exists = !GetAccountDataForUser(username).is_null();
qsr 2016/02/16 14:17:06 This is parsing the string.
ukode 2016/02/26 21:35:49 Acknowledged.
90
91 mojo::String new_db_contents =
92 GetUpdatedDbContents(username, new_account_data, user_exists);
qsr 2016/02/16 14:17:06 And this is doing it again. Any reason the in-mem
ukode 2016/02/26 21:35:49 Got rid of this extra parsing completely,and direc
93 if (new_db_contents.is_null()) {
94 return;
95 }
96
97 // Update contents cache with new data
98 if (user_exists) {
99 contents_.assign(new_db_contents.data(), new_db_contents.size());
100 } else {
101 contents_ += new_db_contents;
102 }
103
104 // Write updated contents to file
105 std::vector<uint8_t> bytes_to_write(new_db_contents.get().begin(),
106 new_db_contents.get().end());
107 bytes_to_write.push_back('\0');
108 mojo::files::Whence whence;
109 if (user_exists) {
110 whence = mojo::files::Whence::FROM_START;
111 } else {
112 whence = mojo::files::Whence::FROM_CURRENT;
113 }
114 creds_db_file_->Write(
115 mojo::Array<uint8_t>::From(bytes_to_write), 0, whence,
116 [this](mojo::files::Error error, uint32_t num_bytes_written) {
117 this->OnWriteResponse(error, num_bytes_written);
118 });
119 }
120
121 void AccountsDbManager::OnWriteResponse(const mojo::files::Error error,
122 const uint32_t num_bytes_written) {
123 if (mojo::files::Error::OK != error) {
124 LOG(ERROR) << "Write() error on accounts db:" << error;
125 delete this;
qsr 2016/02/16 14:17:06 Return after the delete. Doesn't matter that much
ukode 2016/02/26 21:35:49 Done.
126 }
127 return;
128 }
129
130 mojo::String AccountsDbManager::GetAccountDataForUser(
131 const mojo::String& username) {
132 if (username.is_null() || contents_.empty()) {
133 return nullptr;
134 }
135
136 base::StringTokenizer lines(contents_, "\n");
137 std::string entry;
138 while (lines.GetNext()) {
139 entry = lines.token();
140 std::size_t pos = entry.find(username.get() + ",");
141 if ((pos != std::string::npos) && (pos == 0)) {
142 return mojo::String(entry);
143 }
144 }
145 return nullptr;
146 }
147
148 mojo::String AccountsDbManager::GetAllUserAccounts() {
149 return mojo::String(contents_);
150 }
151
152 void AccountsDbManager::Initialize() {
153 auth_grants.version = kAuthDbVersion;
154
155 const size_t kMaxReadSize = 1 * 1024 * 1024;
156 mojo::Array<uint8_t> cred_bytes_read;
157 creds_db_file_->Read(
qsr 2016/02/16 14:17:06 Don't you have a race in this class? What happen i
ukode 2016/02/26 21:35:49 The async reads happen very quickly and have enoug
158 kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
159 [this](mojo::files::Error error, mojo::Array<uint8_t> cred_bytes_read) {
160 this->OnReadResponse(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::OnReadResponse(const mojo::files::Error error,
qsr 2016/02/16 14:17:06 Maybe rename this. Response is not that clear when
ukode 2016/02/26 21:35:49 Acknowledged.
172 const mojo::Array<uint8_t> bytes_read) {
173 if (error != mojo::files::Error::OK) {
174 LOG(ERROR) << "Read() error on accounts db: " << error;
175 delete this;
176 return;
177 }
178
179 if (bytes_read.size() != 0) {
180 contents_.assign(reinterpret_cast<const char*>(&bytes_read[0]),
181 bytes_read.size());
182 }
183 }
184
185 void AccountsDbManager::OnAuthFileReadResponse(
186 const mojo::files::Error error,
187 const mojo::Array<uint8_t> bytes_read) {
188 if (error != mojo::files::Error::OK) {
189 LOG(ERROR) << "Read() error on auth db: " << error;
190 delete this;
191 return;
192 }
193
194 if (bytes_read.size() != 0) {
195 // Deserialize data from file
196 const char* p = reinterpret_cast<const char*>(&bytes_read[0]);
qsr 2016/02/16 14:17:06 s/p/data/g?
ukode 2016/02/26 21:35:49 Done.
197 auth_grants.Deserialize((void*)p);
198 CHECK_EQ(auth_grants.version, kAuthDbVersion);
199 CHECK(!auth_grants.last_selected_accounts.is_null());
200 }
201 }
202
203 mojo::String AccountsDbManager::GetAuthorizedUserForApp(mojo::String app_url) {
204 if (app_url.is_null()) {
205 return nullptr;
206 }
207 auto it = auth_grants.last_selected_accounts.find(app_url);
208 if (it == auth_grants.last_selected_accounts.end()) {
209 return nullptr;
210 }
211 return mojo::String(it.GetValue());
212 }
213
214 void AccountsDbManager::UpdateAuthorization(mojo::String app_url,
215 mojo::String username) {
216 if (app_url.is_null() || username.is_null()) {
217 return;
218 }
219 auth_grants.last_selected_accounts[app_url] = username;
220
221 size_t buf_size = auth_grants.GetSerializedSize();
222 char buf[buf_size];
223 MOJO_CHECK(auth_grants.Serialize(buf, buf_size));
224
225 std::vector<uint8_t> bytes_to_write(buf, buf + buf_size);
226 bytes_to_write.push_back('\0');
qsr 2016/02/16 14:17:06 Why this?
ukode 2016/02/26 21:35:49 The very first version of files service needed thi
227 mojo::files::Whence whence;
228 whence = mojo::files::Whence::FROM_START;
229
230 auth_db_file_->Write(
231 mojo::Array<uint8_t>::From(bytes_to_write), 0, whence,
232 [this](mojo::files::Error error, uint32_t num_bytes_written) {
233 this->OnAuthFileWriteResponse(error, num_bytes_written);
234 });
235 }
236
237 void AccountsDbManager::OnAuthFileWriteResponse(
238 const mojo::files::Error error,
239 const uint32_t num_bytes_written) {
240 if (mojo::files::Error::OK != error) {
241 LOG(ERROR) << "Write() error on auth db:" << error;
242 delete this;
243 }
244 return;
245 }
246
247 } // namespace authentication
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698