feat: expose the sameSite value for cookies (#22789)

* feat: expose the sameSite value for cookies

* Apply suggestions from code review

Co-Authored-By: Charles Kerr <ckerr@github.com>

* Apply suggestions from code review

Align with cookie samesite values for the extensions API

https://developer.chrome.com/extensions/cookies#type-SameSiteStatus

* chore: add tests for sameSite cookies get/set

* chore: update docs parser

* chore: update docs for MessageChannel and MessagePort to have correct process information

* chore: remove LOG warning

* chore: throw error if the string->samesite conversion fails

Co-authored-by: Charles Kerr <ckerr@github.com>
This commit is contained in:
Samuel Attard 2020-04-02 11:28:43 -07:00 committed by GitHub
parent 2ce8dff175
commit 1d158399a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 260 additions and 33 deletions

View file

@ -29,6 +29,25 @@ using content::BrowserThread;
namespace gin {
template <>
struct Converter<net::CookieSameSite> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CookieSameSite& val) {
switch (val) {
case net::CookieSameSite::UNSPECIFIED:
return ConvertToV8(isolate, "unspecified");
case net::CookieSameSite::NO_RESTRICTION:
return ConvertToV8(isolate, "no_restriction");
case net::CookieSameSite::LAX_MODE:
return ConvertToV8(isolate, "lax");
case net::CookieSameSite::STRICT_MODE:
return ConvertToV8(isolate, "strict");
}
DCHECK(false);
return ConvertToV8(isolate, "unknown");
}
};
template <>
struct Converter<net::CanonicalCookie> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
@ -44,6 +63,7 @@ struct Converter<net::CanonicalCookie> {
dict.Set("session", !val.IsPersistent());
if (val.IsPersistent())
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
dict.Set("sameSite", val.SameSite());
return ConvertToV8(isolate, dict).As<v8::Object>();
}
};
@ -171,6 +191,28 @@ std::string InclusionStatusToString(
return "Setting cookie failed";
}
std::string StringToCookieSameSite(const std::string* str_ptr,
net::CookieSameSite* same_site) {
if (!str_ptr) {
*same_site = net::CookieSameSite::NO_RESTRICTION;
return "";
}
const std::string& str = *str_ptr;
if (str == "unspecified") {
*same_site = net::CookieSameSite::UNSPECIFIED;
} else if (str == "no_restriction") {
*same_site = net::CookieSameSite::NO_RESTRICTION;
} else if (str == "lax") {
*same_site = net::CookieSameSite::LAX_MODE;
} else if (str == "strict") {
*same_site = net::CookieSameSite::STRICT_MODE;
} else {
return "Failed to convert '" + str +
"' to an appropriate cookie same site value";
}
return "";
}
} // namespace
gin::WrapperInfo Cookies::kWrapperInfo = {gin::kEmbedderNativeGin};
@ -254,6 +296,13 @@ v8::Local<v8::Promise> Cookies::Set(v8::Isolate* isolate,
const std::string* path = details.FindStringKey("path");
bool secure = details.FindBoolKey("secure").value_or(false);
bool http_only = details.FindBoolKey("httpOnly").value_or(false);
const std::string* same_site_string = details.FindStringKey("sameSite");
net::CookieSameSite same_site;
std::string error = StringToCookieSameSite(same_site_string, &same_site);
if (!error.empty()) {
promise.RejectWithErrorMessage(error);
return handle;
}
GURL url(url_string ? *url_string : "");
if (!url.is_valid()) {
@ -270,8 +319,7 @@ v8::Local<v8::Promise> Cookies::Set(v8::Isolate* isolate,
ParseTimeProperty(details.FindDoubleKey("creationDate")),
ParseTimeProperty(details.FindDoubleKey("expirationDate")),
ParseTimeProperty(details.FindDoubleKey("lastAccessDate")), secure,
http_only, net::CookieSameSite::NO_RESTRICTION,
net::COOKIE_PRIORITY_DEFAULT);
http_only, same_site, net::COOKIE_PRIORITY_DEFAULT);
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
promise.RejectWithErrorMessage(
InclusionStatusToString(net::CanonicalCookie::CookieInclusionStatus(
@ -283,6 +331,8 @@ v8::Local<v8::Promise> Cookies::Set(v8::Isolate* isolate,
if (http_only) {
options.set_include_httponly();
}
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
auto* storage_partition =
content::BrowserContext::GetDefaultStoragePartition(browser_context_);