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

Unified Diff: chrome/browser/policy/cloud/device_management_service.cc

Issue 109743002: Move policy code into components/policy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moar fixes Created 7 years 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/policy/cloud/device_management_service.cc
diff --git a/chrome/browser/policy/cloud/device_management_service.cc b/chrome/browser/policy/cloud/device_management_service.cc
deleted file mode 100644
index 51b3a9042bb2e38f800144fca2abfedeedc0ede7..0000000000000000000000000000000000000000
--- a/chrome/browser/policy/cloud/device_management_service.cc
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright (c) 2012 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 "chrome/browser/policy/cloud/device_management_service.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "net/base/escape.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_response_headers.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request_status.h"
-#include "url/gurl.h"
-
-namespace em = enterprise_management;
-
-namespace policy {
-
-namespace {
-
-const char kPostContentType[] = "application/protobuf";
-
-const char kServiceTokenAuthHeader[] = "Authorization: GoogleLogin auth=";
-const char kDMTokenAuthHeader[] = "Authorization: GoogleDMToken token=";
-
-// Number of times to retry on ERR_NETWORK_CHANGED errors.
-const int kMaxNetworkChangedRetries = 3;
-
-// HTTP Error Codes of the DM Server with their concrete meanings in the context
-// of the DM Server communication.
-const int kSuccess = 200;
-const int kInvalidArgument = 400;
-const int kInvalidAuthCookieOrDMToken = 401;
-const int kMissingLicenses = 402;
-const int kDeviceManagementNotAllowed = 403;
-const int kInvalidURL = 404; // This error is not coming from the GFE.
-const int kInvalidSerialNumber = 405;
-const int kDeviceIdConflict = 409;
-const int kDeviceNotFound = 410;
-const int kPendingApproval = 412;
-const int kInternalServerError = 500;
-const int kServiceUnavailable = 503;
-const int kPolicyNotFound = 902; // This error is not sent as HTTP status code.
-
-bool IsProxyError(const net::URLRequestStatus status) {
- switch (status.error()) {
- case net::ERR_PROXY_CONNECTION_FAILED:
- case net::ERR_TUNNEL_CONNECTION_FAILED:
- case net::ERR_PROXY_AUTH_UNSUPPORTED:
- case net::ERR_HTTPS_PROXY_TUNNEL_RESPONSE:
- case net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED:
- case net::ERR_PROXY_CERTIFICATE_INVALID:
- case net::ERR_SOCKS_CONNECTION_FAILED:
- case net::ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
- return true;
- }
- return false;
-}
-
-bool IsProtobufMimeType(const net::URLFetcher* fetcher) {
- return fetcher->GetResponseHeaders()->HasHeaderValue(
- "content-type", "application/x-protobuffer");
-}
-
-bool FailedWithProxy(const net::URLFetcher* fetcher) {
- if ((fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY) != 0) {
- // The request didn't use a proxy.
- return false;
- }
-
- if (!fetcher->GetStatus().is_success() &&
- IsProxyError(fetcher->GetStatus())) {
- LOG(WARNING) << "Proxy failed while contacting dmserver.";
- return true;
- }
-
- if (fetcher->GetStatus().is_success() &&
- fetcher->GetResponseCode() == kSuccess &&
- fetcher->WasFetchedViaProxy() &&
- !IsProtobufMimeType(fetcher)) {
- // The proxy server can be misconfigured but pointing to an existing
- // server that replies to requests. Try to recover if a successful
- // request that went through a proxy returns an unexpected mime type.
- LOG(WARNING) << "Got bad mime-type in response from dmserver that was "
- << "fetched via a proxy.";
- return true;
- }
-
- return false;
-}
-
-const char* UserAffiliationToString(UserAffiliation affiliation) {
- switch (affiliation) {
- case USER_AFFILIATION_MANAGED:
- return dm_protocol::kValueUserAffiliationManaged;
- case USER_AFFILIATION_NONE:
- return dm_protocol::kValueUserAffiliationNone;
- }
- NOTREACHED() << "Invalid user affiliation " << affiliation;
- return dm_protocol::kValueUserAffiliationNone;
-}
-
-const char* JobTypeToRequestType(DeviceManagementRequestJob::JobType type) {
- switch (type) {
- case DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT:
- return dm_protocol::kValueRequestAutoEnrollment;
- case DeviceManagementRequestJob::TYPE_REGISTRATION:
- return dm_protocol::kValueRequestRegister;
- case DeviceManagementRequestJob::TYPE_POLICY_FETCH:
- return dm_protocol::kValueRequestPolicy;
- case DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH:
- return dm_protocol::kValueRequestApiAuthorization;
- case DeviceManagementRequestJob::TYPE_UNREGISTRATION:
- return dm_protocol::kValueRequestUnregister;
- case DeviceManagementRequestJob::TYPE_UPLOAD_CERTIFICATE:
- return dm_protocol::kValueRequestUploadCertificate;
- }
- NOTREACHED() << "Invalid job type " << type;
- return "";
-}
-
-} // namespace
-
-// Request job implementation used with DeviceManagementService.
-class DeviceManagementRequestJobImpl : public DeviceManagementRequestJob {
- public:
- DeviceManagementRequestJobImpl(
- JobType type,
- const std::string& agent_parameter,
- const std::string& platform_parameter,
- DeviceManagementService* service,
- net::URLRequestContextGetter* request_context);
- virtual ~DeviceManagementRequestJobImpl();
-
- // Handles the URL request response.
- void HandleResponse(const net::URLRequestStatus& status,
- int response_code,
- const net::ResponseCookies& cookies,
- const std::string& data);
-
- // Gets the URL to contact.
- GURL GetURL(const std::string& server_url);
-
- // Configures the fetcher, setting up payload and headers.
- void ConfigureRequest(net::URLFetcher* fetcher);
-
- // Returns true if this job should be retried. |fetcher| has just completed,
- // and can be inspected to determine if the request failed and should be
- // retried.
- bool ShouldRetry(const net::URLFetcher* fetcher);
-
- // Invoked right before retrying this job.
- void PrepareRetry();
-
- protected:
- // DeviceManagementRequestJob:
- virtual void Run() OVERRIDE;
-
- private:
- // Invokes the callback with the given error code.
- void ReportError(DeviceManagementStatus code);
-
- // Pointer to the service this job is associated with.
- DeviceManagementService* service_;
-
- // Whether the BYPASS_PROXY flag should be set by ConfigureRequest().
- bool bypass_proxy_;
-
- // Number of times that this job has been retried due to ERR_NETWORK_CHANGED.
- int retries_count_;
-
- // The request context to use for this job.
- net::URLRequestContextGetter* request_context_;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceManagementRequestJobImpl);
-};
-
-DeviceManagementRequestJobImpl::DeviceManagementRequestJobImpl(
- JobType type,
- const std::string& agent_parameter,
- const std::string& platform_parameter,
- DeviceManagementService* service,
- net::URLRequestContextGetter* request_context)
- : DeviceManagementRequestJob(type, agent_parameter, platform_parameter),
- service_(service),
- bypass_proxy_(false),
- retries_count_(0),
- request_context_(request_context) {}
-
-DeviceManagementRequestJobImpl::~DeviceManagementRequestJobImpl() {
- service_->RemoveJob(this);
-}
-
-void DeviceManagementRequestJobImpl::Run() {
- service_->AddJob(this);
-}
-
-void DeviceManagementRequestJobImpl::HandleResponse(
- const net::URLRequestStatus& status,
- int response_code,
- const net::ResponseCookies& cookies,
- const std::string& data) {
- if (status.status() != net::URLRequestStatus::SUCCESS) {
- LOG(WARNING) << "DMServer request failed, status: " << status.status()
- << ", error: " << status.error();
- em::DeviceManagementResponse dummy_response;
- callback_.Run(DM_STATUS_REQUEST_FAILED, status.error(), dummy_response);
- return;
- }
-
- if (response_code != kSuccess)
- LOG(WARNING) << "DMServer sent an error response: " << response_code;
-
- switch (response_code) {
- case kSuccess: {
- em::DeviceManagementResponse response;
- if (!response.ParseFromString(data)) {
- ReportError(DM_STATUS_RESPONSE_DECODING_ERROR);
- return;
- }
- callback_.Run(DM_STATUS_SUCCESS, net::OK, response);
- return;
- }
- case kInvalidArgument:
- ReportError(DM_STATUS_REQUEST_INVALID);
- return;
- case kInvalidAuthCookieOrDMToken:
- ReportError(DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID);
- return;
- case kMissingLicenses:
- ReportError(DM_STATUS_SERVICE_MISSING_LICENSES);
- return;
- case kDeviceManagementNotAllowed:
- ReportError(DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED);
- return;
- case kPendingApproval:
- ReportError(DM_STATUS_SERVICE_ACTIVATION_PENDING);
- return;
- case kInvalidURL:
- case kInternalServerError:
- case kServiceUnavailable:
- ReportError(DM_STATUS_TEMPORARY_UNAVAILABLE);
- return;
- case kDeviceNotFound:
- ReportError(DM_STATUS_SERVICE_DEVICE_NOT_FOUND);
- return;
- case kPolicyNotFound:
- ReportError(DM_STATUS_SERVICE_POLICY_NOT_FOUND);
- return;
- case kInvalidSerialNumber:
- ReportError(DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER);
- return;
- case kDeviceIdConflict:
- ReportError(DM_STATUS_SERVICE_DEVICE_ID_CONFLICT);
- return;
- default:
- // Handle all unknown 5xx HTTP error codes as temporary and any other
- // unknown error as one that needs more time to recover.
- if (response_code >= 500 && response_code <= 599)
- ReportError(DM_STATUS_TEMPORARY_UNAVAILABLE);
- else
- ReportError(DM_STATUS_HTTP_STATUS_ERROR);
- return;
- }
-}
-
-GURL DeviceManagementRequestJobImpl::GetURL(
- const std::string& server_url) {
- std::string result(server_url);
- result += '?';
- for (ParameterMap::const_iterator entry(query_params_.begin());
- entry != query_params_.end();
- ++entry) {
- if (entry != query_params_.begin())
- result += '&';
- result += net::EscapeQueryParamValue(entry->first, true);
- result += '=';
- result += net::EscapeQueryParamValue(entry->second, true);
- }
- return GURL(result);
-}
-
-void DeviceManagementRequestJobImpl::ConfigureRequest(
- net::URLFetcher* fetcher) {
- fetcher->SetRequestContext(request_context_);
- fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DISABLE_CACHE |
- (bypass_proxy_ ? net::LOAD_BYPASS_PROXY : 0));
- std::string payload;
- CHECK(request_.SerializeToString(&payload));
- fetcher->SetUploadData(kPostContentType, payload);
- std::string extra_headers;
- if (!gaia_token_.empty())
- extra_headers += kServiceTokenAuthHeader + gaia_token_ + "\n";
- if (!dm_token_.empty())
- extra_headers += kDMTokenAuthHeader + dm_token_ + "\n";
- fetcher->SetExtraRequestHeaders(extra_headers);
-}
-
-bool DeviceManagementRequestJobImpl::ShouldRetry(
- const net::URLFetcher* fetcher) {
- if (FailedWithProxy(fetcher) && !bypass_proxy_) {
- // Retry the job if it failed due to a broken proxy, by bypassing the
- // proxy on the next try.
- bypass_proxy_ = true;
- return true;
- }
-
- // Early device policy fetches on ChromeOS and Auto-Enrollment checks are
- // often interrupted during ChromeOS startup when network change notifications
- // are sent. Allowing the fetcher to retry once after that is enough to
- // recover; allow it to retry up to 3 times just in case.
- if (fetcher->GetStatus().error() == net::ERR_NETWORK_CHANGED &&
- retries_count_ < kMaxNetworkChangedRetries) {
- ++retries_count_;
- return true;
- }
-
- // The request didn't fail, or the limit of retry attempts has been reached;
- // forward the result to the job owner.
- return false;
-}
-
-void DeviceManagementRequestJobImpl::PrepareRetry() {
- if (!retry_callback_.is_null())
- retry_callback_.Run(this);
-}
-
-void DeviceManagementRequestJobImpl::ReportError(DeviceManagementStatus code) {
- em::DeviceManagementResponse dummy_response;
- callback_.Run(code, net::OK, dummy_response);
-}
-
-DeviceManagementRequestJob::~DeviceManagementRequestJob() {}
-
-void DeviceManagementRequestJob::SetGaiaToken(const std::string& gaia_token) {
- gaia_token_ = gaia_token;
-}
-
-void DeviceManagementRequestJob::SetOAuthToken(const std::string& oauth_token) {
- AddParameter(dm_protocol::kParamOAuthToken, oauth_token);
-}
-
-void DeviceManagementRequestJob::SetUserAffiliation(
- UserAffiliation user_affiliation) {
- AddParameter(dm_protocol::kParamUserAffiliation,
- UserAffiliationToString(user_affiliation));
-}
-
-void DeviceManagementRequestJob::SetDMToken(const std::string& dm_token) {
- dm_token_ = dm_token;
-}
-
-void DeviceManagementRequestJob::SetClientID(const std::string& client_id) {
- AddParameter(dm_protocol::kParamDeviceID, client_id);
-}
-
-em::DeviceManagementRequest* DeviceManagementRequestJob::GetRequest() {
- return &request_;
-}
-
-DeviceManagementRequestJob::DeviceManagementRequestJob(
- JobType type,
- const std::string& agent_parameter,
- const std::string& platform_parameter) {
- AddParameter(dm_protocol::kParamRequest, JobTypeToRequestType(type));
- AddParameter(dm_protocol::kParamDeviceType, dm_protocol::kValueDeviceType);
- AddParameter(dm_protocol::kParamAppType, dm_protocol::kValueAppType);
- AddParameter(dm_protocol::kParamAgent, agent_parameter);
- AddParameter(dm_protocol::kParamPlatform, platform_parameter);
-}
-
-void DeviceManagementRequestJob::SetRetryCallback(
- const RetryCallback& retry_callback) {
- retry_callback_ = retry_callback;
-}
-
-void DeviceManagementRequestJob::Start(const Callback& callback) {
- callback_ = callback;
- Run();
-}
-
-void DeviceManagementRequestJob::AddParameter(const std::string& name,
- const std::string& value) {
- query_params_.push_back(std::make_pair(name, value));
-}
-
-// A random value that other fetchers won't likely use.
-const int DeviceManagementService::kURLFetcherID = 0xde71ce1d;
-
-DeviceManagementService::~DeviceManagementService() {
- // All running jobs should have been cancelled by now.
- DCHECK(pending_jobs_.empty());
- DCHECK(queued_jobs_.empty());
-}
-
-DeviceManagementRequestJob* DeviceManagementService::CreateJob(
- DeviceManagementRequestJob::JobType type,
- net::URLRequestContextGetter* request_context) {
- return new DeviceManagementRequestJobImpl(
- type,
- configuration_->GetAgentParameter(),
- configuration_->GetPlatformParameter(),
- this,
- request_context);
-}
-
-void DeviceManagementService::ScheduleInitialization(int64 delay_milliseconds) {
- if (initialized_)
- return;
- base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&DeviceManagementService::Initialize,
- weak_ptr_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(delay_milliseconds));
-}
-
-void DeviceManagementService::Initialize() {
- if (initialized_)
- return;
- initialized_ = true;
-
- while (!queued_jobs_.empty()) {
- StartJob(queued_jobs_.front());
- queued_jobs_.pop_front();
- }
-}
-
-void DeviceManagementService::Shutdown() {
- for (JobFetcherMap::iterator job(pending_jobs_.begin());
- job != pending_jobs_.end();
- ++job) {
- delete job->first;
- queued_jobs_.push_back(job->second);
- }
- pending_jobs_.clear();
-}
-
-DeviceManagementService::DeviceManagementService(
- scoped_ptr<Configuration> configuration)
- : configuration_(configuration.Pass()),
- initialized_(false),
- weak_ptr_factory_(this) {
- DCHECK(configuration_);
-}
-
-void DeviceManagementService::StartJob(DeviceManagementRequestJobImpl* job) {
- std::string server_url = GetServerURL();
- net::URLFetcher* fetcher = net::URLFetcher::Create(
- kURLFetcherID, job->GetURL(server_url), net::URLFetcher::POST, this);
- job->ConfigureRequest(fetcher);
- pending_jobs_[fetcher] = job;
- fetcher->Start();
-}
-
-std::string DeviceManagementService::GetServerURL() {
- return configuration_->GetServerUrl();
-}
-
-void DeviceManagementService::OnURLFetchComplete(
- const net::URLFetcher* source) {
- JobFetcherMap::iterator entry(pending_jobs_.find(source));
- if (entry == pending_jobs_.end()) {
- NOTREACHED() << "Callback from foreign URL fetcher";
- return;
- }
-
- DeviceManagementRequestJobImpl* job = entry->second;
- pending_jobs_.erase(entry);
-
- if (job->ShouldRetry(source)) {
- VLOG(1) << "Retrying dmserver request.";
- job->PrepareRetry();
- StartJob(job);
- } else {
- std::string data;
- source->GetResponseAsString(&data);
- job->HandleResponse(source->GetStatus(), source->GetResponseCode(),
- source->GetCookies(), data);
- }
- delete source;
-}
-
-void DeviceManagementService::AddJob(DeviceManagementRequestJobImpl* job) {
- if (initialized_)
- StartJob(job);
- else
- queued_jobs_.push_back(job);
-}
-
-void DeviceManagementService::RemoveJob(DeviceManagementRequestJobImpl* job) {
- for (JobFetcherMap::iterator entry(pending_jobs_.begin());
- entry != pending_jobs_.end();
- ++entry) {
- if (entry->second == job) {
- delete entry->first;
- pending_jobs_.erase(entry);
- return;
- }
- }
-
- const JobQueue::iterator elem =
- std::find(queued_jobs_.begin(), queued_jobs_.end(), job);
- if (elem != queued_jobs_.end())
- queued_jobs_.erase(elem);
-}
-
-} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698