// Copyright 2017 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.

module safe_browsing.mojom;

import "content/public/common/resource_type.mojom";
import "services/network/public/mojom/http_request_headers.mojom";
import "url/mojom/url.mojom";

// Provided by the browser and used by renderers to perform SafeBrowsing URL
// checks.
interface SafeBrowsing {
  // Queries SafeBrowsing whether |url| is safe to load, and creates a
  // SafeBrowsingUrlChecker interface.
  //
  // The check and (subsequent checks performed using SafeBrowsingUrlChecker)
  // checks against SafeBrowsing's Malware, Phishing, and UwS blacklists.
  //
  // The SafeBrowsingUrlChecker interface should be used (and only used) for
  // subsequent checks of redirects, so that the server side could keep track of
  // the redirect chain. Disconnecting the checker interface cancels on-going
  // URL checks. Please note that in that case if the check started by this
  // method hasn't completed yet, it will also be canceled and the callback is
  // ran with |proceed == true| and |showed_interstitial == false| as if the URL
  // is safe.
  //
  // If |slow_check_notifier| is a valid interface request, it indicates that
  // the URL may be unsafe and a more time-consuming process is required to get
  // the final result. In that case, the rest of the callback arguments should
  // be ignored. The result will be reported using the UrlCheckNotifier
  // interface. Receiving a valid |slow_check_notifier| could be considered as
  // a singal that the resource should be handled with more caution until the
  // final result is obtained. For example, the network service may want to
  // pause reading the response body for MIME sniffing.
  //
  // |proceed| indicates whether it is okay to proceed with loading the URL.
  // |showed_interstitial| indicates whether the SafeBrowsing interstitial page
  // has been shown to the user.
  CreateCheckerAndCheck(
      int32 render_frame_id,
      SafeBrowsingUrlChecker& request,
      url.mojom.Url url,
      string method,
      network.mojom.HttpRequestHeaders headers,
      int32 load_flags,
      content.mojom.ResourceType resource_type,
      bool has_user_gesture,
      bool originated_from_service_worker)
          => (UrlCheckNotifier&? slow_check_notifier,
              bool proceed,
              bool showed_interstitial);

  // Bind an additional pipe to this instance of the SafeBrowsing interface.
  Clone(SafeBrowsing& request);
};

interface SafeBrowsingUrlChecker {
  CheckUrl(url.mojom.Url url, string method)
      => (UrlCheckNotifier&? slow_check_notifier,
          bool proceed,
          bool showed_interstitial);
};

interface UrlCheckNotifier {
  OnCompleteCheck(bool proceed, bool showed_interstitial);
};

// Used to store the name and value of an HTML Element's attribute.
struct AttributeNameValue {
  string name;
  string value;
};

// A node is essentially a frame.
struct ThreatDOMDetailsNode {
  // A unique ID for this node, unique to the current Render Frame.
  int32 node_id;
  // URL of this resource. Can be empty.
  url.mojom.Url url;
  // If this resource was in the "src" attribute of a tag, this is the tagname
  // (eg "IFRAME"). Can be empty.
  string tag_name;
  // URL of the parent node. Can be empty.
  url.mojom.Url parent;
  // The unique ID of the parent node. Can be 0 if this is the top node.
  int32 parent_node_id;
  // Children of this node. Can be empty.
  array<url.mojom.Url> children;
  // The unique IDs of the child nodes. Can be empty if there are no children.
  array<int32> child_node_ids;
  // The node's attributes as a collection of name-value pairs.
  array<AttributeNameValue> attributes;
  // If this node represents a frame or iframe, then this field is set to the
  // routing ID of the local or remote frame in this renderer process that is
  // responsible for rendering the contents of this frame (to handle OOPIFs).
  int32 child_frame_routing_id;
};

interface ThreatReporter {
  // Client-side detection message sent from the browser to the renderer.
  // Request a DOM tree when a safe browsing interstitial is shown.
  // Renderer returns part of the DOM to be used in a threat report.
  GetThreatDOMDetails() => (array<ThreatDOMDetailsNode> nodes);
};

[EnableIf=full_safe_browsing]
interface PhishingDetector {
  // Tells the renderer to begin phishing detection for the given toplevel URL
  // which it has started loading
  StartPhishingDetection(url.mojom.Url url);
};

[EnableIf=full_safe_browsing]
interface PhishingDetectorClient {
  // Inform the browser that the client-side phishing detector running in the
  // renderer is done classifying the current URL.  If the URL is phishing
  // the request proto will have |is_phishing()| set to true.
  // TODO(noelutz): we may want to create custom ParamTraits for MessageLite to
  // have a generic way to send protocol messages over IPC.
  PhishingDetectionDone(string request_proto);
};

interface PhishingModelSetter {
  // A classification model for client-side phishing detection.
  // The string is an encoded safe_browsing::ClientSideModel protocol buffer, or
  // empty to disable client-side phishing detection for this renderer.
  SetPhishingModel(string model);
};