// Copyright (c) 2012 The Chromium OS 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 LIBBRILLO_POLICY_DEVICE_POLICY_IMPL_H_
#define LIBBRILLO_POLICY_DEVICE_POLICY_IMPL_H_

#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/macros.h>

#include "bindings/chrome_device_policy.pb.h"
#include "bindings/device_management_backend.pb.h"
#include "install_attributes/libinstallattributes.h"
#include "policy/device_policy.h"

#pragma GCC visibility push(default)

namespace policy {

// This class holds device settings that are to be enforced across all users.
//
// Before serving it to the users this class verifies that the policy is valid
// against its signature and the owner's key and also that the policy files
// are owned by root.
class DevicePolicyImpl : public DevicePolicy {
 public:
  DevicePolicyImpl();
  ~DevicePolicyImpl() override;

  const enterprise_management::ChromeDeviceSettingsProto& get_device_policy()
      const {
    return device_policy_;
  }

  // DevicePolicy overrides:
  bool LoadPolicy() override;
  bool GetPolicyRefreshRate(int* rate) const override;
  bool GetUserWhitelist(
      std::vector<std::string>* user_whitelist) const override;
  bool GetGuestModeEnabled(bool* guest_mode_enabled) const override;
  bool GetCameraEnabled(bool* camera_enabled) const override;
  bool GetShowUserNames(bool* show_user_names) const override;
  bool GetDataRoamingEnabled(bool* data_roaming_enabled) const override;
  bool GetAllowNewUsers(bool* allow_new_users) const override;
  bool GetMetricsEnabled(bool* metrics_enabled) const override;
  bool GetReportVersionInfo(bool* report_version_info) const override;
  bool GetReportActivityTimes(bool* report_activity_times) const override;
  bool GetReportBootMode(bool* report_boot_mode) const override;
  bool GetEphemeralUsersEnabled(bool* ephemeral_users_enabled) const override;
  bool GetReleaseChannel(std::string* release_channel) const override;
  bool GetReleaseChannelDelegated(
      bool* release_channel_delegated) const override;
  bool GetUpdateDisabled(bool* update_disabled) const override;
  bool GetTargetVersionPrefix(
      std::string* target_version_prefix) const override;
  bool GetRollbackToTargetVersion(
      int* rollback_to_target_version) const override;
  bool GetRollbackAllowedMilestones(
      int* rollback_allowed_milestones) const override;
  bool GetScatterFactorInSeconds(
      int64_t* scatter_factor_in_seconds) const override;
  bool GetAllowedConnectionTypesForUpdate(
      std::set<std::string>* connection_types) const override;
  bool GetOpenNetworkConfiguration(
      std::string* open_network_configuration) const override;
  bool GetOwner(std::string* owner) const override;
  bool GetHttpDownloadsEnabled(bool* http_downloads_enabled) const override;
  bool GetAuP2PEnabled(bool* au_p2p_enabled) const override;
  bool GetAllowKioskAppControlChromeVersion(
      bool* allow_kiosk_app_control_chrome_version) const override;
  bool GetUsbDetachableWhitelist(
      std::vector<UsbDeviceId>* usb_whitelist) const override;
  bool GetAutoLaunchedKioskAppId(std::string* app_id_out) const override;
  bool IsEnterpriseManaged() const override;
  bool GetSecondFactorAuthenticationMode(int* mode_out) const override;
  bool GetDisallowedTimeIntervals(
      std::vector<WeeklyTimeInterval>* intervals_out) const override;

  // Methods that can be used only for testing.
  void set_policy_data_for_testing(
      const enterprise_management::PolicyData& policy_data) {
    policy_data_ = policy_data;
  }
  void set_verify_root_ownership_for_testing(bool verify_root_ownership) {
    verify_root_ownership_ = verify_root_ownership;
  }
  void set_install_attributes_for_testing(
      std::unique_ptr<InstallAttributesReader> install_attributes_reader) {
    install_attributes_reader_ = std::move(install_attributes_reader);
  }
  void set_policy_for_testing(
      const enterprise_management::ChromeDeviceSettingsProto& device_policy) {
    device_policy_ = device_policy;
  }
  void set_policy_path_for_testing(const base::FilePath& policy_path) {
    policy_path_ = policy_path;
  }
  void set_key_file_path_for_testing(const base::FilePath& keyfile_path) {
    keyfile_path_ = keyfile_path;
  }
  void set_verify_policy_for_testing(bool value) { verify_policy_ = value; }

 private:
  // Verifies that both the policy file and the signature file exist and are
  // owned by the root. Does nothing when |verify_root_ownership_| is set to
  // false.
  bool VerifyPolicyFile(const base::FilePath& policy_path);

  // Verifies that the policy signature is correct.
  bool VerifyPolicySignature() override;

  // Loads policy off of disk from |policy_path| into |policy_|. Returns true if
  // the |policy_path| is present on disk and loading it is successful.
  bool LoadPolicyFromFile(const base::FilePath& policy_path);

  // Path of the default policy file, e.g. /path/to/policy. In order to make
  // device policy more resilient against broken files, this class also tries to
  // load indexed paths /path/to/policy.1, /path/to/policy.2 etc., see
  // resilient_policy_utils.h.
  base::FilePath policy_path_;
  base::FilePath keyfile_path_;
  std::unique_ptr<InstallAttributesReader> install_attributes_reader_;
  enterprise_management::PolicyFetchResponse policy_;
  enterprise_management::PolicyData policy_data_;
  enterprise_management::ChromeDeviceSettingsProto device_policy_;

  // If true, verify that policy files are owned by root. True in production
  // but can be set to false by tests.
  bool verify_root_ownership_ = true;
  // If false, all types of verification are disabled. True in production
  // but can be set to false by tests.
  bool verify_policy_ = true;

  DISALLOW_COPY_AND_ASSIGN(DevicePolicyImpl);
};
}  // namespace policy

#pragma GCC visibility pop

#endif  // LIBBRILLO_POLICY_DEVICE_POLICY_IMPL_H_
