// Copyright 2020 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/enterprise/connectors/connectors_service.h"

#include <memory>

#include "base/memory/singleton.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/enterprise/connectors/common.h"
#include "chrome/browser/enterprise/connectors/connectors_manager.h"
#include "chrome/browser/enterprise/connectors/service_provider_config.h"
#include "chrome/browser/enterprise/util/affiliation.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/policy/dm_token_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "components/embedder_support/user_agent_utils.h"
#include "components/enterprise/browser/controller/browser_dm_token_storage.h"
#include "components/enterprise/common/proto/connectors.pb.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_util.h"
#include "components/policy/core/common/cloud/dm_token.h"
#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
#include "components/policy/core/common/policy_types.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/user_prefs/user_prefs.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_context.h"
#include "device_management_backend.pb.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/policy/core/user_cloud_policy_manager_chromeos.h"
#endif

namespace enterprise_connectors {

namespace {

const enterprise_management::PolicyData* GetProfilePolicyData(
    Profile* profile) {
  DCHECK(profile);
  auto* manager =
#if BUILDFLAG(IS_CHROMEOS_ASH)
      profile->GetUserCloudPolicyManagerChromeOS();
#else
      profile->GetUserCloudPolicyManager();
#endif
  if (manager && manager->core()->store() &&
      manager->core()->store()->has_policy()) {
    return manager->core()->store()->policy();
  }
  return nullptr;
}

void PopulateBrowserMetadata(bool include_device_info,
                             ClientMetadata::Browser* browser_proto) {
  base::FilePath browser_id;
  if (base::PathService::Get(base::DIR_EXE, &browser_id))
    browser_proto->set_browser_id(browser_id.AsUTF8Unsafe());
  browser_proto->set_user_agent(embedder_support::GetUserAgent());
  browser_proto->set_chrome_version(version_info::GetVersionNumber());
  if (include_device_info)
    browser_proto->set_machine_user(policy::GetOSUsername());
}

void PopulateDeviceMetadata(const ReportingSettings& reporting_settings,
                            Profile* profile,
                            ClientMetadata::Device* device_proto) {
  if (!reporting_settings.per_profile)
    device_proto->set_dm_token(reporting_settings.dm_token);
#if BUILDFLAG(IS_CHROMEOS_ASH)
  std::string client_id;
  auto* manager = profile->GetUserCloudPolicyManagerChromeOS();
  if (manager && manager->core() && manager->core()->client())
    client_id = manager->core()->client()->client_id();
#else
  std::string client_id =
      policy::BrowserDMTokenStorage::Get()->RetrieveClientId();
#endif
  device_proto->set_client_id(client_id);
  device_proto->set_os_version(policy::GetOSVersion());
  device_proto->set_os_platform(policy::GetOSPlatform());
  device_proto->set_name(policy::GetDeviceName());
}

void PopulateProfileMetadata(const ReportingSettings& reporting_settings,
                             Profile* profile,
                             ClientMetadata::Profile* profile_proto) {
  if (reporting_settings.per_profile)
    profile_proto->set_dm_token(reporting_settings.dm_token);
  auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
  if (identity_manager) {
    profile_proto->set_gaia_email(
        identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
            .email);
  }
  profile_proto->set_profile_path(profile->GetPath().AsUTF8Unsafe());
  ProfileAttributesEntry* entry =
      g_browser_process->profile_manager()
          ->GetProfileAttributesStorage()
          .GetProfileAttributesWithPath(profile->GetPath());
  if (entry) {
    profile_proto->set_profile_name(base::UTF16ToUTF8(entry->GetName()));
  }
  const enterprise_management::PolicyData* profile_policy =
      GetProfilePolicyData(profile);
  if (profile_policy) {
    if (profile_policy->has_device_id())
      profile_proto->set_client_id(profile_policy->device_id());
  }
}

}  // namespace

const base::Feature kEnterpriseConnectorsEnabled{
    "EnterpriseConnectorsEnabled", base::FEATURE_ENABLED_BY_DEFAULT};

const base::Feature kPerProfileConnectorsEnabled{
    "PerProfileConnectorsEnabled", base::FEATURE_ENABLED_BY_DEFAULT};

const char kServiceProviderConfig[] = R"({
  "version": "1",
  "service_providers" : [
    {
      "name": "google",
      "display_name": "Google Cloud",
      "version": {
        "1": {
          "analysis": {
            "url": "https://safebrowsing.google.com/safebrowsing/uploads/scan",
            "supported_tags": [
              {
                "name": "malware",
                "display_name": "Threat protection",
                "mime_types": [
                  "application/vnd.microsoft.portable-executable",
                  "application/vnd.rar",
                  "application/x-msdos-program",
                  "application/zip"
                ],
                "max_file_size": 52428800
              },
              {
                "name": "dlp",
                "display_name": "Sensitive data protection",
                "mime_types": [
                  "application/gzip",
                  "application/msword",
                  "application/pdf",
                  "application/postscript",
                  "application/rtf",
                  "application/vnd.google-apps.document.internal",
                  "application/vnd.google-apps.spreadsheet.internal",
                  "application/vnd.ms-cab-compressed",
                  "application/vnd.ms-excel",
                  "application/vnd.ms-powerpoint",
                  "application/vnd.ms-xpsdocument",
                  "application/vnd.oasis.opendocument.text",
                  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
                  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                  "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
                  "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                  "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
                  "application/vnd.ms-excel.sheet.macroenabled.12",
                  "application/vnd.ms-excel.template.macroenabled.12",
                  "application/vnd.ms-word.document.macroenabled.12",
                  "application/vnd.ms-word.template.macroenabled.12",
                  "application/vnd.rar",
                  "application/vnd.wordperfect",
                  "application/x-7z-compressed",
                  "application/x-bzip",
                  "application/x-bzip2",
                  "application/x-tar",
                  "application/zip",
                  "text/csv",
                  "text/plain"
                ],
                "max_file_size": 52428800
              }
            ]
          },
          "reporting": {
            "url": "https://chromereporting-pa.googleapis.com/v1/events"
          }
        }
      }
    },
    {
      "name": "box",
      "display_name": "Box",
      "version":  {
        "1": {
          "file_system": {
            "home": "https://box.com",
            "authorization_endpoint": "https://account.box.com/api/oauth2/authorize",
            "token_endpoint": "https://api.box.com/oauth2/token",
            "max_direct_size": 20971520,
            "scopes": [],
            "disable": [ "box.com" ]
          }
        }
      }
    }
  ]
})";

ServiceProviderConfig* GetServiceProviderConfig() {
  static base::NoDestructor<ServiceProviderConfig> config(
      kServiceProviderConfig);
  return config.get();
}

// --------------------------------
// ConnectorsService implementation
// --------------------------------

ConnectorsService::ConnectorsService(content::BrowserContext* context,
                                     std::unique_ptr<ConnectorsManager> manager)
    : context_(context), connectors_manager_(std::move(manager)) {
  DCHECK(context_);
  DCHECK(connectors_manager_);
}

ConnectorsService::~ConnectorsService() = default;

absl::optional<ReportingSettings> ConnectorsService::GetReportingSettings(
    ReportingConnector connector) {
  if (!ConnectorsEnabled())
    return absl::nullopt;

  absl::optional<ReportingSettings> settings =
      connectors_manager_->GetReportingSettings(connector);
  if (!settings.has_value())
    return absl::nullopt;

  absl::optional<DmToken> dm_token = GetDmToken(ConnectorScopePref(connector));
  if (!dm_token.has_value())
    return absl::nullopt;

  settings.value().dm_token = dm_token.value().value;
  settings.value().per_profile =
      dm_token.value().scope == policy::POLICY_SCOPE_USER;

  return settings;
}

absl::optional<AnalysisSettings> ConnectorsService::GetAnalysisSettings(
    const GURL& url,
    AnalysisConnector connector) {
  if (!ConnectorsEnabled())
    return absl::nullopt;

  absl::optional<AnalysisSettings> settings =
      connectors_manager_->GetAnalysisSettings(url, connector);
  if (!settings.has_value())
    return absl::nullopt;

  absl::optional<DmToken> dm_token = GetDmToken(ConnectorScopePref(connector));
  if (!dm_token.has_value())
    return absl::nullopt;

  settings.value().dm_token = dm_token.value().value;
  settings.value().per_profile =
      dm_token.value().scope == policy::POLICY_SCOPE_USER;
  settings.value().client_metadata = BuildClientMetadata();

  return settings;
}

absl::optional<FileSystemSettings> ConnectorsService::GetFileSystemSettings(
    const GURL& url,
    FileSystemConnector connector) {
  if (!ConnectorsEnabled())
    return absl::nullopt;

  absl::optional<FileSystemSettings> settings =
      connectors_manager_->GetFileSystemSettings(url, connector);
  if (!settings.has_value())
    return absl::nullopt;

  return settings;
}

bool ConnectorsService::IsConnectorEnabled(AnalysisConnector connector) const {
  if (!ConnectorsEnabled())
    return false;

  return connectors_manager_->IsConnectorEnabled(connector);
}

bool ConnectorsService::IsConnectorEnabled(ReportingConnector connector) const {
  if (!ConnectorsEnabled())
    return false;

  return connectors_manager_->IsConnectorEnabled(connector);
}

bool ConnectorsService::IsConnectorEnabled(
    FileSystemConnector connector) const {
  if (!ConnectorsEnabled())
    return false;

  return connectors_manager_->IsConnectorEnabled(connector);
}

std::vector<std::string> ConnectorsService::GetReportingServiceProviderNames(
    ReportingConnector connector) {
  if (!ConnectorsEnabled())
    return {};

  if (!GetDmToken(ConnectorScopePref(connector)).has_value())
    return {};

  return connectors_manager_->GetReportingServiceProviderNames(connector);
}

bool ConnectorsService::DelayUntilVerdict(AnalysisConnector connector) {
  if (!ConnectorsEnabled())
    return false;

  return connectors_manager_->DelayUntilVerdict(connector);
}

absl::optional<std::u16string> ConnectorsService::GetCustomMessage(
    AnalysisConnector connector,
    const std::string& tag) {
  if (!ConnectorsEnabled())
    return absl::nullopt;

  return connectors_manager_->GetCustomMessage(connector, tag);
}

absl::optional<GURL> ConnectorsService::GetLearnMoreUrl(
    AnalysisConnector connector,
    const std::string& tag) {
  if (!ConnectorsEnabled())
    return absl::nullopt;

  return connectors_manager_->GetLearnMoreUrl(connector, tag);
}

bool ConnectorsService::HasCustomInfoToDisplay(AnalysisConnector connector,
                                               const std::string& tag) {
  return GetCustomMessage(connector, tag) || GetLearnMoreUrl(connector, tag);
}

std::vector<std::string> ConnectorsService::GetAnalysisServiceProviderNames(
    AnalysisConnector connector) {
  if (!ConnectorsEnabled())
    return {};

  if (!GetDmToken(ConnectorScopePref(connector)).has_value())
    return {};

  return connectors_manager_->GetAnalysisServiceProviderNames(connector);
}

absl::optional<std::string> ConnectorsService::GetDMTokenForRealTimeUrlCheck()
    const {
  if (!ConnectorsEnabled())
    return absl::nullopt;

  if (Profile::FromBrowserContext(context_)->GetPrefs()->GetInteger(
          prefs::kSafeBrowsingEnterpriseRealTimeUrlCheckMode) ==
      safe_browsing::REAL_TIME_CHECK_DISABLED) {
    return absl::nullopt;
  }

  absl::optional<DmToken> dm_token =
      GetDmToken(prefs::kSafeBrowsingEnterpriseRealTimeUrlCheckScope);

  if (dm_token.has_value())
    return dm_token.value().value;
  return absl::nullopt;
}

safe_browsing::EnterpriseRealTimeUrlCheckMode
ConnectorsService::GetAppliedRealTimeUrlCheck() const {
  if (!ConnectorsEnabled() ||
      !GetDmToken(prefs::kSafeBrowsingEnterpriseRealTimeUrlCheckScope)
           .has_value()) {
    return safe_browsing::REAL_TIME_CHECK_DISABLED;
  }

  return static_cast<safe_browsing::EnterpriseRealTimeUrlCheckMode>(
      Profile::FromBrowserContext(context_)->GetPrefs()->GetInteger(
          prefs::kSafeBrowsingEnterpriseRealTimeUrlCheckMode));
}

ConnectorsManager* ConnectorsService::ConnectorsManagerForTesting() {
  return connectors_manager_.get();
}

ConnectorsService::DmToken::DmToken(const std::string& value,
                                    policy::PolicyScope scope)
    : value(value), scope(scope) {}
ConnectorsService::DmToken::DmToken(DmToken&&) = default;
ConnectorsService::DmToken& ConnectorsService::DmToken::operator=(DmToken&&) =
    default;
ConnectorsService::DmToken::~DmToken() = default;

absl::optional<ConnectorsService::DmToken> ConnectorsService::GetDmToken(
    const char* scope_pref) const {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  // On CrOS, the device must be affiliated to use the DM token for
  // scanning/reporting so we always use the browser DM token.
  return GetBrowserDmToken();
#else
  return GetPolicyScope(scope_pref) == policy::POLICY_SCOPE_USER
             ? GetProfileDmToken()
             : GetBrowserDmToken();
#endif
}

absl::optional<ConnectorsService::DmToken>
ConnectorsService::GetBrowserDmToken() const {
  policy::DMToken dm_token =
      policy::GetDMToken(Profile::FromBrowserContext(context_));

  if (!dm_token.is_valid())
    return absl::nullopt;

  return DmToken(dm_token.value(), policy::POLICY_SCOPE_MACHINE);
}

#if !BUILDFLAG(IS_CHROMEOS_ASH)
absl::optional<ConnectorsService::DmToken>
ConnectorsService::GetProfileDmToken() const {
  if (!base::FeatureList::IsEnabled(kPerProfileConnectorsEnabled))
    return absl::nullopt;

  if (!CanUseProfileDmToken())
    return absl::nullopt;

  policy::UserCloudPolicyManager* policy_manager =
      Profile::FromBrowserContext(context_)->GetUserCloudPolicyManager();
  if (!policy_manager || !policy_manager->IsClientRegistered())
    return absl::nullopt;

  return DmToken(policy_manager->core()->client()->dm_token(),
                 policy::POLICY_SCOPE_USER);
}

bool ConnectorsService::CanUseProfileDmToken() const {
  // If the browser isn't managed by CBCM, then the profile DM token can be
  // used.
  if (!policy::BrowserDMTokenStorage::Get()->RetrieveDMToken().is_valid())
    return true;

  return chrome::enterprise_util::IsProfileAffiliated(
      Profile::FromBrowserContext(context_));
}
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

policy::PolicyScope ConnectorsService::GetPolicyScope(
    const char* scope_pref) const {
  return static_cast<policy::PolicyScope>(
      Profile::FromBrowserContext(context_)->GetPrefs()->GetInteger(
          scope_pref));
}

bool ConnectorsService::ConnectorsEnabled() const {
  if (!base::FeatureList::IsEnabled(kEnterpriseConnectorsEnabled))
    return false;

  return !Profile::FromBrowserContext(context_)->IsOffTheRecord();
}

std::unique_ptr<ClientMetadata> ConnectorsService::BuildClientMetadata() {
  // Check the reporting policy value to check if the analysis should include
  // browser/device/profile information.
  auto reporting_settings =
      GetReportingSettings(ReportingConnector::SECURITY_EVENT);
  if (!reporting_settings.has_value())
    return nullptr;

  bool include_device_info = !reporting_settings.value().per_profile;
  Profile* profile = Profile::FromBrowserContext(context_);

  auto metadata = std::make_unique<ClientMetadata>();
  PopulateBrowserMetadata(include_device_info, metadata->mutable_browser());
  if (include_device_info) {
    PopulateDeviceMetadata(reporting_settings.value(), profile,
                           metadata->mutable_device());
  }
  PopulateProfileMetadata(reporting_settings.value(), profile,
                          metadata->mutable_profile());

  return metadata;
}

// ---------------------------------------
// ConnectorsServiceFactory implementation
// ---------------------------------------

// static
ConnectorsServiceFactory* ConnectorsServiceFactory::GetInstance() {
  return base::Singleton<ConnectorsServiceFactory>::get();
}

ConnectorsService* ConnectorsServiceFactory::GetForBrowserContext(
    content::BrowserContext* context) {
  return static_cast<ConnectorsService*>(
      GetInstance()->GetServiceForBrowserContext(context, true));
}

ConnectorsServiceFactory::ConnectorsServiceFactory()
    : BrowserContextKeyedServiceFactory(
          "ConnectorsService",
          BrowserContextDependencyManager::GetInstance()) {}

ConnectorsServiceFactory::~ConnectorsServiceFactory() = default;

KeyedService* ConnectorsServiceFactory::BuildServiceInstanceFor(
    content::BrowserContext* context) const {
  return new ConnectorsService(
      context,
      std::make_unique<ConnectorsManager>(
          user_prefs::UserPrefs::Get(context), GetServiceProviderConfig(),
          base::FeatureList::IsEnabled(kEnterpriseConnectorsEnabled)));
}

content::BrowserContext* ConnectorsServiceFactory::GetBrowserContextToUse(
    content::BrowserContext* context) const {
  return context;
}

}  // namespace enterprise_connectors
