// Copyright (c) 2012 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/extensions/active_tab_permission_granter.h"

#include <set>
#include <utility>
#include <vector>

#include "base/no_destructor.h"
#include "chrome/browser/extensions/extension_action_runner.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/user_script.h"
#include "url/gurl.h"

namespace extensions {

namespace {

using CreateMessageFunction = base::Callback<IPC::Message*(bool)>;

// Creates a new IPC message for updating tab-specific permissions.
IPC::Message* CreateUpdateMessage(const GURL& visible_url,
                                  const std::string& extension_id,
                                  const URLPatternSet& new_hosts,
                                  int tab_id,
                                  bool update_whitelist) {
  return new ExtensionMsg_UpdateTabSpecificPermissions(
      visible_url, extension_id, new_hosts, update_whitelist, tab_id);
}

// Creates a new IPC message for clearing tab-specific permissions.
IPC::Message* CreateClearMessage(const std::vector<std::string>& ids,
                                 int tab_id,
                                 bool update_whitelist) {
  return new ExtensionMsg_ClearTabSpecificPermissions(
      ids, update_whitelist, tab_id);
}

// Sends a message exactly once to each render process host owning one of the
// given |frame_hosts| and |tab_process|. If |tab_process| doesn't own any of
// the |frame_hosts|, it will not be signaled to update its origin whitelist.
void SendMessageToProcesses(
    const std::set<content::RenderFrameHost*>& frame_hosts,
    content::RenderProcessHost* tab_process,
    const CreateMessageFunction& create_message) {
  std::set<content::RenderProcessHost*> sent_to_hosts;
  for (content::RenderFrameHost* frame_host : frame_hosts) {
    content::RenderProcessHost* process_host = frame_host->GetProcess();
    if (sent_to_hosts.count(process_host) == 0) {
      // Extension processes have to update the origin whitelists.
      process_host->Send(create_message.Run(true));
      sent_to_hosts.insert(frame_host->GetProcess());
    }
  }
  // If the tab wasn't one of those processes already updated (it likely
  // wasn't), update it. Tabs don't need to update the origin whitelist.
  if (sent_to_hosts.count(tab_process) == 0)
    tab_process->Send(create_message.Run(false));
}

std::unique_ptr<ActiveTabPermissionGranter::Delegate>&
GetActiveTabPermissionGranterDelegateWrapper() {
  static base::NoDestructor<
      std::unique_ptr<ActiveTabPermissionGranter::Delegate>>
      delegate_wrapper;
  return *delegate_wrapper;
}

ActiveTabPermissionGranter::Delegate* GetActiveTabPermissionGranterDelegate() {
  return GetActiveTabPermissionGranterDelegateWrapper().get();
}

// Returns true if activeTab is allowed to be granted to the extension. This can
// return false for platform-specific implementations.
bool ShouldGrantActiveTabOrPrompt(const Extension* extension,
                                  content::WebContents* web_contents) {
  return !GetActiveTabPermissionGranterDelegate() ||
         GetActiveTabPermissionGranterDelegate()->ShouldGrantActiveTabOrPrompt(
             extension, web_contents);
}

}  // namespace

ActiveTabPermissionGranter::ActiveTabPermissionGranter(
    content::WebContents* web_contents,
    int tab_id,
    Profile* profile)
    : content::WebContentsObserver(web_contents),
      tab_id_(tab_id),
      extension_registry_observer_(this) {
  extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
}

ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {}

// static
void ActiveTabPermissionGranter::SetPlatformDelegate(
    std::unique_ptr<Delegate> delegate) {
  GetActiveTabPermissionGranterDelegateWrapper() = std::move(delegate);
}

void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) {
  if (granted_extensions_.Contains(extension->id()))
    return;

  APIPermissionSet new_apis;
  URLPatternSet new_hosts;

  const PermissionsData* permissions_data = extension->permissions_data();

  // TODO(devlin): This should be GetLastCommittedURL().
  GURL url = web_contents()->GetVisibleURL();

  // If the extension requested the host permission to |url| but had it
  // withheld, we grant it active tab-style permissions, even if it doesn't have
  // the activeTab permission in the manifest. This is necessary for the
  // runtime host permissions feature to work.
  // Note: It's important that we check if the extension has activeTab before
  // checking ShouldGrantActiveTabOrPrompt() in order to prevent
  // ShouldGrantActiveTabOrPrompt() from prompting for extensions that don't
  // request the activeTab permission.
  if ((permissions_data->HasAPIPermission(APIPermission::kActiveTab) ||
       permissions_data->withheld_permissions().effective_hosts().MatchesURL(
           url)) &&
      ShouldGrantActiveTabOrPrompt(extension, web_contents())) {
    // Gate activeTab for file urls on extensions having explicit access to file
    // urls.
    int valid_schemes = UserScript::ValidUserScriptSchemes();
    if (!util::AllowFileAccess(extension->id(),
                               web_contents()->GetBrowserContext())) {
      valid_schemes &= ~URLPattern::SCHEME_FILE;
    }
    new_hosts.AddOrigin(valid_schemes, url.GetOrigin());
    new_apis.insert(APIPermission::kTab);
  }

  if (permissions_data->HasAPIPermission(APIPermission::kTabCapture))
    new_apis.insert(APIPermission::kTabCaptureForTab);

  if (!new_apis.empty() || !new_hosts.is_empty()) {
    granted_extensions_.Insert(extension);
    PermissionSet new_permissions(new_apis, ManifestPermissionSet(), new_hosts,
                                  new_hosts);
    permissions_data->UpdateTabSpecificPermissions(tab_id_, new_permissions);
    const content::NavigationEntry* navigation_entry =
        web_contents()->GetController().GetVisibleEntry();
    if (navigation_entry) {
      // We update all extension render views with the new tab permissions, and
      // also the tab itself.
      CreateMessageFunction update_message =
          base::Bind(&CreateUpdateMessage,
                     navigation_entry->GetURL(),
                     extension->id(),
                     new_hosts,
                     tab_id_);
      SendMessageToProcesses(
          ProcessManager::Get(web_contents()->GetBrowserContext())
              ->GetRenderFrameHostsForExtension(extension->id()),
          web_contents()->GetMainFrame()->GetProcess(), update_message);

      // If more things ever need to know about this, we should consider making
      // an observer class.
      // It's important that this comes after the IPC is sent to the renderer,
      // so that any tasks executing in the renderer occur after it has the
      // updated permissions.
      ExtensionActionRunner::GetForWebContents(web_contents())
          ->OnActiveTabPermissionGranted(extension);
    }
  }
}

void ActiveTabPermissionGranter::RevokeForTesting() {
  ClearActiveExtensionsAndNotify();
}

void ActiveTabPermissionGranter::DidFinishNavigation(
    content::NavigationHandle* navigation_handle) {
  // Important: sub-frames don't get granted!
  if (!navigation_handle->IsInMainFrame() ||
      !navigation_handle->HasCommitted() ||
      navigation_handle->IsSameDocument()) {
    return;
  }

  // Only clear the granted permissions for cross-origin navigations.
  // TODO(devlin): We likely shouldn't be using the visible entry. Instead,
  // we should use WebContents::GetLastCommittedURL().
  const content::NavigationEntry* navigation_entry =
      web_contents()->GetController().GetVisibleEntry();
  if (navigation_entry && navigation_entry->GetURL().GetOrigin() ==
                              navigation_handle->GetPreviousURL().GetOrigin()) {
    return;
  }

  ClearActiveExtensionsAndNotify();
}

void ActiveTabPermissionGranter::WebContentsDestroyed() {
  ClearActiveExtensionsAndNotify();
}

void ActiveTabPermissionGranter::OnExtensionUnloaded(
    content::BrowserContext* browser_context,
    const Extension* extension,
    UnloadedExtensionReason reason) {
  // Note: don't need to clear the permissions (nor tell the renderer about it)
  // because it's being unloaded anyway.
  granted_extensions_.Remove(extension->id());
}

void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() {
  if (granted_extensions_.is_empty())
    return;

  std::set<content::RenderFrameHost*> frame_hosts;
  std::vector<std::string> extension_ids;
  ProcessManager* process_manager =
      ProcessManager::Get(web_contents()->GetBrowserContext());
  for (const scoped_refptr<const Extension>& extension : granted_extensions_) {
    extension->permissions_data()->ClearTabSpecificPermissions(tab_id_);
    extension_ids.push_back(extension->id());
    std::set<content::RenderFrameHost*> extension_frame_hosts =
        process_manager->GetRenderFrameHostsForExtension(extension->id());
    frame_hosts.insert(extension_frame_hosts.begin(),
                       extension_frame_hosts.end());
  }

  CreateMessageFunction clear_message =
      base::Bind(&CreateClearMessage, extension_ids, tab_id_);
  SendMessageToProcesses(
      frame_hosts, web_contents()->GetMainFrame()->GetProcess(), clear_message);

  granted_extensions_.Clear();
}

}  // namespace extensions
