blob: d21c1d2915bba55d27ab33524b9b5026127f9ca9 [file] [log] [blame]
// 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.
#ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_CLIENT_H_
#define COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_CLIENT_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/remote_commands/remote_command_job.h"
#include "components/policy/policy_export.h"
#include "components/policy/proto/device_management_backend.pb.h"
namespace net {
class URLRequestContextGetter;
}
namespace policy {
class DeviceManagementRequestJob;
class DeviceManagementService;
class SigningService;
// Implements the core logic required to talk to the device management service.
// Also keeps track of the current state of the association with the service,
// such as whether there is a valid registration (DMToken is present in that
// case) and whether and what errors occurred in the latest request.
//
// Note that CloudPolicyClient doesn't do any validation of policy responses
// such as signature and time stamp checks. These happen once the policy gets
// installed in the cloud policy cache.
class POLICY_EXPORT CloudPolicyClient {
public:
// Maps a (policy type, settings entity ID) pair to its corresponding
// PolicyFetchResponse.
using ResponseMap =
std::map<std::pair<std::string, std::string>,
std::unique_ptr<enterprise_management::PolicyFetchResponse>>;
// Maps a license type to number of available licenses.
using LicenseMap = std::map<LicenseType, int>;
// A callback which receives boolean status of an operation. If the operation
// succeeded, |status| is true.
using StatusCallback = base::Callback<void(bool status)>;
// A callback for available licenses request. If the operation succeeded,
// |success| is true, and |map| contains available licenses.
using LicenseRequestCallback =
base::Callback<void(bool success, const LicenseMap& map)>;
// A callback which receives fetched remote commands.
using RemoteCommandCallback = base::Callback<void(
DeviceManagementStatus,
const std::vector<enterprise_management::RemoteCommand>&)>;
// Observer interface for state and policy changes.
class POLICY_EXPORT Observer {
public:
virtual ~Observer();
// Called when a policy fetch completes successfully. If a policy fetch
// triggers an error, OnClientError() will fire.
virtual void OnPolicyFetched(CloudPolicyClient* client) = 0;
// Called upon registration state changes. This callback is invoked for
// successful completion of registration and unregistration requests.
virtual void OnRegistrationStateChanged(CloudPolicyClient* client) = 0;
// Called when a request for device robot OAuth2 authorization tokens
// returns successfully. Only occurs during enrollment. Optional
// (default implementation is a noop).
virtual void OnRobotAuthCodesFetched(CloudPolicyClient* client);
// Indicates there's been an error in a previously-issued request.
virtual void OnClientError(CloudPolicyClient* client) = 0;
};
// If non-empty, |machine_id| and |machine_model| are passed to the server
// verbatim. As these reveal machine identity, they must only be used where
// this is appropriate (i.e. device policy, but not user policy). |service|
// and |signing_service| are weak pointers and it's the caller's
// responsibility to keep them valid for the lifetime of CloudPolicyClient.
// The |signing_service| is used to sign sensitive requests.
CloudPolicyClient(
const std::string& machine_id,
const std::string& machine_model,
DeviceManagementService* service,
scoped_refptr<net::URLRequestContextGetter> request_context,
SigningService* signing_service);
virtual ~CloudPolicyClient();
// Sets the DMToken, thereby establishing a registration with the server. A
// policy fetch is not automatically issued but can be requested by calling
// FetchPolicy().
virtual void SetupRegistration(const std::string& dm_token,
const std::string& client_id);
// Attempts to register with the device management service. Results in a
// registration change or error notification.
virtual void Register(
enterprise_management::DeviceRegisterRequest::Type registration_type,
enterprise_management::DeviceRegisterRequest::Flavor flavor,
enterprise_management::LicenseType::LicenseTypeEnum license_type,
const std::string& auth_token,
const std::string& client_id,
const std::string& requisition,
const std::string& current_state_key);
// Attempts to register with the device management service using a
// registration certificate. Results in a registration change or
// error notification.
virtual void RegisterWithCertificate(
enterprise_management::DeviceRegisterRequest::Type registration_type,
enterprise_management::DeviceRegisterRequest::Flavor flavor,
enterprise_management::LicenseType::LicenseTypeEnum license_type,
const std::string& pem_certificate_chain,
const std::string& client_id,
const std::string& requisition,
const std::string& current_state_key);
// Sets information about a policy invalidation. Subsequent fetch operations
// will use the given info, and callers can use fetched_invalidation_version
// to determine which version of policy was fetched.
void SetInvalidationInfo(int64_t version, const std::string& payload);
// Requests a policy fetch. The client being registered is a prerequisite to
// this operation and this call will CHECK if the client is not in registered
// state. FetchPolicy() triggers a policy fetch from the cloud. A policy
// change notification is reported to the observers and the new policy blob
// can be retrieved once the policy fetch operation completes. In case of
// multiple requests to fetch policy, new requests will cancel any pending
// requests and the latest request will eventually trigger notifications.
virtual void FetchPolicy();
// Requests OAuth2 auth codes for the device robot account. The client being
// registered is a prerequisite to this operation and this call will CHECK if
// the client is not in registered state.
virtual void FetchRobotAuthCodes(const std::string& auth_token);
// Sends an unregistration request to the server.
virtual void Unregister();
// Upload a machine certificate to the server. Like FetchPolicy, this method
// requires that the client is in a registered state. |certificate_data| must
// hold the X.509 certificate data to be sent to the server. The |callback|
// will be called when the operation completes.
virtual void UploadEnterpriseMachineCertificate(
const std::string& certificate_data,
const StatusCallback& callback);
// Upload an enrollment certificate to the server. Like FetchPolicy, this
// method requires that the client is in a registered state.
// |certificate_data| must hold the X.509 certificate data to be sent to the
// server. The |callback| will be called when the operation completes.
virtual void UploadEnterpriseEnrollmentCertificate(
const std::string& certificate_data,
const StatusCallback& callback);
// Uploads device/session status to the server. As above, the client must be
// in a registered state. If non-null, |device_status| and |session_status|
// will be included in the upload status request. The |callback| will be
// called when the operation completes.
virtual void UploadDeviceStatus(
const enterprise_management::DeviceStatusReportRequest* device_status,
const enterprise_management::SessionStatusReportRequest* session_status,
const StatusCallback& callback);
// Attempts to fetch remote commands, with |last_command_id| being the ID of
// the last command that finished execution and |command_results| being
// results for previous commands which have not been reported yet. The
// |callback| will be called when the operation completes.
// Note that sending |last_command_id| will acknowledge this command and any
// previous commands. A nullptr indicates that no commands have finished
// execution.
virtual void FetchRemoteCommands(
std::unique_ptr<RemoteCommandJob::UniqueIDType> last_command_id,
const std::vector<enterprise_management::RemoteCommandResult>&
command_results,
const RemoteCommandCallback& callback);
// Sends a device attribute update permission request to the server, uses
// OAuth2 token |auth_token| to identify user who requests a permission to
// name a device, calls a |callback| from the enrollment screen to indicate
// whether the device naming prompt should be shown.
void GetDeviceAttributeUpdatePermission(const std::string& auth_token,
const StatusCallback& callback);
// Sends a device naming information (Asset Id and Location) to the
// device management server, uses OAuth2 token |auth_token| to identify user
// who names a device, the |callback| will be called when the operation
// completes.
void UpdateDeviceAttributes(const std::string& auth_token,
const std::string& asset_id,
const std::string& location,
const StatusCallback& callback);
// Requests a list of licenses available for enrollment. Uses OAuth2 token
// |auth_token| to identify user who issues the request, the |callback| will
// be called when the operation completes.
void RequestAvailableLicenses(const std::string& auth_token,
const LicenseRequestCallback& callback);
// Sends a GCM id update request to the DM server. The server will
// associate the DM token in authorization header with |gcm_id|, and
// |callback| will be called when the operation completes.
virtual void UpdateGcmId(const std::string& gcm_id,
const StatusCallback& callback);
// Adds an observer to be called back upon policy and state changes.
void AddObserver(Observer* observer);
// Removes the specified observer.
void RemoveObserver(Observer* observer);
const std::string& machine_id() const { return machine_id_; }
const std::string& machine_model() const { return machine_model_; }
void set_last_policy_timestamp(const base::Time& timestamp) {
last_policy_timestamp_ = timestamp;
}
const base::Time& last_policy_timestamp() { return last_policy_timestamp_; }
void set_public_key_version(int public_key_version) {
public_key_version_ = public_key_version;
public_key_version_valid_ = true;
}
void clear_public_key_version() {
public_key_version_valid_ = false;
}
// FetchPolicy() calls will request this policy type.
// If |settings_entity_id| is empty then it won't be set in the
// PolicyFetchRequest.
void AddPolicyTypeToFetch(const std::string& policy_type,
const std::string& settings_entity_id);
// FetchPolicy() calls won't request the given policy type and optional
// |settings_entity_id| anymore.
void RemovePolicyTypeToFetch(const std::string& policy_type,
const std::string& settings_entity_id);
// Configures a set of device state keys to transfer to the server in the next
// policy fetch. If the fetch is successful, the keys will be cleared so they
// are only uploaded once.
void SetStateKeysToUpload(const std::vector<std::string>& keys);
// Whether the client is registered with the device management service.
bool is_registered() const { return !dm_token_.empty(); }
const std::string& dm_token() const { return dm_token_; }
const std::string& client_id() const { return client_id_; }
// The device mode as received in the registration request.
DeviceMode device_mode() const { return device_mode_; }
// The policy responses as obtained by the last request to the cloud. These
// policies haven't gone through verification, so their contents cannot be
// trusted. Use CloudPolicyStore::policy() and CloudPolicyStore::policy_map()
// instead for making policy decisions.
const ResponseMap& responses() const {
return responses_;
}
// Returns the policy response for the (|policy_type|, |settings_entity_id|)
// pair if found in |responses()|. Otherwise returns nullptr.
const enterprise_management::PolicyFetchResponse* GetPolicyFor(
const std::string& policy_type,
const std::string& settings_entity_id) const;
DeviceManagementStatus status() const {
return status_;
}
const std::string& robot_api_auth_code() const {
return robot_api_auth_code_;
}
// Returns the invalidation version that was used for the last FetchPolicy.
// Observers can call this method from their OnPolicyFetched method to
// determine which at which invalidation version the policy was fetched.
int64_t fetched_invalidation_version() const {
return fetched_invalidation_version_;
}
scoped_refptr<net::URLRequestContextGetter> GetRequestContext();
// Returns the number of active requests.
int GetActiveRequestCountForTest() const;
protected:
// A set of (policy type, settings entity ID) pairs to fetch.
typedef std::set<std::pair<std::string, std::string>> PolicyTypeSet;
// Upload a certificate to the server. Like FetchPolicy, this method
// requires that the client is in a registered state. |certificate_data| must
// hold the X.509 certificate data to be sent to the server. The |callback|
// will be called when the operation completes.
void UploadCertificate(
const std::string& certificate_data,
enterprise_management::DeviceCertUploadRequest::CertificateType
certificate_type,
const StatusCallback& callback);
// Callback for retries of registration requests.
void OnRetryRegister(DeviceManagementRequestJob* job);
// Callback for siganture of requests.
void OnRegisterWithCertificateRequestSigned(bool success,
enterprise_management::SignedData signed_data);
// Callback for registration requests.
void OnRegisterCompleted(
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for policy fetch requests.
void OnPolicyFetchCompleted(
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for robot account api authorization requests.
void OnFetchRobotAuthCodesCompleted(
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for unregistration requests.
void OnUnregisterCompleted(
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for certificate upload requests.
void OnCertificateUploadCompleted(
const DeviceManagementRequestJob* job,
const StatusCallback& callback,
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for status upload requests.
void OnStatusUploadCompleted(
const DeviceManagementRequestJob* job,
const StatusCallback& callback,
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for remote command fetch requests.
void OnRemoteCommandsFetched(
const DeviceManagementRequestJob* job,
const RemoteCommandCallback& callback,
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for device attribute update permission requests.
void OnDeviceAttributeUpdatePermissionCompleted(
const DeviceManagementRequestJob* job,
const StatusCallback& callback,
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for device attribute update requests.
void OnDeviceAttributeUpdated(
const DeviceManagementRequestJob* job,
const StatusCallback& callback,
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for available license types request.
void OnAvailableLicensesRequested(
const DeviceManagementRequestJob* job,
const LicenseRequestCallback& callback,
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Callback for gcm id update requests.
void OnGcmIdUpdated(
const DeviceManagementRequestJob* job,
const StatusCallback& callback,
DeviceManagementStatus status,
int net_error,
const enterprise_management::DeviceManagementResponse& response);
// Helper to remove a job from request_jobs_.
void RemoveJob(const DeviceManagementRequestJob* job);
// Observer notification helpers.
void NotifyPolicyFetched();
void NotifyRegistrationStateChanged();
void NotifyRobotAuthCodesFetched();
void NotifyClientError();
// Data necessary for constructing policy requests.
const std::string machine_id_;
const std::string machine_model_;
PolicyTypeSet types_to_fetch_;
std::vector<std::string> state_keys_to_upload_;
std::string dm_token_;
DeviceMode device_mode_ = DEVICE_MODE_NOT_SET;
std::string client_id_;
base::Time last_policy_timestamp_;
int public_key_version_ = -1;
bool public_key_version_valid_ = false;
std::string robot_api_auth_code_;
// Information for the latest policy invalidation received.
int64_t invalidation_version_ = 0;
std::string invalidation_payload_;
// The invalidation version used for the most recent fetch operation.
int64_t fetched_invalidation_version_ = 0;
// Used for issuing requests to the cloud.
DeviceManagementService* service_ = nullptr;
// Used for signing requests.
SigningService* signing_service_ = nullptr;
// Only one outstanding policy fetch is allowed, so this is tracked in
// its own member variable.
std::unique_ptr<DeviceManagementRequestJob> policy_fetch_request_job_;
// All of the outstanding non-policy-fetch request jobs. These jobs are
// silently cancelled if Unregister() is called.
std::vector<std::unique_ptr<DeviceManagementRequestJob>> request_jobs_;
// The policy responses returned by the last policy fetch operation.
ResponseMap responses_;
DeviceManagementStatus status_ = DM_STATUS_SUCCESS;
base::ObserverList<Observer, true> observers_;
scoped_refptr<net::URLRequestContextGetter> request_context_;
private:
void SetClientId(const std::string& client_id);
// Used to create tasks which run delayed on the UI thread.
base::WeakPtrFactory<CloudPolicyClient> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CloudPolicyClient);
};
} // namespace policy
#endif // COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_CLIENT_H_