// Copyright 2025 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/devtools/devtools_availability_checker.h"

#include <string>

#include "base/check.h"
#include "base/feature_list.h"
#include "base/notreached.h"
#include "base/types/expected.h"
#include "base/values.h"
#include "chrome/browser/devtools/features.h"
#include "chrome/browser/policy/developer_tools_policy_checker.h"
#include "chrome/browser/policy/developer_tools_policy_checker_factory.h"
#include "chrome/browser/policy/developer_tools_policy_handler.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/buildflags/buildflags.h"
#include "url/gurl.h"
#include "url/url_constants.h"

#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"
#endif

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
#include "chrome/browser/web_applications/web_app.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/browser/web_applications/web_app_utils.h"
#include "components/webapps/isolated_web_apps/scheme.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/constants/pref_names.h"
#endif

namespace {

policy::DeveloperToolsAvailability GetDevToolsAvailability(
    Profile* profile) {
  using Availability = policy::DeveloperToolsAvailability;
  Availability availability =
      policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile);
#if BUILDFLAG(IS_CHROMEOS)
  // On ChromeOS disable dev tools for captive portal signin windows to prevent
  // them from being used for general navigation.
  if (availability != Availability::kDisallowed) {
    const PrefService::Preference* const captive_portal_pref =
        profile->GetPrefs()->FindPreference(
            chromeos::prefs::kCaptivePortalSignin);
    if (captive_portal_pref && captive_portal_pref->GetValue()->GetBool()) {
      availability = Availability::kDisallowed;
    }
  }
#endif
  return availability;
}

#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
bool IsRestrictedExtension(const extensions::Extension* extension,
                           Profile* profile) {
  if (!extension) {
    return false;
  }
  if (extensions::Manifest::IsPolicyLocation(extension->location())) {
    return true;
  }
  if (extensions::Manifest::IsComponentLocation(extension->location()) &&
      profile->GetProfilePolicyConnector()->IsManaged()) {
    return true;
  }
  return false;
}
#endif

}  // namespace

bool IsInspectionAllowed(Profile* profile,
                         content::DevToolsAgentHost* agent_host) {
  if (base::FeatureList::IsEnabled(features::kDevToolsTargetLevelEvaluation)) {
    GURL target_url = agent_host->GetURL();
    if (!IsInspectionAllowed(profile, target_url)) {
      return false;
    }

#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
    // Enforce extension policy at the target level before falling back to the
    // parent WebContents.
    if (target_url.SchemeIs(extensions::kExtensionScheme)) {
      if (auto* registry = extensions::ExtensionRegistry::Get(profile)) {
        if (const extensions::Extension* extension =
                registry->GetInstalledExtension(
                    std::string(target_url.host()))) {
          if (!IsInspectionAllowed(profile, extension)) {
            return false;
          }
        }
      }
    }
#endif

    if (content::WebContents* web_contents = agent_host->GetWebContents()) {
      return IsInspectionAllowed(profile, web_contents);
    }
    return true;
  }

  if (content::WebContents* web_contents = agent_host->GetWebContents()) {
    return IsInspectionAllowed(profile, web_contents);
  }
  return IsInspectionAllowed(profile, agent_host->GetURL());
}

bool IsInspectionAllowed(Profile* profile, content::WebContents* web_contents) {
  if (!web_contents) {
    // For contexts without web_contents, we can only check the general policy.
    return IsInspectionAllowed(
        profile, static_cast<const extensions::Extension*>(nullptr));
  }

  if (base::FeatureList::IsEnabled(features::kDevToolsTargetLevelEvaluation)) {
    if (content::RenderFrameHost* main_frame =
            web_contents->GetPrimaryMainFrame()) {
      if (!IsInspectionAllowed(profile, main_frame->GetLastCommittedURL())) {
        return false;
      }
    }
  } else {
    policy::DeveloperToolsPolicyChecker* checker =
        policy::DeveloperToolsPolicyCheckerFactory::GetForBrowserContext(
            profile);
    if (checker) {
      if (content::RenderFrameHost* main_frame =
              web_contents->GetPrimaryMainFrame()) {
        using FrameIterationAction =
            content::RenderFrameHost::FrameIterationAction;
        bool is_blocked = false;
        main_frame->ForEachRenderFrameHostWithAction(
            [&](content::RenderFrameHost* frame) {
              if (frame->GetLastCommittedURL().is_empty() ||
                  frame->GetLastCommittedURL().SchemeIs(url::kAboutScheme)) {
                return FrameIterationAction::kContinue;
              }
              auto frame_availability = checker->GetDevToolsAvailabilityForUrl(
                  frame->GetLastCommittedURL());
              if (frame_availability == policy::DeveloperToolsPolicyChecker::
                                            DevToolsAvailability::kDisallowed) {
                is_blocked = true;
                return FrameIterationAction::kStop;
              }
              return FrameIterationAction::kContinue;
            });
        if (is_blocked) {
          return false;
        }
      }
    }
  }

#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
  if (auto* process_manager =
          extensions::ProcessManager::Get(web_contents->GetBrowserContext())) {
    if (const extensions::Extension* extension =
            process_manager->GetExtensionForWebContents(web_contents)) {
      return IsInspectionAllowed(profile, extension);
    }
  }
#endif

#if !BUILDFLAG(IS_ANDROID)
  if (web_app::AreWebAppsEnabled(profile)) {
    if (const webapps::AppId* app_id =
            web_app::WebAppTabHelper::GetAppId(web_contents)) {
      if (auto* web_app_provider =
              web_app::WebAppProvider::GetForWebContents(web_contents)) {
        if (const web_app::WebApp* web_app =
                web_app_provider->registrar_unsafe().GetAppById(*app_id)) {
          return IsInspectionAllowed(profile, web_app);
        }
      }
    }
  }
#endif

  policy::DeveloperToolsPolicyChecker* checker =
      policy::DeveloperToolsPolicyCheckerFactory::GetForBrowserContext(profile);
  if (checker) {
    auto url_availability =
        checker->GetDevToolsAvailabilityForUrl(web_contents->GetURL());
    switch (url_availability) {
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kAllowed:
        return true;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::
          kDisallowed:
        return false;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kNotSet:
        break;
    }
  }

  // Fall back to the general enum policy for the tab context.
  using Availability = policy::DeveloperToolsAvailability;
  Availability availability = GetDevToolsAvailability(profile);
  switch (availability) {
    case Availability::kDisallowed:
      return false;
    case Availability::kAllowed:
    case Availability::kDisallowedForForceInstalledExtensions:
      return true;
    default:
      NOTREACHED() << "Unknown developer tools policy";
  }
}

bool IsInspectionAllowed(Profile* profile,
                         const extensions::Extension* extension) {
#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
  policy::DeveloperToolsPolicyChecker* checker =
      policy::DeveloperToolsPolicyCheckerFactory::GetForBrowserContext(profile);
  if (checker && extension) {
    auto url_availability =
        checker->GetDevToolsAvailabilityForUrl(extension->url());
    switch (url_availability) {
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kAllowed:
        return true;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::
          kDisallowed:
        return false;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kNotSet:
        // The URL is not covered by the URL-based policies, so we fall back to
        // the general enum-based policy.
        break;
    }
  }
#endif

  using Availability = policy::DeveloperToolsAvailability;
  Availability availability =
      extension ? policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(
                      profile)
                : GetDevToolsAvailability(profile);

  switch (availability) {
    case Availability::kDisallowed:
      if (!extension) {
        // When no specific context is given, we can't check for exceptions
        // like the allowlist. But if the allowlist is not empty, we should
        // allow the DevTools UI to load its resources, so it can be used for
        // allowlisted contexts.
        const base::ListValue& allowlist = profile->GetPrefs()->GetList(
            prefs::kDeveloperToolsAvailabilityAllowlist);
        if (!allowlist.empty()) {
          return true;
        }
      }
      return false;
    case Availability::kAllowed:
      return true;
    case Availability::kDisallowedForForceInstalledExtensions:
// This policy only restricts extensions and web apps. Regular pages are
// allowed.
#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
      if (IsRestrictedExtension(extension, profile)) {
        return false;
      }
#endif
      return true;
    default:
      NOTREACHED() << "Unknown developer tools policy";
  }
}

#if !BUILDFLAG(IS_ANDROID)
bool IsInspectionAllowed(Profile* profile, const web_app::WebApp* web_app) {
  if (web_app) {
    policy::DeveloperToolsPolicyChecker* checker =
        policy::DeveloperToolsPolicyCheckerFactory::GetForBrowserContext(
            profile);
    auto url_availability =
        checker->GetDevToolsAvailabilityForUrl(web_app->start_url());
    switch (url_availability) {
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kAllowed:
        return true;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::
          kDisallowed:
        return false;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kNotSet:
        // The URL is not covered by the URL-based policies, so we fall back to
        // the general enum-based policy.
        break;
    }
  }
  using Availability = policy::DeveloperToolsAvailability;
  Availability availability =
      policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile);
  switch (availability) {
    case Availability::kDisallowed:
      return false;
    case Availability::kAllowed:
      return true;
    case Availability::kDisallowedForForceInstalledExtensions:
      // DevTools should be blocked for Kiosk apps and policy-installed IWAs.
      if (web_app && (web_app->IsKioskInstalledApp() ||
                      web_app->IsIwaPolicyInstalledApp())) {
        return false;
      }
      return true;
    default:
      NOTREACHED() << "Unknown developer tools policy";
  }
}
#endif

bool IsInspectionAllowed(Profile* profile, const GURL& url) {
  if (url.is_empty() || url.SchemeIs(url::kAboutScheme)) {
    return true;
  }
#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
  if (url.SchemeIs(extensions::kExtensionScheme)) {
    if (const extensions::Extension* extension =
            extensions::ExtensionRegistry::Get(profile)->GetExtensionById(
                std::string(url.host()),
                extensions::ExtensionRegistry::EVERYTHING)) {
      return IsInspectionAllowed(profile, extension);
    }
  }
#endif

#if !BUILDFLAG(IS_ANDROID)
  if (url.SchemeIs(webapps::kIsolatedAppScheme) &&
      web_app::AreWebAppsEnabled(profile)) {
    base::expected<web_app::IsolatedWebAppUrlInfo, std::string> url_info =
        web_app::IsolatedWebAppUrlInfo::Create(url);
    if (url_info.has_value()) {
      if (auto* web_app_provider =
              web_app::WebAppProvider::GetForWebApps(profile)) {
        if (const web_app::WebApp* web_app =
                web_app_provider->registrar_unsafe().GetAppById(
                    url_info->app_id())) {
          return IsInspectionAllowed(profile, web_app);
        }
      }
    }
  }
#endif

  policy::DeveloperToolsPolicyChecker* checker =
      policy::DeveloperToolsPolicyCheckerFactory::GetForBrowserContext(profile);
  if (checker) {
    auto url_availability = checker->GetDevToolsAvailabilityForUrl(url);
    switch (url_availability) {
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kAllowed:
        return true;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::
          kDisallowed:
        return false;
      case policy::DeveloperToolsPolicyChecker::DevToolsAvailability::kNotSet:
        // The URL is not covered by the URL-based policies, so we fall back to
        // the general enum-based policy.
        break;
    }
  }
  // If the URL-based policy doesn't have a rule for this URL, we fall back to
  // the general enum-based policy.
  using Availability = policy::DeveloperToolsAvailability;
  Availability availability = GetDevToolsAvailability(profile);
  switch (availability) {
    case Availability::kDisallowed:
      return false;
    case Availability::kAllowed:
    case Availability::kDisallowedForForceInstalledExtensions:
      return true;
    default:
      NOTREACHED() << "Unknown developer tools policy";
  }
}
