chromium/chrome/browser/ash/policy/core/device_cloud_policy_client_factory_ash.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/policy/core/device_cloud_policy_client_factory_ash.h"

#include <optional>
#include <string>
#include <string_view>
#include <utility>

#include "base/check.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "chromeos/ash/components/system/statistics_provider.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

namespace {

constexpr int kDottedMacAddressSize = 17;

// Parses MAC address string frommated as AA:AA:AA:AA:AA:AA. Returns nullopt if
// `mac_address_string` is empty or ill-formated.
std::optional<policy::CloudPolicyClient::MacAddress> ParseMacAddress(
    std::string_view mac_address_string) {
  if (mac_address_string.size() != kDottedMacAddressSize)
    return std::nullopt;

  policy::CloudPolicyClient::MacAddress parsed_mac_address;
  base::span<policy::CloudPolicyClient::MacAddress::value_type>
      parsed_mac_address_span(parsed_mac_address);

  // Go through every 2 chars digit + 1 char separator. Check the separator is
  // correct. Parse the hex digit.
  for (size_t string_idx = 0, span_idx = 0;
       string_idx < mac_address_string.size() &&
       span_idx < parsed_mac_address.size();
       string_idx += 3, ++span_idx) {
    const size_t separator_idx = string_idx + 2;
    if (separator_idx < mac_address_string.size() &&
        mac_address_string[separator_idx] != ':') {
      return std::nullopt;
    }

    if (!base::HexStringToSpan(mac_address_string.substr(string_idx, 2),
                               parsed_mac_address_span.subspan(span_idx, 1))) {
      return std::nullopt;
    }
  }

  return parsed_mac_address;
}

std::string_view EmptyIfAbsent(std::optional<std::string_view> opt) {
  return opt.value_or(std::string_view());
}

}  // namespace

namespace policy {

// static
std::unique_ptr<CloudPolicyClient> CreateDeviceCloudPolicyClientAsh(
    ash::system::StatisticsProvider* statistics_provider,
    DeviceManagementService* service,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    CloudPolicyClient::DeviceDMTokenCallback device_dm_token_callback) {
  return std::make_unique<CloudPolicyClient>(
      EmptyIfAbsent(statistics_provider->GetMachineID()),
      EmptyIfAbsent(statistics_provider->GetMachineStatistic(
          ash::system::kHardwareClassKey)),
      EmptyIfAbsent(statistics_provider->GetMachineStatistic(
          ash::system::kRlzBrandCodeKey)),
      EmptyIfAbsent(statistics_provider->GetMachineStatistic(
          ash::system::kAttestedDeviceIdKey)),
      ParseMacAddress(EmptyIfAbsent(statistics_provider->GetMachineStatistic(
          ash::system::kEthernetMacAddressKey))),
      ParseMacAddress(EmptyIfAbsent(statistics_provider->GetMachineStatistic(
          ash::system::kDockMacAddressKey))),
      EmptyIfAbsent(statistics_provider->GetMachineStatistic(
          ash::system::kManufactureDateKey)),
      service, url_loader_factory, std::move(device_dm_token_callback));
}

}  // namespace policy