// Copyright 2020 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/device_api/device_service_impl.h"

#include <functional>
#include <optional>
#include <utility>

#include "base/check_deref.h"
#include "base/check_is_test.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/types/expected_macros.h"
#include "build/build_config.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/device_api/device_attribute_api.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
#include "chrome/browser/policy/policy_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_constants.h"
#include "chrome/browser/web_applications/policy/web_app_policy_constants.h"
#include "chrome/browser/web_applications/web_app_filter.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_tab_helper.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/permissions/features.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/permission_controller_delegate.h"
#include "content/public/browser/permission_descriptor_util.h"
#include "content/public/browser/render_frame_host.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/common/features_generated.h"
#include "url/gurl.h"
#include "url/origin.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ash/app_mode/isolated_web_app/kiosk_iwa_data.h"
#include "chrome/browser/ash/app_mode/isolated_web_app/kiosk_iwa_manager.h"
#include "chrome/browser/ash/app_mode/web_app/kiosk_web_app_data.h"
#include "chrome/browser/ash/app_mode/web_app/kiosk_web_app_manager.h"
#include "chrome/common/url_constants.h"
#include "chromeos/components/kiosk/kiosk_utils.h"
#include "components/user_manager/user_manager.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace {
#if BUILDFLAG(IS_CHROMEOS)

// Returns an origin of the current kiosk web app.
// Should only be called when the current user is a web kiosk.
url::Origin GetWebKioskOrigin() {
  const AccountId& account_id =
      user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId();
  CHECK(ash::KioskWebAppManager::IsInitialized());
  const ash::KioskWebAppData* app_data =
      ash::KioskWebAppManager::Get()->GetAppByAccountId(account_id);
  return url::Origin::Create(CHECK_DEREF(app_data).install_url());
}

// Returns an origin of the current kiosk isolated web app.
// Should only be called when the current user is an IWA kiosk.
url::Origin GetIwaKioskOrigin() {
  const AccountId& account_id =
      user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId();
  const ash::KioskIwaData* iwa_data =
      CHECK_DEREF(ash::KioskIwaManager::Get()).GetApp(account_id);
  return CHECK_DEREF(iwa_data).origin();
}

std::optional<url::Origin> MaybeGetCurrentKioskOrigin() {
  if (chromeos::IsWebKioskSession()) {
    return GetWebKioskOrigin();
  }
  if (chromeos::IsIwaKioskSession()) {
    return GetIwaKioskOrigin();
  }
  return std::nullopt;
}

// Check whether the target origin is the same as the main application running
// in the Kiosk session.
bool IsEqualToKioskOrigin(const url::Origin& origin) {
  std::optional<url::Origin> current_kiosk_origin =
      MaybeGetCurrentKioskOrigin();
  return current_kiosk_origin.has_value() &&
         (current_kiosk_origin.value() == origin);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

Profile* GetProfile(content::RenderFrameHost& host) {
  return Profile::FromBrowserContext(host.GetBrowserContext());
}

std::optional<std::reference_wrapper<const web_app::WebAppRegistrar>>
GetRegistrar(content::RenderFrameHost& host, const url::Origin& origin) {
  const web_app::WebAppProvider* web_app_provider =
      web_app::WebAppProvider::GetForWebApps(GetProfile(host));
  if (!web_app_provider) {
    return std::nullopt;
  }
  // In this case we will not modify any data so it is safe to access registrar
  // without lock
  return web_app_provider->registrar_unsafe();
}

std::optional<webapps::AppId> GetAppId(
    const web_app::WebAppRegistrar& registrar,
    const url::Origin& origin) {
  return registrar.FindBestAppWithUrlInScope(
      origin.GetURL(), web_app::WebAppFilter::InstalledInChrome());
}

// Check whether an app with the target origin is in the WebAppRegistrar and is
// an IWA.
bool IsForceInstalledIwaOrigin(content::RenderFrameHost& host,
                               const url::Origin& origin) {
  ASSIGN_OR_RETURN(const web_app::WebAppRegistrar& registrar,
                   GetRegistrar(host, origin), [] { return false; });
  ASSIGN_OR_RETURN(webapps::AppId app_id, GetAppId(registrar, origin),
                   [] { return false; });
  return registrar.IsInstalledByPolicy(app_id) && registrar.IsIsolated(app_id);
}

// Check whether an app with the target origin is in the WebAppRegistrar.
bool IsForceInstalledOrigin(content::RenderFrameHost& host,
                            const url::Origin& origin) {
  ASSIGN_OR_RETURN(const web_app::WebAppRegistrar& registrar,
                   GetRegistrar(host, origin), [] { return false; });
  ASSIGN_OR_RETURN(webapps::AppId app_id, GetAppId(registrar, origin),
                   [] { return false; });
  return registrar.IsInstalledByPolicy(app_id);
}

bool IsAffiliatedUser() {
#if BUILDFLAG(IS_CHROMEOS)
  const user_manager::User* user =
      user_manager::UserManager::Get()->GetPrimaryUser();
  return (user != nullptr) && user->IsAffiliated();
#else
  return false;
#endif  // BUILDFLAG(IS_CHROMEOS)
}

bool IsPermissionsPolicyFeatureEnabled() {
  return base::FeatureList::IsEnabled(
      blink::features::kDeviceAttributesPermissionPolicy);
}

bool IsTrustedContext(content::RenderFrameHost& host,
                      const url::Origin& origin) {
  // Do not create the service for the incognito mode.
  if (GetProfile(host)->IsIncognitoProfile()) {
    return false;
  }

#if BUILDFLAG(IS_CHROMEOS)
  if (IsRunningInAppMode()) {
    if (base::FeatureList::IsEnabled(
            permissions::features::
                kAllowMultipleOriginsForWebKioskPermissions)) {
      return IsEqualToKioskOrigin(origin) ||
             IsWebKioskOriginAllowed(GetProfile(host)->GetPrefs(),
                                     origin.GetURL());
    }

    return IsEqualToKioskOrigin(origin);
  }
#endif  // BUILDFLAG(IS_CHROMEOS)
  return IsPermissionsPolicyFeatureEnabled()
             ? IsForceInstalledIwaOrigin(host, origin)
             : IsForceInstalledOrigin(host, origin);
}

bool IsAllowedByPermissionsPolicy(content::RenderFrameHost& host) {
  return host.IsFeatureEnabled(
      network::mojom::PermissionsPolicyFeature::kDeviceAttributes);
}

bool IsAllowedByAdminPolicy(content::RenderFrameHost& host,
                            const url::Origin& origin) {
#if BUILDFLAG(IS_CHROMEOS)
  return policy::IsOriginInAllowlist(
      origin.GetURL(), GetProfile(host)->GetPrefs(),
      prefs::kManagedDeviceAttributesAllowedForOrigins);
#else
  return false;
#endif  // BUILDFLAG(IS_CHROMEOS)
}

bool IsAllowedByContentSettings(content::RenderFrameHost& host,
                                const url::Origin& origin) {
  switch (HostContentSettingsMapFactory::GetForProfile(GetProfile(host))
              ->GetContentSetting(origin.GetURL(), origin.GetURL(),
                                  ContentSettingsType::DEVICE_ATTRIBUTES)) {
    case CONTENT_SETTING_ALLOW:
      return true;
    case CONTENT_SETTING_BLOCK:
      return false;
    default:
      NOTREACHED();
  }
}
}  // namespace

DeviceServiceImpl::DeviceServiceImpl(
    content::RenderFrameHost& host,
    mojo::PendingReceiver<blink::mojom::DeviceAPIService> receiver,
    std::unique_ptr<DeviceAttributeApi> device_attribute_api)
    : DocumentService(host, std::move(receiver)),
      device_attribute_api_(std::move(device_attribute_api)) {
  Profile* const profile = GetProfile(host);
  pref_change_registrar_.Init(profile->GetPrefs());
  pref_change_registrar_.Add(
      prefs::kWebAppInstallForceList,
      base::BindRepeating(&DeviceServiceImpl::OnDisposingIfNeeded,
                          base::Unretained(this)));
  pref_change_registrar_.Add(
      prefs::kIsolatedWebAppInstallForceList,
      base::BindRepeating(&DeviceServiceImpl::OnDisposingIfNeeded,
                          base::Unretained(this)));
#if BUILDFLAG(IS_CHROMEOS)
  pref_change_registrar_.Add(
      prefs::kKioskBrowserPermissionsAllowedForOrigins,
      base::BindRepeating(&DeviceServiceImpl::OnDisposingIfNeeded,
                          base::Unretained(this)));
  if (!IsPermissionsPolicyFeatureEnabled()) {
    pref_change_registrar_.Add(
        prefs::kManagedDeviceAttributesAllowedForOrigins,
        base::BindRepeating(&DeviceServiceImpl::OnDisposingIfNeeded,
                            base::Unretained(this)));
  }
#endif  // BUILDFLAG(IS_CHROMEOS)
  content_settings_observation_.Observe(
      HostContentSettingsMapFactory::GetForProfile(profile));
  auto& provider = CHECK_DEREF(web_app::WebAppProvider::GetForWebApps(profile));
  install_manager_observation_.Observe(&provider.install_manager());
}

DeviceServiceImpl::~DeviceServiceImpl() = default;

// static
void DeviceServiceImpl::Create(
    content::RenderFrameHost* host,
    mojo::PendingReceiver<blink::mojom::DeviceAPIService> receiver,
    std::unique_ptr<DeviceAttributeApi> device_attribute_api) {
  CHECK(host);
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (host->GetParentOrOuterDocumentOrEmbedder()) {
    mojo::ReportBadMessage(
        "Device Attributes are allowed only in top level frames.");
    return;
  }
  if (!IsTrustedContext(*host, host->GetLastCommittedOrigin())) {
    // Not sending bad message here since the API is always exposed to the end
    // user.
    return;
  }
  if (IsPermissionsPolicyFeatureEnabled() &&
      !IsAllowedByPermissionsPolicy(*host)) {
    mojo::ReportBadMessage(
        "Permissions policy blocks access to Device Attributes.");
    return;
  }
  // The object is bound to the lifetime of |host| and the mojo
  // connection. See DocumentService for details.
  new DeviceServiceImpl(*host, std::move(receiver),
                        std::move(device_attribute_api));
}

// static
void DeviceServiceImpl::Create(
    content::RenderFrameHost* host,
    mojo::PendingReceiver<blink::mojom::DeviceAPIService> receiver) {
  Create(host, std::move(receiver), std::make_unique<DeviceAttributeApiImpl>());
}

// static
void DeviceServiceImpl::CreateForTest(
    content::RenderFrameHost* host,
    mojo::PendingReceiver<blink::mojom::DeviceAPIService> receiver,
    std::unique_ptr<DeviceAttributeApi> device_attribute_api) {
  CHECK_IS_TEST();
  Create(host, std::move(receiver), std::move(device_attribute_api));
}

void DeviceServiceImpl::OnWebAppSourceRemoved(const webapps::AppId& app_id) {
  OnDisposingIfNeeded();
}

void DeviceServiceImpl::OnWebAppUninstalled(
    const webapps::AppId& app_id,
    webapps::WebappUninstallSource uninstall_source) {
  OnDisposingIfNeeded();
}

void DeviceServiceImpl::OnWebAppInstallManagerDestroyed() {
  install_manager_observation_.Reset();
}

void DeviceServiceImpl::OnContentSettingChanged(
    const ContentSettingsPattern& primary_pattern,
    const ContentSettingsPattern& secondary_pattern,
    ContentSettingsTypeSet content_type_set) {
  if (!content_type_set.Contains(ContentSettingsType::DEVICE_ATTRIBUTES)) {
    return;
  }
  OnDisposingIfNeeded();
}

void DeviceServiceImpl::OnDisposingIfNeeded() {
  // DeviceServiceImpl is allocated on the heap, thus it is safe to remove it
  // like this.
  if (!IsTrustedContext(render_frame_host(), origin())) {
    ResetAndDeleteThis();
  }
}

void DeviceServiceImpl::GetDirectoryId(GetDirectoryIdCallback callback) {
  GetDeviceAttribute(&DeviceAttributeApi::GetDirectoryId, std::move(callback));
}

void DeviceServiceImpl::GetHostname(GetHostnameCallback callback) {
  GetDeviceAttribute(&DeviceAttributeApi::GetHostname, std::move(callback));
}

void DeviceServiceImpl::GetSerialNumber(GetSerialNumberCallback callback) {
  GetDeviceAttribute(&DeviceAttributeApi::GetSerialNumber, std::move(callback));
}

void DeviceServiceImpl::GetAnnotatedAssetId(
    GetAnnotatedAssetIdCallback callback) {
  GetDeviceAttribute(&DeviceAttributeApi::GetAnnotatedAssetId,
                     std::move(callback));
}

void DeviceServiceImpl::GetAnnotatedLocation(
    GetAnnotatedLocationCallback callback) {
  GetDeviceAttribute(&DeviceAttributeApi::GetAnnotatedLocation,
                     std::move(callback));
}

void DeviceServiceImpl::GetDeviceAttribute(
    void (DeviceAttributeApi::*method)(DeviceAttributeCallback callback),
    DeviceAttributeCallback callback) {
  if (!IsAffiliatedUser()) {
    device_attribute_api_->ReportNotAffiliatedError(std::move(callback));
    return;
  }

  if (IsPermissionsPolicyFeatureEnabled()) {
    if (!IsAllowedByContentSettings(render_frame_host(), origin())) {
      device_attribute_api_->ReportNotAllowedError(std::move(callback));
      return;
    }
  } else {
    if (!IsAllowedByAdminPolicy(render_frame_host(), origin())) {
      device_attribute_api_->ReportNotAllowedError(std::move(callback));
      return;
    }
  }

  (device_attribute_api_.get()->*method)(std::move(callback));
}
