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

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: updated demo namespaces Created 5 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
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";
18 AccountsDbManager::AccountsDbManager()
19 : directory_(nullptr), contents_(nullptr) {}
20
21 AccountsDbManager::AccountsDbManager(mojo::files::FilesPtr files) {
22 // TODO: Move to a file system with secure privileges as the accounts db needs
23 // to persist across multiple invocations and apps, and the temporary root
24 // solution here is just a short term path.
25 mojo::files::Error error = mojo::files::Error::INTERNAL;
26 files->OpenFileSystem(nullptr, GetProxy(&directory_), Capture(&error));
27 files.WaitForIncomingResponse();
28 if (mojo::files::Error::OK != error) {
29 LOG(FATAL) << "Unable to initialize accounts DB";
30 }
31 }
32
33 AccountsDbManager::~AccountsDbManager() {}
34
35 bool AccountsDbManager::UpdateAccount(const mojo::String& username,
36 const mojo::String& new_account_data) {
37 if (username.is_null() || new_account_data.is_null()) {
38 return false;
39 }
40
41 std::string buffer;
42 std::string new_contents(AccountsDbManager::contents_);
jln (very slow on Chromium) 2015/12/08 22:27:29 No need for AccountsDbManager:: qualifier.
ukode 2015/12/16 19:24:12 Done.
43 mojo::String existing_user_data;
44 AccountsDbManager::GetAccountDataForUser(username, existing_user_data);
45
46 if (existing_user_data.is_null()) { // new account to be added
jln (very slow on Chromium) 2015/12/08 22:27:29 I don't quite understand what's happening here yet
ukode 2015/12/16 19:24:12 This is very specific to account db functionality.
47 if (!AccountsDbManager::contents_.empty()) {
48 buffer += "\n";
49 }
50 buffer += new_account_data.get();
51 new_contents += buffer;
52 } else {
53 // Parse the existing account data and replace the token
54 base::StringTokenizer lines(AccountsDbManager::contents_, "\n");
55 std::string user_data;
56 while (lines.GetNext()) {
57 user_data = lines.token();
58 if (user_data.find(username) != std::string::npos) {
59 buffer += new_account_data.get(); // replace with new contents
60 } else {
61 buffer += user_data; // carry forward the existing user data
62 }
63 buffer += "\n";
64 }
65 if (!buffer.empty()) {
66 buffer.pop_back();
67 }
68 new_contents.assign(buffer.c_str(), buffer.size());
jln (very slow on Chromium) 2015/12/08 22:27:29 Why are new_contents and buffer both needed. It lo
ukode 2015/12/16 19:24:13 Fixed it as part of refactoring.
69 }
70
71 // Open accounts db file
72 mojo::files::FilePtr file;
73 mojo::files::Error error = mojo::files::Error::INTERNAL;
74 if (existing_user_data.is_null()) {
75 // Append to existing File
76 directory_->OpenFile(kAccountsDbFileName, GetProxy(&file),
77 mojo::files::kOpenFlagWrite |
78 mojo::files::kOpenFlagCreate |
79 mojo::files::kOpenFlagAppend,
80 Capture(&error));
81 } else {
82 // Rewrite the file contents with updated info
83 directory_->OpenFile(
84 kAccountsDbFileName, GetProxy(&file),
85 mojo::files::kOpenFlagWrite | mojo::files::kOpenFlagCreate,
86 Capture(&error));
87 }
88 directory_.WaitForIncomingResponse();
89 if (mojo::files::Error::OK != error) {
90 return false;
jln (very slow on Chromium) 2015/12/08 22:27:29 Looks like the opened file is not getting closed h
ukode 2015/12/16 19:24:12 Good catch. Fixed it.
91 }
92
93 // Write to it.
94 std::vector<uint8_t> bytes_to_write(buffer.begin(), buffer.end());
95 bytes_to_write.push_back('\0');
96 error = mojo::files::Error::INTERNAL;
97 uint32_t num_bytes_written = 0;
98 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
99 mojo::files::Whence::FROM_CURRENT,
100 Capture(&error, &num_bytes_written));
101 file.WaitForIncomingResponse();
102 if (mojo::files::Error::OK != error) {
103 return false;
104 }
105
106 // Close the accounts db file
107 error = mojo::files::Error::INTERNAL;
108 file->Close(Capture(&error));
109 file.WaitForIncomingResponse();
110 if (mojo::files::Error::OK != error) {
111 return false;
112 }
113
114 // Update the existing contents with new data
115 AccountsDbManager::contents_.assign(new_contents.c_str(),
116 new_contents.size());
117 return true;
118 }
119
120 void AccountsDbManager::GetAccountDataForUser(const mojo::String& username,
121 mojo::String& user_data) {
122 if (username.is_null()) {
123 return;
124 }
125
126 if (AccountsDbManager::contents_.empty()) {
127 mojo::Array<uint8_t> all_accounts_data(
128 AccountsDbManager::FetchAllAccounts());
129 if (!all_accounts_data.size()) {
130 return;
131 }
132 }
133
134 base::StringTokenizer lines(AccountsDbManager::contents_, "\n");
135 std::string entry;
136 while (lines.GetNext()) {
137 entry = lines.token();
138 if (entry.find(username) != std::string::npos) {
139 user_data.Swap(&entry);
140 return;
141 }
142 }
143 }
144
145 mojo::Array<uint8_t> AccountsDbManager::FetchAllAccounts() {
146 const size_t kMaxReadSize = 1 * 1024 * 1024;
147
148 // Open accounts db file
149 mojo::files::FilePtr file;
150 mojo::files::Error error = mojo::files::Error::INTERNAL;
151 directory_->OpenFile(kAccountsDbFileName, GetProxy(&file),
152 mojo::files::kOpenFlagRead, Capture(&error));
153 directory_.WaitForIncomingResponse();
154 if (mojo::files::Error::OK != error) {
155 return mojo::Array<uint8_t>();
156 }
157
158 // Read from it.
159 mojo::Array<uint8_t> bytes_read;
160 error = mojo::files::Error::INTERNAL;
161 file->Read(kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
162 Capture(&error, &bytes_read));
163
164 file.WaitForIncomingResponse();
165 if (mojo::files::Error::OK != error) {
166 return mojo::Array<uint8_t>();
167 }
168
169 // Close the accounts db file
170 error = mojo::files::Error::INTERNAL;
171 file->Close(Capture(&error));
172 file.WaitForIncomingResponse();
173 if (mojo::files::Error::OK != error) {
174 return mojo::Array<uint8_t>();
175 }
176
177 const std::vector<uint8_t> vec = bytes_read.storage();
jln (very slow on Chromium) 2015/12/08 22:27:29 I'm surprised if Mojo doesn't offer a better way t
ukode 2015/12/16 19:24:12 +vtl/mitch - do you have any other suggestion here
178 AccountsDbManager::contents_.assign((char*)vec.data(), vec.size());
179
180 return bytes_read.Pass();
181 }
182
183 } // namespace authentication
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698