Commit b9ba95a8 authored by Findit's avatar Findit

Revert "Add Chrome OS Account Manager"

This reverts commit 33cfbf08.

Reason for revert:

Findit (https://goo.gl/kROfz5) identified CL at revision 543944 as the
culprit for failures in the build cycles as shown on:
https://findit-for-me.appspot.com/waterfall/culprit?key=ag9zfmZpbmRpdC1mb3ItbWVyRAsSDVdmU3VzcGVjdGVkQ0wiMWNocm9taXVtLzMzY2ZiZjA4ODFlYmU3ZWQyMGRhNmU2ZjU2M2M3YjQ1YTkzNDRhNDMM

Sample Failed Build: https://ci.chromium.org/buildbot/chromium.chromiumos/linux-chromeos-dbg/4761

Sample Failed Step: compile

Original change's description:
> Add Chrome OS Account Manager
> 
>   - Loads Login Scoped Tokens (LSTs) from disk to memory
>   - Persists updates to LSTs to disk
> 
> Design doc is linked in the bug id.
> This CL creates the core of Account Manager and its ability to load
> and persist its state.
> Follow up CLs will:
> - Link it with OAuth2TokenService via an OAuth2TokenServiceDelegate.
> - Add UI components to modify Account Manager's state.
> 
> Bug: 820046
> Change-Id: I1b43e11cfc7ed3592daf4a79ff664d377644f6a8
> Test: chromeos_unittests --gtest_filter="*AccountManager*"
> Reviewed-on: https://chromium-review.googlesource.com/955523
> Commit-Queue: Kush Sinha <sinhak@chromium.org>
> Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#543944}

Change-Id: Idd138c68b9de07ed160651c3a948aceb8fb5d92e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 820046
Reviewed-on: https://chromium-review.googlesource.com/967467
Cr-Commit-Position: refs/heads/master@{#543946}
parent 64ed6094
...@@ -19,7 +19,6 @@ component("chromeos") { ...@@ -19,7 +19,6 @@ component("chromeos") {
"//dbus", "//dbus",
] ]
deps = [ deps = [
":account_manager_proto",
":attestation_proto", ":attestation_proto",
":authpolicy_proto", ":authpolicy_proto",
":biod_proto", ":biod_proto",
...@@ -60,8 +59,6 @@ component("chromeos") { ...@@ -60,8 +59,6 @@ component("chromeos") {
"accelerometer/accelerometer_reader.h", "accelerometer/accelerometer_reader.h",
"accelerometer/accelerometer_types.cc", "accelerometer/accelerometer_types.cc",
"accelerometer/accelerometer_types.h", "accelerometer/accelerometer_types.h",
"account_manager/account_manager.cc",
"account_manager/account_manager.h",
"app_mode/kiosk_oem_manifest_parser.cc", "app_mode/kiosk_oem_manifest_parser.cc",
"app_mode/kiosk_oem_manifest_parser.h", "app_mode/kiosk_oem_manifest_parser.h",
"attestation/attestation_constants.cc", "attestation/attestation_constants.cc",
...@@ -667,7 +664,6 @@ test("chromeos_unittests") { ...@@ -667,7 +664,6 @@ test("chromeos_unittests") {
"//url", "//url",
] ]
sources = [ sources = [
"account_manager/account_manager_unittest.cc",
"app_mode/kiosk_oem_manifest_parser_unittest.cc", "app_mode/kiosk_oem_manifest_parser_unittest.cc",
"attestation/attestation_flow_unittest.cc", "attestation/attestation_flow_unittest.cc",
"audio/audio_devices_pref_handler_impl_unittest.cc", "audio/audio_devices_pref_handler_impl_unittest.cc",
...@@ -852,11 +848,3 @@ proto_library("smbprovider_proto") { ...@@ -852,11 +848,3 @@ proto_library("smbprovider_proto") {
proto_out_dir = "chromeos/dbus/smbprovider" proto_out_dir = "chromeos/dbus/smbprovider"
} }
proto_library("account_manager_proto") {
sources = [
"account_manager/tokens.proto",
]
proto_out_dir = "chromeos/account_manager"
}
// Copyright 2018 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 "chromeos/account_manager/account_manager.h"
#include <utility>
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/important_file_writer.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
#include "base/task_runner_util.h"
#include "base/task_scheduler/post_task.h"
#include "chromeos/account_manager/tokens.pb.h"
#include "third_party/protobuf/src/google/protobuf/message_lite.h"
namespace chromeos {
namespace {
constexpr base::FilePath::CharType kTokensFileName[] =
FILE_PATH_LITERAL("AccountManagerTokens.bin");
constexpr int kTokensFileMaxSizeInBytes = 100000; // ~100 KB
AccountManager::TokenMap LoadTokensFromDisk(
const base::FilePath& tokens_file_path) {
AccountManager::TokenMap tokens;
VLOG(1) << "AccountManager::LoadTokensFromDisk";
std::string token_file_data;
bool success = ReadFileToStringWithMaxSize(tokens_file_path, &token_file_data,
kTokensFileMaxSizeInBytes);
if (!success) {
LOG(ERROR) << "Failed to read tokens file";
return tokens;
}
chromeos::account_manager::Tokens tokens_proto;
success = tokens_proto.ParseFromString(token_file_data);
if (!success) {
LOG(ERROR) << "Failed to parse tokens from file";
return tokens;
}
tokens.insert(tokens_proto.login_scoped_tokens().begin(),
tokens_proto.login_scoped_tokens().end());
return tokens;
}
std::string GetSerializedTokens(const AccountManager::TokenMap& tokens) {
chromeos::account_manager::Tokens tokens_proto;
*tokens_proto.mutable_login_scoped_tokens() =
::google::protobuf::Map<std::string, std::string>(tokens.begin(),
tokens.end());
return tokens_proto.SerializeAsString();
}
} // namespace
AccountManager::AccountManager() : weak_factory_(this) {}
void AccountManager::Initialize(const base::FilePath& home_dir) {
Initialize(home_dir, base::CreateSequencedTaskRunnerWithTraits(
{base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
base::MayBlock()}));
}
void AccountManager::Initialize(
const base::FilePath& home_dir,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
VLOG(1) << "AccountManager::Initialize";
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (init_state_ != InitializationState::kNotStarted) {
// |Initialize| has already been called once. To help diagnose possible race
// conditions, check whether the |home_dir| parameter provided by the first
// invocation of |Initialize| matches the one it is currently being called
// with.
DCHECK_EQ(home_dir, writer_->path().DirName());
return;
}
init_state_ = InitializationState::kInProgress;
task_runner_ = task_runner;
writer_ = std::make_unique<base::ImportantFileWriter>(
home_dir.Append(kTokensFileName), task_runner_);
PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
base::BindOnce(&LoadTokensFromDisk, writer_->path()),
base::BindOnce(&AccountManager::InsertTokensAndRunInitializationCallbacks,
weak_factory_.GetWeakPtr()));
}
void AccountManager::InsertTokensAndRunInitializationCallbacks(
const AccountManager::TokenMap& tokens) {
VLOG(1) << "AccountManager::InsertTokensAndRunInitializationCallbacks";
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
tokens_.insert(tokens.begin(), tokens.end());
init_state_ = InitializationState::kInitialized;
for (auto& cb : initialization_callbacks_) {
std::move(cb).Run();
}
initialization_callbacks_.clear();
}
AccountManager::~AccountManager() {
// AccountManager is supposed to be used as a leaky global.
}
void AccountManager::RunOnInitialization(base::OnceClosure closure) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (init_state_ != InitializationState::kInitialized) {
initialization_callbacks_.emplace_back(std::move(closure));
} else {
std::move(closure).Run();
}
}
void AccountManager::GetAccounts(
base::OnceCallback<void(std::vector<std::string>)> callback) {
DCHECK_NE(init_state_, InitializationState::kNotStarted);
base::OnceClosure closure =
base::BindOnce(&AccountManager::GetAccountsInternal,
weak_factory_.GetWeakPtr(), std::move(callback));
RunOnInitialization(std::move(closure));
}
void AccountManager::GetAccountsInternal(
base::OnceCallback<void(std::vector<std::string>)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(init_state_, InitializationState::kInitialized);
std::vector<std::string> accounts;
accounts.reserve(tokens_.size());
for (auto& key_val : tokens_) {
accounts.emplace_back(key_val.first);
}
std::move(callback).Run(std::move(accounts));
}
void AccountManager::UpsertToken(const std::string& account_id,
const std::string& login_scoped_token) {
DCHECK_NE(init_state_, InitializationState::kNotStarted);
base::OnceClosure closure = base::BindOnce(
&AccountManager::UpsertTokenInternal, weak_factory_.GetWeakPtr(),
account_id, login_scoped_token);
RunOnInitialization(std::move(closure));
}
void AccountManager::UpsertTokenInternal(
const std::string& account_id,
const std::string& login_scoped_token) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(init_state_, InitializationState::kInitialized);
tokens_[account_id] = login_scoped_token;
PersistTokensAsync();
}
void AccountManager::PersistTokensAsync() {
// Schedule (immediately) a non-blocking write.
writer_->WriteNow(
std::make_unique<std::string>(GetSerializedTokens(tokens_)));
}
} // namespace chromeos
// Copyright 2018 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.
#ifndef CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MANAGER_H_
#define CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MANAGER_H_
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
namespace base {
class SequencedTaskRunner;
class ImportantFileWriter;
} // namespace base
namespace chromeos {
class AccountManager {
public:
// A map of account identifiers to login scoped tokens.
using TokenMap = std::unordered_map<std::string, std::string>;
// Note: |Initialize| MUST be called at least once on this object.
AccountManager();
~AccountManager();
// |home_dir| is the path of the Device Account's home directory (root of the
// user's cryptohome). This method MUST be called at least once.
void Initialize(const base::FilePath& home_dir);
// Gets (async) a list of account identifiers known to |AccountManager|.
void GetAccounts(base::OnceCallback<void(std::vector<std::string>)> callback);
// Updates or inserts an LST (Login Scoped Token), for the account
// corresponding to the given account id.
void UpsertToken(const std::string& account_id,
const std::string& login_scoped_token);
private:
enum InitializationState {
kNotStarted, // Initialize has not been called
kInProgress, // Initialize has been called but not completed
kInitialized, // Initialization was successfully completed
};
friend class AccountManagerTest;
FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestInitialization);
FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestUpsert);
FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestPersistence);
// Initializes |AccountManager| with the provided |task_runner| and location
// of the user's home directory.
void Initialize(const base::FilePath& home_dir,
scoped_refptr<base::SequencedTaskRunner> task_runner);
// Reads tokens from |tokens| and inserts them in |tokens_| and runs all
// callbacks waiting on |AccountManager| initialization.
void InsertTokensAndRunInitializationCallbacks(const TokenMap& tokens);
// Accepts a closure and runs it immediately if |AccountManager| has already
// been initialized, otherwise saves the |closure| for running later, when the
// class is initialized.
void RunOnInitialization(base::OnceClosure closure);
// Does the actual work of getting a list of accounts. Assumes that
// |AccountManager| initialization (|init_state_|) is complete.
void GetAccountsInternal(
base::OnceCallback<void(std::vector<std::string>)> callback);
// Does the actual work of updating or inserting tokens. Assumes that
// |AccountManager| initialization (|init_state_|) is complete.
void UpsertTokenInternal(const std::string& account_id,
const std::string& login_scoped_token);
// Persists (async) the current state of |tokens_| on disk.
void PersistTokensAsync();
// Status of this object's initialization.
InitializationState init_state_ = InitializationState::kNotStarted;
// A task runner for disk I/O.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
std::unique_ptr<base::ImportantFileWriter> writer_;
// A map of account ids to login scoped tokens.
TokenMap tokens_;
// Callbacks waiting on class initialization (|init_state_|).
std::vector<base::OnceClosure> initialization_callbacks_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<AccountManager> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AccountManager);
};
} // namespace chromeos
#endif // CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MANAGER_H_
// Copyright 2018 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 "chromeos/account_manager/account_manager.h"
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
class AccountManagerTest : public testing::Test {
public:
AccountManagerTest() = default;
~AccountManagerTest() override {}
protected:
void SetUp() override {
ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
account_manager_ = std::make_unique<AccountManager>();
account_manager_->Initialize(tmp_dir_.GetPath(),
base::SequencedTaskRunnerHandle::Get());
}
// Check base/test/scoped_task_environment.h. This must be the first member /
// declared before any member that cares about tasks.
base::test::ScopedTaskEnvironment scoped_task_environment_;
base::ScopedTempDir tmp_dir_;
std::unique_ptr<AccountManager> account_manager_;
private:
DISALLOW_COPY_AND_ASSIGN(AccountManagerTest);
};
TEST_F(AccountManagerTest, TestInitialization) {
AccountManager account_manager;
EXPECT_EQ(account_manager.init_state_,
AccountManager::InitializationState::kNotStarted);
account_manager.Initialize(tmp_dir_.GetPath(),
base::SequencedTaskRunnerHandle::Get());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(account_manager.init_state_,
AccountManager::InitializationState::kInitialized);
}
TEST_F(AccountManagerTest, TestUpsert) {
account_manager_->UpsertToken("abc", "123");
std::vector<std::string> accounts;
base::RunLoop run_loop;
account_manager_->GetAccounts(base::BindOnce(
[](std::vector<std::string>* accounts, base::OnceClosure quit_closure,
std::vector<std::string> stored_accounts) -> void {
*accounts = stored_accounts;
std::move(quit_closure).Run();
},
base::Unretained(&accounts), run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(1UL, accounts.size());
EXPECT_EQ("abc", accounts[0]);
}
TEST_F(AccountManagerTest, TestPersistence) {
account_manager_->UpsertToken("abc", "123");
base::RunLoop().RunUntilIdle();
account_manager_ = std::make_unique<AccountManager>();
account_manager_->Initialize(tmp_dir_.GetPath(),
base::SequencedTaskRunnerHandle::Get());
std::vector<std::string> accounts;
base::RunLoop run_loop;
account_manager_->GetAccounts(base::BindOnce(
[](std::vector<std::string>* accounts, base::OnceClosure quit_closure,
std::vector<std::string> stored_accounts) -> void {
*accounts = stored_accounts;
std::move(quit_closure).Run();
},
base::Unretained(&accounts), run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(1UL, accounts.size());
EXPECT_EQ("abc", accounts[0]);
}
} // namespace chromeos
// Copyright 2018 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.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package chromeos.account_manager;
message Tokens {
// A mapping from GAIA id to a Login Scoped (Refresh) Token
map<string, string> login_scoped_tokens = 1;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment