// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_BASE_NETWORK_ISOLATION_KEY_H_
#define NET_BASE_NETWORK_ISOLATION_KEY_H_

#include <string>

#include "base/gtest_prod_util.h"
#include "base/unguessable_token.h"
#include "net/base/net_export.h"
#include "net/base/schemeful_site.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace url {
class Origin;
}

namespace network::mojom {
class FrameSiteEnabledNetworkIsolationKeyDataView;
class CrossSiteFlagEnabledNetworkIsolationKeyDataView;
}

namespace net {
class CookiePartitionKey;
}

namespace net {

// Key used to isolate shared network stack resources used by requests based on
// the context on which they were made.
class NET_EXPORT NetworkIsolationKey {
 public:
  class SerializationPasskey {
   private:
    friend struct mojo::StructTraits<
        network::mojom::FrameSiteEnabledNetworkIsolationKeyDataView,
        NetworkIsolationKey>;
    friend struct mojo::StructTraits<
        network::mojom::CrossSiteFlagEnabledNetworkIsolationKeyDataView,
        NetworkIsolationKey>;
    SerializationPasskey() = default;
    ~SerializationPasskey() = default;
  };

  class CookiePartitionKeyPasskey {
   private:
    friend class CookiePartitionKey;
    CookiePartitionKeyPasskey() = default;
    ~CookiePartitionKeyPasskey() = default;
  };

  // This constructor is used for deserialization when `GetMode()` returns
  // `kCrossSiteFlagEnabled`.
  NetworkIsolationKey(SerializationPasskey,
                      SchemefulSite top_frame_site,
                      SchemefulSite frame_site,
                      bool is_cross_site,
                      absl::optional<base::UnguessableToken> nonce);

  // Full constructor.  When a request is initiated by the top frame, it must
  // also populate the |frame_site| parameter when calling this constructor.
  NetworkIsolationKey(
      const SchemefulSite& top_frame_site,
      const SchemefulSite& frame_site,
      const absl::optional<base::UnguessableToken>& nonce = absl::nullopt);

  // Alternative constructor that takes ownership of arguments, to save copies.
  NetworkIsolationKey(
      SchemefulSite&& top_frame_site,
      SchemefulSite&& frame_site,
      absl::optional<base::UnguessableToken>&& nonce = absl::nullopt);

  // Legacy constructor.
  // TODO(https://crbug.com/1145294):  Remove this in favor of above
  // constructor.
  NetworkIsolationKey(const url::Origin& top_frame_origin,
                      const url::Origin& frame_origin);

  // Construct an empty key.
  NetworkIsolationKey();

  NetworkIsolationKey(const NetworkIsolationKey& network_isolation_key);
  NetworkIsolationKey(NetworkIsolationKey&& network_isolation_key);

  ~NetworkIsolationKey();

  NetworkIsolationKey& operator=(
      const NetworkIsolationKey& network_isolation_key);
  NetworkIsolationKey& operator=(NetworkIsolationKey&& network_isolation_key);

  // Creates a transient non-empty NetworkIsolationKey by creating an opaque
  // origin. This prevents the NetworkIsolationKey from sharing data with other
  // NetworkIsolationKeys. Data for transient NetworkIsolationKeys is not
  // persisted to disk.
  static NetworkIsolationKey CreateTransient();

  // Creates a new key using |top_frame_site_| and |new_frame_site|.
  NetworkIsolationKey CreateWithNewFrameSite(
      const SchemefulSite& new_frame_site) const;

  // Intended for temporary use in locations that should be using main frame and
  // frame origin, but are currently only using frame origin, because the
  // creating object may be shared across main frame objects. Having a special
  // constructor for these methods makes it easier to keep track of locating
  // callsites that need to have their NetworkIsolationKey filled in.
  static NetworkIsolationKey ToDoUseTopFrameOriginAsWell(
      const url::Origin& incorrectly_used_frame_origin) {
    return NetworkIsolationKey(incorrectly_used_frame_origin,
                               incorrectly_used_frame_origin);
  }

  // Compare keys for equality, true if all enabled fields are equal.
  bool operator==(const NetworkIsolationKey& other) const {
    if (GetMode() != Mode::kFrameSiteEnabled) {
      return std::tie(top_frame_site_, is_cross_site_, nonce_) ==
             std::tie(other.top_frame_site_, other.is_cross_site_,
                      other.nonce_);
    }
    return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) ==
           std::tie(other.top_frame_site_, other.frame_site_,
                    other.is_cross_site_, other.nonce_);
  }

  // Compare keys for inequality, true if any enabled field varies.
  bool operator!=(const NetworkIsolationKey& other) const {
    return !(*this == other);
  }

  // Provide an ordering for keys based on all enabled fields.
  bool operator<(const NetworkIsolationKey& other) const {
    if (GetMode() != Mode::kFrameSiteEnabled) {
      return std::tie(top_frame_site_, is_cross_site_, nonce_) <
             std::tie(other.top_frame_site_, other.is_cross_site_,
                      other.nonce_);
    }
    return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) <
           std::tie(other.top_frame_site_, other.frame_site_,
                    other.is_cross_site_, other.nonce_);
  }

  // Returns the string representation of the key for use in string-keyed disk
  // cache. This is the string representation of each piece of the key separated
  // by spaces. Returns nullopt if the network isolation key is transient, in
  // which case, nothing should typically be saved to disk using the key.
  absl::optional<std::string> ToCacheKeyString() const;

  // Returns string for debugging. Difference from ToString() is that transient
  // entries may be distinguishable from each other.
  std::string ToDebugString() const;

  // Returns true if all parts of the key are non-empty.
  bool IsFullyPopulated() const;

  // Returns true if this key's lifetime is short-lived, or if
  // IsFullyPopulated() returns true. It may not make sense to persist state to
  // disk related to it (e.g., disk cache).
  bool IsTransient() const;

  // Getters for the top frame and frame sites. These accessors are primarily
  // intended for IPC calls, and to be able to create an IsolationInfo from a
  // NetworkIsolationKey.
  const absl::optional<SchemefulSite>& GetTopFrameSite() const {
    return top_frame_site_;
  }

  enum class Mode {
    // This scheme indicates that "triple-key" NetworkIsolationKeys are used to
    // partition the HTTP cache. This key will have the following properties:
    // `top_frame_site` -> the schemeful site of the top level page.
    // `frame_site ` -> the schemeful site of the frame.
    // `is_cross_site` -> absl::nullopt.
    kFrameSiteEnabled,
    // This scheme indicates that "2.5-key" NetworkIsolationKeys are used to
    // partition the HTTP cache. This key will have the following properties:
    // `top_frame_site_` -> the schemeful site of the top level page.
    // `frame_site_` -> should only be accessed for serialization or building
    // nonced CookiePartitionKeys.
    // `is_cross_site_` -> a boolean indicating whether the frame site is
    // schemefully cross-site from the top-level site.
    kCrossSiteFlagEnabled,
  };

  // Returns the cache key scheme currently in use.
  static Mode GetMode();

  // Getter for `frame_site_`. Will return absl::nullopt if the
  // `NetworkIsolationKey` is empty.
  // Note: This will CHECK if `GetMode()` does not return `kFrameSiteEnabled`.
  const absl::optional<SchemefulSite>& GetFrameSite() const;

  // Do not use outside of testing. Returns the `frame_site_`.
  const absl::optional<SchemefulSite> GetFrameSiteForTesting() const {
    if (GetMode() == Mode::kCrossSiteFlagEnabled) {
      return absl::nullopt;
    }
    return frame_site_;
  }

  // Getter for the boolean indicating that `frame_site_` is cross-site from
  // `top_frame_site_`. If the `NetworkIsolationKey` is empty, this will return
  // absl::nullopt.
  // Note: This will CHECK if `GetMode()` does not return
  // `kCrossSiteFlagEnabled`.
  absl::optional<bool> GetIsCrossSite() const;

  // When serializing a NIK for sending via mojo we want to access the frame
  // site directly. We don't want to expose this broadly, though, hence the
  // passkey.
  const absl::optional<SchemefulSite>& GetFrameSiteForSerialization(
      SerializationPasskey) const {
    CHECK(!IsEmpty());
    return frame_site_;
  }
  // We also need to access the frame site directly when constructing
  // CookiePartitionKey for nonced partitions. We also use a passkey for this
  // case.
  const absl::optional<SchemefulSite>& GetFrameSiteForCookiePartitionKey(
      CookiePartitionKeyPasskey) const {
    CHECK(!IsEmpty());
    return frame_site_;
  }

  // Same as above but for the is-cross-site bit.
  const absl::optional<bool>& GetIsCrossSiteForSerialization(
      SerializationPasskey) const {
    CHECK(!IsEmpty());
    CHECK_EQ(GetMode(), Mode::kCrossSiteFlagEnabled);
    return is_cross_site_;
  }

  // Getter for the nonce.
  const absl::optional<base::UnguessableToken>& GetNonce() const {
    return nonce_;
  }

  // Returns true if all parts of the key are empty.
  bool IsEmpty() const;

 private:
  // Whether this key has opaque origins or a nonce.
  bool IsOpaque() const;

  // The origin/etld+1 of the top frame of the page making the request.
  absl::optional<SchemefulSite> top_frame_site_;

  // The origin/etld+1 of the frame that initiates the request.
  absl::optional<SchemefulSite> frame_site_;

  // A boolean indicating whether the frame origin is cross-site from the
  // top-level origin. This will be used for experiments to determine the
  // the difference in performance between partitioning the HTTP cache using the
  // top-level origin and frame origin ("triple-keying") vs. the top-level
  // origin and an is-cross-site bit ("2.5-keying") like the
  // `NetworkAnonymizationKey` uses for network state partitioning. This will be
  // absl::nullopt when `GetMode()` returns `Mode::kFrameSiteEnabled`, or for an
  // empty `NetworkIsolationKey`.
  absl::optional<bool> is_cross_site_;

  // Having a nonce is a way to force a transient opaque `NetworkIsolationKey`
  // for non-opaque origins.
  absl::optional<base::UnguessableToken> nonce_;
};

}  // namespace net

#endif  // NET_BASE_NETWORK_ISOLATION_KEY_H_
