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

Unified Diff: chrome/browser/chromeos/policy/active_directory_policy_manager.cc

Issue 2954293002: Chromad: Prevent session from starting without policy (Closed)
Patch Set: Comment fixes Created 3 years, 5 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: chrome/browser/chromeos/policy/active_directory_policy_manager.cc
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
index 195140d9e972a2b2efc033267aa4707a4a941935..fc1f40020a4d6a3e080b96a47ccd5d2f7af2ba84 100644
--- a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
+++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
@@ -31,17 +31,24 @@ ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() {}
std::unique_ptr<ActiveDirectoryPolicyManager>
ActiveDirectoryPolicyManager::CreateForDevicePolicy(
std::unique_ptr<CloudPolicyStore> store) {
- return base::WrapUnique(
- new ActiveDirectoryPolicyManager(EmptyAccountId(), std::move(store)));
+ // Can't use MakeUnique<> because the constructor is private.
+ return base::WrapUnique(new ActiveDirectoryPolicyManager(
+ EmptyAccountId(), false, base::TimeDelta(), base::OnceClosure(),
+ std::move(store)));
}
// static
std::unique_ptr<ActiveDirectoryPolicyManager>
ActiveDirectoryPolicyManager::CreateForUserPolicy(
const AccountId& account_id,
+ bool wait_for_policy_fetch,
+ base::TimeDelta initial_policy_fetch_timeout,
+ base::OnceClosure exit_session,
std::unique_ptr<CloudPolicyStore> store) {
- return base::WrapUnique(
- new ActiveDirectoryPolicyManager(account_id, std::move(store)));
+ // Can't use MakeUnique<> because the constructor is private.
+ return base::WrapUnique(new ActiveDirectoryPolicyManager(
+ account_id, wait_for_policy_fetch, initial_policy_fetch_timeout,
+ std::move(exit_session), std::move(store)));
}
void ActiveDirectoryPolicyManager::Init(SchemaRegistry* registry) {
@@ -70,10 +77,13 @@ void ActiveDirectoryPolicyManager::Shutdown() {
bool ActiveDirectoryPolicyManager::IsInitializationComplete(
PolicyDomain domain) const {
+ if (waiting_for_initial_policy_fetch_) {
+ return false;
+ }
if (domain == POLICY_DOMAIN_CHROME) {
return store_->is_initialized();
}
- return true;
+ return false;
emaxx 2017/07/12 20:18:19 Not sure I understand this change: now the compone
Thiemo Nagel 2017/07/14 12:18:55 Since we don't support component policy for Chroma
Thiemo Nagel 2017/07/14 12:21:29 I've changed it back.
}
void ActiveDirectoryPolicyManager::RefreshPolicies() {
@@ -84,6 +94,9 @@ void ActiveDirectoryPolicyManager::OnStoreLoaded(
CloudPolicyStore* cloud_policy_store) {
DCHECK_EQ(store_.get(), cloud_policy_store);
PublishPolicy();
+ if (fetch_ever_completed_) {
+ CancelWaitForPolicy(fetch_ever_succeeded_ /* success */);
+ }
}
void ActiveDirectoryPolicyManager::OnStoreError(
@@ -93,12 +106,39 @@ void ActiveDirectoryPolicyManager::OnStoreError(
// complete on the ConfigurationPolicyProvider interface. Technically, this is
// only required on the first load, but doesn't hurt in any case.
PublishPolicy();
+ if (fetch_ever_completed_) {
+ CancelWaitForPolicy(false /* success */);
+ }
+}
+
+void ActiveDirectoryPolicyManager::ForceTimeoutForTest() {
+ DCHECK(initial_policy_timeout_.IsRunning());
+ // Stop the timer to mimic what happens when a real timer fires, then invoke
+ // the timer callback directly.
+ initial_policy_timeout_.Stop();
+ OnBlockingFetchTimeout();
}
ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager(
const AccountId& account_id,
+ bool wait_for_policy_fetch,
+ base::TimeDelta initial_policy_fetch_timeout,
+ base::OnceClosure exit_session,
std::unique_ptr<CloudPolicyStore> store)
- : account_id_(account_id), store_(std::move(store)) {}
+ : account_id_(account_id),
+ waiting_for_initial_policy_fetch_(wait_for_policy_fetch),
+ exit_session_(std::move(exit_session)),
+ store_(std::move(store)) {
+ DCHECK(!(account_id == EmptyAccountId() && wait_for_policy_fetch));
+ DCHECK_NE(wait_for_policy_fetch, initial_policy_fetch_timeout.is_zero());
+ initial_policy_fetch_may_fail_ = !initial_policy_fetch_timeout.is_max();
+ if (wait_for_policy_fetch && !initial_policy_fetch_timeout.is_max()) {
+ initial_policy_timeout_.Start(
+ FROM_HERE, initial_policy_fetch_timeout,
+ base::Bind(&ActiveDirectoryPolicyManager::OnBlockingFetchTimeout,
+ base::Unretained(this)));
emaxx 2017/07/12 20:18:19 nit: Ideally we'd have this documented why Unretai
Thiemo Nagel 2017/07/14 12:18:55 Good point. It used to be safe because the timer w
+ }
+}
void ActiveDirectoryPolicyManager::PublishPolicy() {
if (!store_->is_initialized()) {
@@ -133,12 +173,60 @@ void ActiveDirectoryPolicyManager::DoFetch(
}
void ActiveDirectoryPolicyManager::OnPolicyFetched(bool success) {
- if (!success) {
+ fetch_ever_completed_ = true;
+ if (success) {
+ fetch_ever_succeeded_ = true;
+ } else {
LOG(ERROR) << "Active Directory policy fetch failed.";
+ if (store_->is_initialized()) {
+ CancelWaitForPolicy(false /* success */);
+ }
}
// Load independently of success or failure to keep up to date with whatever
// has happened on the authpolicyd / session manager side.
store_->Load();
}
+void ActiveDirectoryPolicyManager::OnBlockingFetchTimeout() {
+ DCHECK(waiting_for_initial_policy_fetch_);
+ LOG(WARNING) << "Timed out while waiting for the policy fetch. "
+ << "The session will start with the cached policy.";
+ CancelWaitForPolicy(false);
+}
+
+void ActiveDirectoryPolicyManager::CancelWaitForPolicy(bool success) {
+ if (!waiting_for_initial_policy_fetch_)
+ return;
+
+ initial_policy_timeout_.Stop();
+
+ // If there was an error, and we don't want to allow profile initialization
+ // to go forward after a failed policy fetch, then just return (profile
+ // initialization will not complete).
+ // TODO(tnagel): Maybe add code to retry policy fetching?
+ if (!store_->has_policy()) {
emaxx 2017/07/12 20:18:20 I'm quite confused about complexity of the state m
Thiemo Nagel 2017/07/14 12:18:55 After a lot of offline discussion: It's hard to si
+ // If there's no policy at all (not even cached) we can't continue.
+ LOG(ERROR) << "Policy could not be obtained. "
+ << "Aborting profile initialization";
+ if (exit_session_) {
+ std::move(exit_session_).Run();
+ }
+ return;
+ }
+ if (!success && !initial_policy_fetch_may_fail_) {
+ LOG(ERROR) << "Policy fetch failed for the user. "
+ << "Aborting profile initialization";
+ if (exit_session_) {
+ std::move(exit_session_).Run();
+ }
+ return;
+ }
+
+ waiting_for_initial_policy_fetch_ = false;
+
+ // Publish policy (even though it hasn't changed) in order to signal load
+ // complete on the ConfigurationPolicyProvider interface.
+ PublishPolicy();
+}
+
} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698