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

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: Removed data_unittest.py Created 4 years, 9 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..f7cd3fecc9167768b1abf2970e01f1041455031c
--- /dev/null
+++ b/services/authentication/accounts_db_manager.cc
@@ -0,0 +1,292 @@
+// Copyright 2016 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"
+#include "services/authentication/credentials_impl_db.mojom.h"
+
+namespace authentication {
+
+char kAccountsDbFileName[] = "creds_db";
+char kAuthDbFileName[] = "auth_db";
+const uint32 kAuthDbVersion = 1;
+const uint32 kCredsDbVersion = 1;
+
+AccountsDbManager::AccountsDbManager(const mojo::files::DirectoryPtr directory)
+ : creds_db_file_(nullptr), auth_db_file_(nullptr) {
+ // 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;
+ error_ = CREDENTIALS_DB_READ_ERROR;
+ 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;
+ error_ = AUTHORIZATIONS_DB_READ_ERROR;
+ return;
+ }
+ });
+
+ Initialize();
+}
+
+AccountsDbManager::~AccountsDbManager() {}
+
+bool AccountsDbManager::isValid() {
+ return error_ == NONE;
+}
+
+authentication::CredentialsPtr AccountsDbManager::GetCredentials(
+ const mojo::String& username) {
+ ensureCredentialsDbInit();
+ CHECK(error_ == NONE);
+
+ authentication::CredentialsPtr creds = authentication::Credentials::New();
+ if (username.is_null()) {
+ return creds.Pass();
+ }
+
+ auto it = creds_store_.credentials.find(username);
+ if (it != creds_store_.credentials.end()) {
+ creds->token = it.GetValue()->token;
+ creds->auth_provider = it.GetValue()->auth_provider;
+ creds->scopes = it.GetValue()->scopes;
+ creds->credential_type = it.GetValue()->credential_type;
+ }
+ return creds.Pass();
+}
+
+mojo::Array<mojo::String> AccountsDbManager::GetAllUsers() {
+ ensureCredentialsDbInit();
+ CHECK(error_ == NONE);
+
+ mojo::Array<mojo::String> users =
+ mojo::Array<mojo::String>::New(creds_store_.credentials.size());
+ size_t i = 0;
+
+ for (auto it = creds_store_.credentials.begin();
+ it != creds_store_.credentials.end(); it++) {
+ users[i++] = it.GetKey().get();
+ }
+
+ return users.Pass();
+}
+
+void AccountsDbManager::UpdateCredentials(
+ const mojo::String& username,
+ const authentication::CredentialsPtr creds) {
+ ensureCredentialsDbInit();
+ CHECK(error_ == NONE);
+
+ if (username.is_null()) {
+ return;
+ }
+
+ // Update contents cache with new data
+ creds_store_.credentials[username] = authentication::Credentials::New();
+ creds_store_.credentials[username]->token = creds->token;
+ creds_store_.credentials[username]->auth_provider = creds->auth_provider;
+ creds_store_.credentials[username]->scopes = creds->scopes;
+ creds_store_.credentials[username]->credential_type = creds->credential_type;
+
+ size_t buf_size = creds_store_.GetSerializedSize();
+ auto bytes_to_write = mojo::Array<uint8_t>::New(buf_size);
+ MOJO_CHECK(creds_store_.Serialize(&bytes_to_write.front(), buf_size));
+
+ mojo::files::Whence whence;
+ whence = mojo::files::Whence::FROM_START;
+ creds_db_file_->Write(
+ bytes_to_write.Pass(), 0, whence,
+ [this](mojo::files::Error error, uint32_t num_bytes_written) {
+ this->OnCredentialsFileWriteResponse(error, num_bytes_written);
+ });
+}
+
+void AccountsDbManager::OnCredentialsFileWriteResponse(
+ const mojo::files::Error error,
+ const uint32_t num_bytes_written) {
+ CHECK(error_ == NONE);
+
+ if (mojo::files::Error::OK != error) {
+ LOG(ERROR) << "Write() error on accounts db:" << error;
+ error_ = CREDENTIALS_DB_WRITE_ERROR;
+ return;
+ }
+}
+
+void AccountsDbManager::ensureCredentialsDbInit() {
+ if ((db_init_option_ & CREDENTIALS_DB_INIT_SUCCESS) !=
+ CREDENTIALS_DB_INIT_SUCCESS) {
+ CHECK(creds_db_file_.WaitForIncomingResponse());
+ }
+}
+
+void AccountsDbManager::ensureAuthorizationsDbInit() {
+ if ((db_init_option_ & AUTHORIZATIONS_DB_INIT_SUCCESS) !=
+ AUTHORIZATIONS_DB_INIT_SUCCESS) {
+ CHECK(auth_db_file_.WaitForIncomingResponse());
+ }
+}
+
+void AccountsDbManager::Initialize() {
+ CHECK(error_ == NONE);
+
+ const size_t kMaxReadSize = 1 * 1024 * 1024;
+ mojo::Array<uint8_t> cred_bytes_read;
+ creds_db_file_->Read(
+ kMaxReadSize - 1, 0, mojo::files::Whence::FROM_START,
+ [this](mojo::files::Error error, mojo::Array<uint8_t> cred_bytes_read) {
+ this->OnCredentialsFileReadResponse(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->OnAuthorizationsFileReadResponse(error, auth_bytes_read.Pass());
+ });
+}
+
+void AccountsDbManager::OnCredentialsFileReadResponse(
+ const mojo::files::Error error,
+ const mojo::Array<uint8_t> bytes_read) {
+ CHECK(error_ == NONE);
+
+ if (error != mojo::files::Error::OK) {
+ LOG(ERROR) << "Read() error on accounts db: " << error;
+ error_ = CREDENTIALS_DB_READ_ERROR;
+ return;
+ }
+
+ if (bytes_read.size() != 0) {
+ // Deserialize data from file
+ const char* data = reinterpret_cast<const char*>(&bytes_read[0]);
+
+ // Validate the file contents before deserializing
+ mojo::internal::BoundsChecker bounds_checker(data, bytes_read.size(), 0);
+ std::string error;
+ mojo::internal::ValidationError verror =
+ internal::CredentialStore_Data::Validate(data, &bounds_checker, &error);
+ if (verror != mojo::internal::ValidationError::NONE) {
+ LOG(ERROR) << "Validation() error on accounts db ["
+ << ValidationErrorToString(verror) << "][" << error << "]";
+ error_ = CREDENTIALS_DB_VALIDATE_ERROR;
+ return;
+ }
+
+ creds_store_.Deserialize((void*)data);
+ // When we have multiple versions, this is not a fatal error, but a sign
+ // that we need to update (or reinitialize) the db.
+ CHECK_EQ(creds_store_.version, kCredsDbVersion);
+ } else {
+ creds_store_.version = kCredsDbVersion;
+ }
+
+ db_init_option_ |= CREDENTIALS_DB_INIT_SUCCESS;
+}
+
+void AccountsDbManager::OnAuthorizationsFileReadResponse(
+ const mojo::files::Error error,
+ const mojo::Array<uint8_t> bytes_read) {
+ CHECK(error_ == NONE);
+
+ if (error != mojo::files::Error::OK) {
+ LOG(ERROR) << "Read() error on auth db: " << error;
+ error_ = AUTHORIZATIONS_DB_READ_ERROR;
+ return;
+ }
+
+ if (bytes_read.size() != 0) {
+ // Deserialize data from file
+ const char* data = reinterpret_cast<const char*>(&bytes_read[0]);
+
+ // Validate the file contents before deserializing
+ mojo::internal::BoundsChecker bounds_checker(data, bytes_read.size(), 0);
+ if (internal::Db_Data::Validate(data, &bounds_checker, nullptr) !=
+ mojo::internal::ValidationError::NONE) {
+ LOG(ERROR) << "Validation() error on auth db.";
+ error_ = AUTHORIZATIONS_DB_VALIDATE_ERROR;
+ return;
+ }
+
+ auth_grants_.Deserialize((void*)data);
+ // When we have multiple versions, this is not a fatal error, but a sign
+ // that we need to update (or reinitialize) the db.
+ CHECK_EQ(auth_grants_.version, kAuthDbVersion);
+ } else {
+ auth_grants_.version = kAuthDbVersion;
+ }
+
+ db_init_option_ |= AUTHORIZATIONS_DB_INIT_SUCCESS;
+}
+
+mojo::String AccountsDbManager::GetAuthorizedUserForApp(mojo::String app_url) {
+ ensureAuthorizationsDbInit();
+ CHECK(error_ == NONE);
+
+ 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) {
+ ensureAuthorizationsDbInit();
+ CHECK(error_ == NONE);
+
+ if (app_url.is_null() || username.is_null()) {
+ return;
+ }
+ auth_grants_.last_selected_accounts[app_url] = username;
+
+ size_t buf_size = auth_grants_.GetSerializedSize();
+ auto bytes_to_write = mojo::Array<uint8_t>::New(buf_size);
+ MOJO_CHECK(auth_grants_.Serialize(&bytes_to_write.front(), buf_size));
+
+ mojo::files::Whence whence;
+ whence = mojo::files::Whence::FROM_START;
+ auth_db_file_->Write(
+ bytes_to_write.Pass(), 0, whence,
+ [this](mojo::files::Error error, uint32_t num_bytes_written) {
+ this->OnAuthorizationsFileWriteResponse(error, num_bytes_written);
+ });
+}
+
+void AccountsDbManager::OnAuthorizationsFileWriteResponse(
+ const mojo::files::Error error,
+ const uint32_t num_bytes_written) {
+ CHECK(error_ == NONE);
+
+ if (mojo::files::Error::OK != error) {
+ LOG(ERROR) << "Write() error on auth db:" << error;
+ error_ = AUTHORIZATIONS_DB_WRITE_ERROR;
+ return;
+ }
+}
+
+} // namespace authentication
« no previous file with comments | « services/authentication/accounts_db_manager.h ('k') | services/authentication/accounts_db_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698