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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: services/authentication/accounts_db_manager.cc
diff --git a/services/authentication/accounts_db_manager.cc b/services/authentication/accounts_db_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..942cd435d6f85515f27f7d1ecf5d9d1f47df23fb
--- /dev/null
+++ b/services/authentication/accounts_db_manager.cc
@@ -0,0 +1,247 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/authentication/accounts_db_manager.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "base/strings/string_tokenizer.h"
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+#include "mojo/services/files/interfaces/files.mojom.h"
+#include "services/authentication/authentication_impl_db.mojom.h"
+
+namespace authentication {
+
+char kAccountsDbFileName[] = "creds_db";
+char kAuthDbFileName[] = "auth_db";
+const uint32 kAuthDbVersion = 1;
+
+AccountsDbManager::AccountsDbManager()
+ : creds_db_file_(nullptr), auth_db_file_(nullptr), contents_(nullptr) {}
+
+AccountsDbManager::AccountsDbManager(
+ const mojo::files::DirectoryPtr directory) {
+ // Initialize in-memory contents from existing DB file
+ directory->OpenFile(
+ kAccountsDbFileName, GetProxy(&creds_db_file_),
+ mojo::files::kOpenFlagCreate | mojo::files::kOpenFlagRead |
+ mojo::files::kOpenFlagWrite,
+ [this](mojo::files::Error error) {
+ if (mojo::files::Error::OK != error) {
+ LOG(ERROR) << "Open() error on credentials db:" << error;
+ delete this;
+ return;
+ }
+ });
+ directory->OpenFile(kAuthDbFileName, GetProxy(&auth_db_file_),
+ mojo::files::kOpenFlagCreate |
+ mojo::files::kOpenFlagRead |
+ mojo::files::kOpenFlagWrite,
+ [this](mojo::files::Error error) {
+ if (mojo::files::Error::OK != error) {
+ LOG(ERROR) << "Open() error on auth db:" << error;
+ delete this;
+ return;
+ }
+ });
+ Initialize();
+}
+
+AccountsDbManager::~AccountsDbManager() {}
+
+mojo::String AccountsDbManager::GetUpdatedDbContents(
+ const mojo::String& username,
+ const mojo::String& new_account_data,
+ bool user_exists) {
+ if (username.is_null() || new_account_data.is_null()) {
+ return nullptr;
+ }
+ std::string buffer;
+ if (user_exists) {
+ // Remove existing user record
+ base::StringTokenizer lines(contents_, "\n");
+ std::string user_record;
+ 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
+ user_record = lines.token();
+ std::size_t pos = user_record.find(username.get() + ",");
+ 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.
+ buffer += user_record;
+ buffer += "\n";
+ }
+ }
+ } else {
+ if (!contents_.empty()) { // first account
+ buffer += "\n";
+ }
+ }
+ buffer += new_account_data;
+ return mojo::String(buffer);
+}
+
+void AccountsDbManager::UpdateAccount(const mojo::String& username,
+ const mojo::String& new_account_data) {
+ if (username.is_null() || new_account_data.is_null()) {
+ return;
+ }
+ 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.
+
+ mojo::String new_db_contents =
+ 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
+ if (new_db_contents.is_null()) {
+ return;
+ }
+
+ // Update contents cache with new data
+ if (user_exists) {
+ contents_.assign(new_db_contents.data(), new_db_contents.size());
+ } else {
+ contents_ += new_db_contents;
+ }
+
+ // Write updated contents to file
+ std::vector<uint8_t> bytes_to_write(new_db_contents.get().begin(),
+ new_db_contents.get().end());
+ bytes_to_write.push_back('\0');
+ mojo::files::Whence whence;
+ if (user_exists) {
+ whence = mojo::files::Whence::FROM_START;
+ } else {
+ whence = mojo::files::Whence::FROM_CURRENT;
+ }
+ creds_db_file_->Write(
+ mojo::Array<uint8_t>::From(bytes_to_write), 0, whence,
+ [this](mojo::files::Error error, uint32_t num_bytes_written) {
+ this->OnWriteResponse(error, num_bytes_written);
+ });
+}
+
+void AccountsDbManager::OnWriteResponse(const mojo::files::Error error,
+ const uint32_t num_bytes_written) {
+ if (mojo::files::Error::OK != error) {
+ LOG(ERROR) << "Write() error on accounts db:" << error;
+ 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.
+ }
+ return;
+}
+
+mojo::String AccountsDbManager::GetAccountDataForUser(
+ const mojo::String& username) {
+ if (username.is_null() || contents_.empty()) {
+ return nullptr;
+ }
+
+ base::StringTokenizer lines(contents_, "\n");
+ std::string entry;
+ while (lines.GetNext()) {
+ entry = lines.token();
+ std::size_t pos = entry.find(username.get() + ",");
+ if ((pos != std::string::npos) && (pos == 0)) {
+ return mojo::String(entry);
+ }
+ }
+ return nullptr;
+}
+
+mojo::String AccountsDbManager::GetAllUserAccounts() {
+ return mojo::String(contents_);
+}
+
+void AccountsDbManager::Initialize() {
+ auth_grants.version = kAuthDbVersion;
+
+ const size_t kMaxReadSize = 1 * 1024 * 1024;
+ mojo::Array<uint8_t> cred_bytes_read;
+ 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
+ kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
+ [this](mojo::files::Error error, mojo::Array<uint8_t> cred_bytes_read) {
+ this->OnReadResponse(error, cred_bytes_read.Pass());
+ });
+
+ mojo::Array<uint8_t> auth_bytes_read;
+ auth_db_file_->Read(
+ kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
+ [this](mojo::files::Error error, mojo::Array<uint8_t> auth_bytes_read) {
+ this->OnAuthFileReadResponse(error, auth_bytes_read.Pass());
+ });
+}
+
+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.
+ const mojo::Array<uint8_t> bytes_read) {
+ if (error != mojo::files::Error::OK) {
+ LOG(ERROR) << "Read() error on accounts db: " << error;
+ delete this;
+ return;
+ }
+
+ if (bytes_read.size() != 0) {
+ contents_.assign(reinterpret_cast<const char*>(&bytes_read[0]),
+ bytes_read.size());
+ }
+}
+
+void AccountsDbManager::OnAuthFileReadResponse(
+ const mojo::files::Error error,
+ const mojo::Array<uint8_t> bytes_read) {
+ if (error != mojo::files::Error::OK) {
+ LOG(ERROR) << "Read() error on auth db: " << error;
+ delete this;
+ return;
+ }
+
+ if (bytes_read.size() != 0) {
+ // Deserialize data from file
+ 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.
+ auth_grants.Deserialize((void*)p);
+ CHECK_EQ(auth_grants.version, kAuthDbVersion);
+ CHECK(!auth_grants.last_selected_accounts.is_null());
+ }
+}
+
+mojo::String AccountsDbManager::GetAuthorizedUserForApp(mojo::String app_url) {
+ if (app_url.is_null()) {
+ return nullptr;
+ }
+ auto it = auth_grants.last_selected_accounts.find(app_url);
+ if (it == auth_grants.last_selected_accounts.end()) {
+ return nullptr;
+ }
+ return mojo::String(it.GetValue());
+}
+
+void AccountsDbManager::UpdateAuthorization(mojo::String app_url,
+ mojo::String username) {
+ if (app_url.is_null() || username.is_null()) {
+ return;
+ }
+ auth_grants.last_selected_accounts[app_url] = username;
+
+ size_t buf_size = auth_grants.GetSerializedSize();
+ char buf[buf_size];
+ MOJO_CHECK(auth_grants.Serialize(buf, buf_size));
+
+ std::vector<uint8_t> bytes_to_write(buf, buf + buf_size);
+ 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
+ mojo::files::Whence whence;
+ whence = mojo::files::Whence::FROM_START;
+
+ auth_db_file_->Write(
+ mojo::Array<uint8_t>::From(bytes_to_write), 0, whence,
+ [this](mojo::files::Error error, uint32_t num_bytes_written) {
+ this->OnAuthFileWriteResponse(error, num_bytes_written);
+ });
+}
+
+void AccountsDbManager::OnAuthFileWriteResponse(
+ const mojo::files::Error error,
+ const uint32_t num_bytes_written) {
+ if (mojo::files::Error::OK != error) {
+ LOG(ERROR) << "Write() error on auth db:" << error;
+ delete this;
+ }
+ return;
+}
+
+} // namespace authentication

Powered by Google App Engine
This is Rietveld 408576698