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

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: Addressed review comments Created 4 years, 11 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
15 namespace authentication {
16
17 const char* kAccountsDbFileName = "accounts_db.txt";
viettrungluu 2016/01/11 21:23:44 nit: This isn't as const as you think it is. You p
ukode 2016/02/09 00:20:17 Thanks for the tip. Done.
18
19 AccountsDbManager::AccountsDbManager() : file_(nullptr), contents_(nullptr) {}
20
21 AccountsDbManager::AccountsDbManager(mojo::files::DirectoryPtr& directory) {
viettrungluu 2016/01/11 21:23:45 Depending on how this is used, this should either
ukode 2016/02/09 00:20:17 Done.
22 // Open accounts db file
23 mojo::files::Error error = mojo::files::Error::INTERNAL;
24 directory.Pass()->OpenFile(kAccountsDbFileName, GetProxy(&file_),
viettrungluu 2016/01/11 21:23:44 No |.Pass()| here.
ukode 2016/02/09 00:20:17 Done.
25 mojo::files::kOpenFlagCreate |
26 mojo::files::kOpenFlagRead |
27 mojo::files::kOpenFlagWrite,
28 Capture(&error));
29 directory.WaitForIncomingResponse();
viettrungluu 2016/01/11 21:23:44 Instead of waiting for the response (esp. since yo
ukode 2016/02/09 00:20:17 Done.
30 if (mojo::files::Error::OK != error) {
31 LOG(FATAL) << "Not able to open accounts database file.";
32 }
33 }
34
35 AccountsDbManager::~AccountsDbManager() {
36 // Close the accounts db file
37 mojo::files::Error error = mojo::files::Error::INTERNAL;
38 file_->Close(Capture(&error));
39 file_.WaitForIncomingResponse();
viettrungluu 2016/01/11 21:23:45 Ditto here. Note that closing the file is optional
ukode 2016/02/09 00:20:17 Ok,removing the file close functionality for now.
40 if (mojo::files::Error::OK != error) {
41 LOG(FATAL) << "Not able to close accounts database file.";
42 }
43 }
44
45 void AccountsDbManager::GetUpdatedDbContents(
46 const mojo::String& username,
47 const mojo::String& new_account_data,
48 bool user_exists,
49 mojo::String& new_db_contents) {
viettrungluu 2016/01/11 21:23:44 For this method, you should probably just return a
ukode 2016/02/09 00:20:18 Done.
50 if (username.is_null() || new_account_data.is_null()) {
51 return;
52 }
53 std::string buffer;
54 if (user_exists) {
55 // Remove existing user record
56 base::StringTokenizer lines(AccountsDbManager::contents_, "\n");
viettrungluu 2016/01/11 21:23:44 (Here and below....) |AccountsDbManager::| not nee
ukode 2016/02/09 00:20:18 Done.
57 std::string user_record;
58 while (lines.GetNext()) {
59 user_record = lines.token();
60 if (user_record.find(username) == std::string::npos) {
viettrungluu 2016/01/11 21:23:44 What's the format of contents_? Does this properly
ukode 2016/02/09 00:20:17 Good catch. Added necessary checks and removed fil
61 buffer += user_record;
62 buffer += "\n";
63 }
64 }
65 } else {
66 if (!AccountsDbManager::contents_.empty()) { // first account
67 buffer += "\n";
viettrungluu 2016/01/11 21:23:45 Why is this needed? (It results in |buffer| beginn
ukode 2016/02/09 00:20:17 This is the line separator between records in the
68 }
69 }
70 buffer += new_account_data;
71 new_db_contents = buffer;
72 return;
viettrungluu 2016/01/11 21:23:44 nit: no |return| needed here
ukode 2016/02/09 00:20:17 Done.
73 }
74
75 bool AccountsDbManager::UpdateAccount(const mojo::String& username,
76 const mojo::String& new_account_data) {
77 if (username.is_null() || new_account_data.is_null()) {
78 return false;
79 }
80 bool user_exists =
81 (AccountsDbManager::contents_.find(username) != std::string::npos)
82 ? true
viettrungluu 2016/01/11 21:23:44 |? true : false| is unnecessary.
ukode 2016/02/09 00:20:18 Done.
83 : false;
84
85 mojo::String new_db_contents;
86 GetUpdatedDbContents(username, new_account_data, user_exists,
87 new_db_contents);
88 if (new_db_contents.is_null()) {
89 return false;
90 }
91
92 // Rewrite the file each time with updated info.
93 std::vector<uint8_t> bytes_to_write(new_db_contents.get().begin(),
94 new_db_contents.get().end());
95 bytes_to_write.push_back('\0');
96 mojo::files::Error error = mojo::files::Error::INTERNAL;
97 uint32_t num_bytes_written = 0;
98 mojo::files::Whence whence;
99 if (user_exists) {
100 whence = mojo::files::Whence::FROM_START;
101 } else {
102 whence = mojo::files::Whence::FROM_CURRENT;
103 }
104 file_->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0, whence,
105 Capture(&error, &num_bytes_written));
106 file_.WaitForIncomingResponse();
viettrungluu 2016/01/11 21:23:44 You shouldn't do a blocking write like this. In ge
ukode 2016/02/09 00:20:17 Acknowledged. MOved to async method.
107 if (mojo::files::Error::OK != error) {
108 return false;
109 }
110
111 // Update the contents cache with new data
112 if (user_exists) {
113 AccountsDbManager::contents_.assign(new_db_contents.data(),
viettrungluu 2016/01/11 21:23:44 Keeping contents_ in sync with the actual contents
ukode 2016/02/09 00:20:18 Acknowledged.
114 new_db_contents.size());
115 } else {
116 AccountsDbManager::contents_ += new_db_contents;
117 }
118 return true;
119 }
120
121 void AccountsDbManager::GetAccountDataForUser(const mojo::String& username,
122 mojo::String& user_data) {
123 if (username.is_null()) {
124 return;
125 }
126
127 if (AccountsDbManager::contents_.empty()) {
128 mojo::Array<uint8_t> all_accounts_data(
129 AccountsDbManager::FetchAllAccounts());
130 if (!all_accounts_data.size()) {
131 return;
132 }
133 }
134
135 base::StringTokenizer lines(AccountsDbManager::contents_, "\n");
136 std::string entry;
137 while (lines.GetNext()) {
138 entry = lines.token();
139 if (entry.find(username) != std::string::npos) {
140 user_data.Swap(&entry);
141 return;
142 }
143 }
144 }
145
146 mojo::Array<uint8_t> AccountsDbManager::FetchAllAccounts() {
147 const size_t kMaxReadSize = 1 * 1024 * 1024;
148 mojo::Array<uint8_t> bytes_read;
149
150 mojo::files::Error error = mojo::files::Error::INTERNAL;
151 file_->Read(kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
152 Capture(&error, &bytes_read));
153 file_.WaitForIncomingResponse();
154 if (mojo::files::Error::OK != error) {
155 return mojo::Array<uint8_t>();
156 }
157
158 const std::vector<uint8_t> vec = bytes_read.storage();
159 AccountsDbManager::contents_.assign((char*)vec.data(), vec.size());
160
161 return bytes_read.Pass();
162 }
163
164 } // namespace authentication
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698