Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |