Repository: pallets/werkzeug

Issue:
SameSite value of 'None' not supported
Google's recent [blog post](https://blog.chromium.org/2019/05/improving-privacy-and-security-on-web.html
) describes changes on how they will enforce Cookies with SameSite value. The referenced [samesite cookies explained article](https://web.dev/samesite-cookies-explained/) and [RFC](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1) both describe the ability to specify a SameSite value of 'None' the string (as opposed to None, not set) for SameSite.

The following today produces an error stating _invalid SameSite value; must be 'Strict', 'Lax' or None_
```python
resp.set_cookie('somekey', 'someval', domain='.mydomain.com', samesite='None')
```

You would think setting ```None``` would work but instead it unsets the key and prevents the samesite attribute from being present with a None (string) value in the headers.
```python
resp.set_cookie('somekey', 'someval', domain='.mydomain.com', samesite=None)
```
 


Discussion:

Resolving patch:
diff --git a/src/werkzeug/http.py b/src/werkzeug/http.py
--- a/src/werkzeug/http.py
+++ b/src/werkzeug/http.py
@@ -1135,10 +1135,13 @@ def dump_cookie(
     :param max_size: Warn if the final header value exceeds this size. The
         default, 4093, should be safely `supported by most browsers
         <cookie_>`_. Set to 0 to disable this check.
-    :param samesite: Limits the scope of the cookie such that it will only
-                     be attached to requests if those requests are "same-site".
+    :param samesite: Limits the scope of the cookie such that it will
+        only be attached to requests if those requests are same-site.
 
     .. _`cookie`: http://browsercookielimits.squawky.net/
+
+    .. versionchanged:: 1.0.0
+        The string ``'None'`` is accepted for ``samesite``.
     """
     key = to_bytes(key, charset)
     value = to_bytes(value, charset)
@@ -1154,9 +1157,11 @@ def dump_cookie(
     elif max_age is not None and sync_expires:
         expires = to_bytes(cookie_date(time() + max_age))
 
-    samesite = samesite.title() if samesite else None
-    if samesite not in ("Strict", "Lax", None):
-        raise ValueError("invalid SameSite value; must be 'Strict', 'Lax' or None")
+    if samesite is not None:
+        samesite = samesite.title()
+
+        if samesite not in {"Strict", "Lax", "None"}:
+            raise ValueError("SameSite must be 'Strict', 'Lax', or 'None'.")
 
     buf = [key + b"=" + _cookie_quote(value)]
 


Test patch:
diff --git a/tests/test_http.py b/tests/test_http.py
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -543,16 +543,21 @@ def test_cookie_maxsize(self, recwarn):
         assert "the limit is 512 bytes" in str(w.message)
 
     @pytest.mark.parametrize(
-        "input, expected",
-        [
+        ("samesite", "expected"),
+        (
             ("strict", "foo=bar; Path=/; SameSite=Strict"),
             ("lax", "foo=bar; Path=/; SameSite=Lax"),
+            ("none", "foo=bar; Path=/; SameSite=None"),
             (None, "foo=bar; Path=/"),
-        ],
+        ),
     )
-    def test_cookie_samesite_attribute(self, input, expected):
-        val = http.dump_cookie("foo", "bar", samesite=input)
-        strict_eq(val, expected)
+    def test_cookie_samesite_attribute(self, samesite, expected):
+        value = http.dump_cookie("foo", "bar", samesite=samesite)
+        assert value == expected
+
+    def test_cookie_samesite_invalid(self):
+        with pytest.raises(ValueError):
+            http.dump_cookie("foo", "bar", samesite="invalid")
 
 
 class TestRange(object):