This source file includes following definitions.
- OnWildcardCheckCompleted
- policy_fetch_timeout_
- Connect
- OnAccessTokenAvailable
- IsClientRegistered
- EnableWildcardLoginCheck
- Shutdown
- IsInitializationComplete
- OnInitializationCompleted
- OnPolicyFetched
- OnRegistrationStateChanged
- OnClientError
- OnComponentCloudPolicyUpdated
- FetchPolicyOAuthTokenUsingSigninProfile
- OnOAuth2PolicyTokenFetched
- OnInitialPolicyFetchComplete
- OnBlockingFetchTimeout
- CancelWaitForPolicyFetch
- StartRefreshSchedulerIfReady
#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/sequenced_task_runner.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
#include "chrome/browser/chromeos/policy/wildcard_login_checker.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/common/chrome_content_client.h"
#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/system_policy_request_context.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"
namespace em = enterprise_management;
namespace policy {
namespace {
const char kUMADelayInitialization[] =
"Enterprise.UserPolicyChromeOS.DelayInitialization";
const char kUMAInitialFetchClientError[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.ClientError";
const char kUMAInitialFetchDelayClientRegister[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.DelayClientRegister";
const char kUMAInitialFetchDelayOAuth2Token[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.DelayOAuth2Token";
const char kUMAInitialFetchDelayPolicyFetch[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.DelayPolicyFetch";
const char kUMAInitialFetchDelayTotal[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.DelayTotal";
const char kUMAInitialFetchOAuth2Error[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2Error";
const char kUMAInitialFetchOAuth2NetworkError[] =
"Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2NetworkError";
void OnWildcardCheckCompleted(const std::string& username,
WildcardLoginChecker::Result result) {
if (result == WildcardLoginChecker::RESULT_BLOCKED) {
LOG(ERROR) << "Online wildcard login check failed, terminating session.";
chromeos::UserManager::Get()->RemoveUserFromList(username);
chrome::AttemptUserExit();
}
}
}
UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
scoped_ptr<CloudPolicyStore> store,
scoped_ptr<CloudExternalDataManager> external_data_manager,
const base::FilePath& component_policy_cache_path,
bool wait_for_policy_fetch,
base::TimeDelta initial_policy_fetch_timeout,
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
const scoped_refptr<base::SequencedTaskRunner>& file_task_runner,
const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
: CloudPolicyManager(
PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
store.get(),
task_runner,
file_task_runner,
io_task_runner),
store_(store.Pass()),
external_data_manager_(external_data_manager.Pass()),
component_policy_cache_path_(component_policy_cache_path),
wait_for_policy_fetch_(wait_for_policy_fetch),
policy_fetch_timeout_(false, false) {
time_init_started_ = base::Time::Now();
if (wait_for_policy_fetch_) {
policy_fetch_timeout_.Start(
FROM_HERE,
initial_policy_fetch_timeout,
base::Bind(&UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout,
base::Unretained(this)));
}
}
UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {}
void UserCloudPolicyManagerChromeOS::Connect(
PrefService* local_state,
DeviceManagementService* device_management_service,
scoped_refptr<net::URLRequestContextGetter> system_request_context,
UserAffiliation user_affiliation) {
DCHECK(device_management_service);
DCHECK(local_state);
local_state_ = local_state;
scoped_refptr<net::URLRequestContextGetter> request_context;
if (system_request_context) {
request_context = new SystemPolicyRequestContext(
system_request_context, GetUserAgent());
}
scoped_ptr<CloudPolicyClient> cloud_policy_client(
new CloudPolicyClient(std::string(), std::string(),
kPolicyVerificationKeyHash, user_affiliation,
NULL, device_management_service,
request_context));
core()->Connect(cloud_policy_client.Pass());
client()->AddObserver(this);
external_data_manager_->Connect(request_context);
CreateComponentCloudPolicyService(component_policy_cache_path_,
request_context);
if (service()->IsInitializationComplete()) {
OnInitializationCompleted(service());
} else {
service()->AddObserver(this);
}
}
void UserCloudPolicyManagerChromeOS::OnAccessTokenAvailable(
const std::string& access_token) {
access_token_ = access_token;
if (!wildcard_username_.empty()) {
wildcard_login_checker_.reset(new WildcardLoginChecker());
wildcard_login_checker_->StartWithAccessToken(
access_token,
base::Bind(&OnWildcardCheckCompleted, wildcard_username_));
}
if (service() && service()->IsInitializationComplete() &&
client() && !client()->is_registered()) {
OnOAuth2PolicyTokenFetched(
access_token, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
}
}
bool UserCloudPolicyManagerChromeOS::IsClientRegistered() const {
return client() && client()->is_registered();
}
void UserCloudPolicyManagerChromeOS::EnableWildcardLoginCheck(
const std::string& username) {
DCHECK(access_token_.empty());
wildcard_username_ = username;
}
void UserCloudPolicyManagerChromeOS::Shutdown() {
if (client())
client()->RemoveObserver(this);
if (service())
service()->RemoveObserver(this);
token_fetcher_.reset();
external_data_manager_->Disconnect();
CloudPolicyManager::Shutdown();
}
bool UserCloudPolicyManagerChromeOS::IsInitializationComplete(
PolicyDomain domain) const {
if (!CloudPolicyManager::IsInitializationComplete(domain))
return false;
if (domain == POLICY_DOMAIN_CHROME)
return !wait_for_policy_fetch_;
return true;
}
void UserCloudPolicyManagerChromeOS::OnInitializationCompleted(
CloudPolicyService* cloud_policy_service) {
DCHECK_EQ(service(), cloud_policy_service);
cloud_policy_service->RemoveObserver(this);
time_init_completed_ = base::Time::Now();
UMA_HISTOGRAM_MEDIUM_TIMES(kUMADelayInitialization,
time_init_completed_ - time_init_started_);
if (!client()->is_registered()) {
if (wait_for_policy_fetch_) {
FetchPolicyOAuthTokenUsingSigninProfile();
} else if (!access_token_.empty()) {
OnAccessTokenAvailable(access_token_);
}
}
if (!wait_for_policy_fetch_) {
StartRefreshSchedulerIfReady();
}
}
void UserCloudPolicyManagerChromeOS::OnPolicyFetched(
CloudPolicyClient* client) {
}
void UserCloudPolicyManagerChromeOS::OnRegistrationStateChanged(
CloudPolicyClient* cloud_policy_client) {
DCHECK_EQ(client(), cloud_policy_client);
if (wait_for_policy_fetch_) {
time_client_registered_ = base::Time::Now();
if (!time_token_available_.is_null()) {
UMA_HISTOGRAM_MEDIUM_TIMES(
kUMAInitialFetchDelayClientRegister,
time_client_registered_ - time_token_available_);
}
if (client()->is_registered()) {
service()->RefreshPolicy(
base::Bind(
&UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete,
base::Unretained(this)));
} else {
CancelWaitForPolicyFetch();
}
}
}
void UserCloudPolicyManagerChromeOS::OnClientError(
CloudPolicyClient* cloud_policy_client) {
DCHECK_EQ(client(), cloud_policy_client);
if (wait_for_policy_fetch_) {
UMA_HISTOGRAM_SPARSE_SLOWLY(kUMAInitialFetchClientError,
cloud_policy_client->status());
}
CancelWaitForPolicyFetch();
}
void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() {
CloudPolicyManager::OnComponentCloudPolicyUpdated();
StartRefreshSchedulerIfReady();
}
void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingSigninProfile() {
scoped_refptr<net::URLRequestContextGetter> signin_context;
Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile();
if (signin_profile)
signin_context = signin_profile->GetRequestContext();
if (!signin_context.get()) {
LOG(ERROR) << "No signin Profile for policy oauth token fetch!";
OnOAuth2PolicyTokenFetched(
std::string(), GoogleServiceAuthError(GoogleServiceAuthError::NONE));
return;
}
token_fetcher_.reset(new PolicyOAuth2TokenFetcher(
signin_context.get(),
g_browser_process->system_request_context(),
base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched,
base::Unretained(this))));
token_fetcher_->Start();
}
void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched(
const std::string& policy_token,
const GoogleServiceAuthError& error) {
DCHECK(!client()->is_registered());
time_token_available_ = base::Time::Now();
if (wait_for_policy_fetch_) {
UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayOAuth2Token,
time_token_available_ - time_init_completed_);
}
if (error.state() == GoogleServiceAuthError::NONE) {
client()->Register(em::DeviceRegisterRequest::USER, policy_token,
std::string(), false, std::string(), std::string());
} else {
CancelWaitForPolicyFetch();
UMA_HISTOGRAM_ENUMERATION(kUMAInitialFetchOAuth2Error,
error.state(),
GoogleServiceAuthError::NUM_STATES);
if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
UMA_HISTOGRAM_SPARSE_SLOWLY(kUMAInitialFetchOAuth2NetworkError,
error.network_error());
}
}
token_fetcher_.reset();
}
void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete(
bool success) {
const base::Time now = base::Time::Now();
UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayPolicyFetch,
now - time_client_registered_);
UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayTotal,
now - time_init_started_);
CancelWaitForPolicyFetch();
}
void UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout() {
if (!wait_for_policy_fetch_)
return;
LOG(WARNING) << "Timed out while waiting for the initial policy fetch. "
<< "The first session will start without policy.";
CancelWaitForPolicyFetch();
}
void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() {
if (!wait_for_policy_fetch_)
return;
wait_for_policy_fetch_ = false;
policy_fetch_timeout_.Stop();
CheckAndPublishPolicy();
StartRefreshSchedulerIfReady();
}
void UserCloudPolicyManagerChromeOS::StartRefreshSchedulerIfReady() {
if (core()->refresh_scheduler())
return;
if (wait_for_policy_fetch_)
return;
if (!service() || !local_state_)
return;
if (component_policy_service() &&
!component_policy_service()->is_initialized()) {
return;
}
core()->StartRefreshScheduler();
core()->TrackRefreshDelayPref(local_state_,
policy_prefs::kUserPolicyRefreshRate);
}
}