#ifndef NET_DEVICE_BOUND_SESSIONS_SESSION_H_
#define NET_DEVICE_BOUND_SESSIONS_SESSION_H_
#include <memory>
#include <optional>
#include <string>
#include "components/unexportable_keys/service_error.h"
#include "components/unexportable_keys/unexportable_key_id.h"
#include "net/base/backoff_entry.h"
#include "net/base/net_export.h"
#include "net/device_bound_sessions/cookie_craving.h"
#include "net/device_bound_sessions/session_error.h"
#include "net/device_bound_sessions/session_inclusion_rules.h"
#include "net/device_bound_sessions/session_key.h"
#include "net/device_bound_sessions/session_params.h"
#include "url/gurl.h"
namespace net {
class URLRequest;
class FirstPartySetMetadata;
}
namespace net::device_bound_sessions {
namespace proto {
class Session;
}
class NET_EXPORT Session {
public:
using Id = SessionKey::Id;
using KeyIdOrError =
unexportable_keys::ServiceErrorOr<unexportable_keys::UnexportableKeyId>;
Session(const Session& other) = delete;
Session& operator=(const Session& other) = delete;
Session(Session&& other) noexcept = delete;
Session& operator=(Session&& other) noexcept = delete;
~Session();
static base::expected<std::unique_ptr<Session>, SessionError> CreateIfValid(
const SessionParams& params);
static std::unique_ptr<Session> CreateFromProto(const proto::Session& proto);
proto::Session ToProto() const;
void set_unexportable_key_id(KeyIdOrError key_id_or_error) {
key_id_or_error_ = std::move(key_id_or_error);
}
const KeyIdOrError& unexportable_key_id() const { return key_id_or_error_; }
bool IsInScope(URLRequest* request);
base::TimeDelta MinimumBoundCookieLifetime(
URLRequest* request,
const FirstPartySetMetadata& first_party_set_metadata);
const Id& id() const { return id_; }
const GURL& refresh_url() const { return refresh_url_; }
const std::optional<std::string>& cached_challenge() const {
return cached_challenge_;
}
base::Time creation_date() const { return creation_date_; }
base::Time expiry_date() const { return expiry_date_; }
bool should_defer_when_expired() const { return should_defer_when_expired_; }
const std::vector<CookieCraving>& cookies() const { return cookie_cravings_; }
bool attempted_proactive_refresh_since_last_success() const {
return attempted_proactive_refresh_since_last_success_;
}
bool IsEqualForTesting(const Session& other) const;
void set_cached_challenge(std::string challenge) {
cached_challenge_ = std::move(challenge);
}
void set_creation_date(base::Time creation_date) {
creation_date_ = creation_date;
}
void set_expiry_date(base::Time expiry_date) { expiry_date_ = expiry_date; }
void RecordAccess();
bool IncludesUrl(const GURL& url) const;
bool AllowedToInitiateRefresh(
const std::optional<url::Origin>& initiator) const;
bool ShouldBackoff() const;
void InformOfRefreshResult(bool was_proactive,
SessionError::ErrorType error_type);
bool CanSetBoundCookie(
const URLRequest& request,
const FirstPartySetMetadata& first_party_set_metadata) const;
const url::Origin& origin() const { return inclusion_rules_.origin(); }
const std::vector<std::string>& allowed_refresh_initiators() {
return allowed_refresh_initiators_;
}
void set_allowed_refresh_initiators(
std::vector<std::string> allowed_refresh_initiators) {
allowed_refresh_initiators_ = std::move(allowed_refresh_initiators);
}
std::optional<base::Time> TakeLastProactiveRefreshOpportunity();
std::optional<base::TimeDelta>
TakeLastProactiveRefreshOpportunityMinimumCookieLifetime();
private:
Session(Id id, SessionInclusionRules inclusion_rules, GURL refresh);
Session(Id id,
GURL refresh,
SessionInclusionRules inclusion_rules,
std::vector<CookieCraving> cookie_cravings,
bool should_defer_when_expired,
base::Time creation_date,
base::Time expiry_date,
std::vector<std::string> allowed_refresh_initiators);
const Id id_;
const GURL refresh_url_;
SessionInclusionRules inclusion_rules_;
std::vector<CookieCraving> cookie_cravings_;
bool should_defer_when_expired_ = true;
base::Time creation_date_;
base::Time expiry_date_;
KeyIdOrError key_id_or_error_ =
base::unexpected(unexportable_keys::ServiceError::kKeyNotReady);
std::optional<std::string> cached_challenge_;
net::BackoffEntry backoff_;
std::vector<std::string> allowed_refresh_initiators_;
std::optional<base::Time> last_proactive_refresh_opportunity_;
std::optional<base::TimeDelta>
last_proactive_refresh_opportunity_minimum_cookie_lifetime_;
bool attempted_proactive_refresh_since_last_success_ = false;
};
}
#endif