Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SameSite attribute in MockMvcHttpConnector #30260

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,14 @@
@SuppressWarnings("removal")
public class MockCookie extends Cookie {

private static final long serialVersionUID = 4312531139502726325L;
private static final long serialVersionUID = 1198809317225300389L;

private static final String SAME_SITE = "SameSite";
private static final String EXPIRES = "Expires";

@Nullable
private ZonedDateTime expires;

@Nullable
private String sameSite;


/**
* Construct a new {@link MockCookie} with the supplied name and value.
* @param name the name
Expand All @@ -64,7 +62,7 @@ public MockCookie(String name, String value) {
* @since 5.1.11
*/
public void setExpires(@Nullable ZonedDateTime expires) {
this.expires = expires;
setAttribute(EXPIRES, expires != null ? expires.format(DateTimeFormatter.RFC_1123_DATE_TIME) : null);
}

/**
Expand All @@ -85,7 +83,7 @@ public ZonedDateTime getExpires() {
* @see <a href="https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis#section-4.1.2.7">RFC6265 bis</a>
*/
public void setSameSite(@Nullable String sameSite) {
this.sameSite = sameSite;
setAttribute(SAME_SITE, sameSite);
}

/**
Expand All @@ -94,10 +92,9 @@ public void setSameSite(@Nullable String sameSite) {
*/
@Nullable
public String getSameSite() {
return this.sameSite;
return getAttribute(SAME_SITE);
}


/**
* Factory method that parses the value of the supplied "Set-Cookie" header.
* @param setCookieHeader the "Set-Cookie" value; never {@code null} or empty
Expand All @@ -122,7 +119,7 @@ public static MockCookie parse(String setCookieHeader) {
else if (StringUtils.startsWithIgnoreCase(attribute, "Max-Age")) {
cookie.setMaxAge(Integer.parseInt(extractAttributeValue(attribute, setCookieHeader)));
}
else if (StringUtils.startsWithIgnoreCase(attribute, "Expires")) {
else if (StringUtils.startsWithIgnoreCase(attribute, EXPIRES)) {
try {
cookie.setExpires(ZonedDateTime.parse(extractAttributeValue(attribute, setCookieHeader),
DateTimeFormatter.RFC_1123_DATE_TIME));
Expand All @@ -140,7 +137,7 @@ else if (StringUtils.startsWithIgnoreCase(attribute, "Secure")) {
else if (StringUtils.startsWithIgnoreCase(attribute, "HttpOnly")) {
cookie.setHttpOnly(true);
}
else if (StringUtils.startsWithIgnoreCase(attribute, "SameSite")) {
else if (StringUtils.startsWithIgnoreCase(attribute, SAME_SITE)) {
cookie.setSameSite(extractAttributeValue(attribute, setCookieHeader));
}
else if (StringUtils.startsWithIgnoreCase(attribute, "Comment")) {
Expand All @@ -157,6 +154,14 @@ private static String extractAttributeValue(String attribute, String header) {
return nameAndValue[1];
}

@Override
public void setAttribute(String name, @Nullable String value) {
if(EXPIRES.equalsIgnoreCase(name) && value != null) {
this.expires = ZonedDateTime.parse(value, DateTimeFormatter.RFC_1123_DATE_TIME);
}
super.setAttribute(name, value);
}

@Override
public String toString() {
return new ToStringCreator(this)
Expand All @@ -168,9 +173,9 @@ public String toString() {
.append("Comment", getComment())
.append("Secure", getSecure())
.append("HttpOnly", isHttpOnly())
.append("SameSite", this.sameSite)
.append(SAME_SITE, getSameSite())
.append("Max-Age", getMaxAge())
.append("Expires", (this.expires != null ?
.append(EXPIRES, (this.expires != null ?
DateTimeFormatter.RFC_1123_DATE_TIME.format(this.expires) : null))
.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ private MockClientHttpResponse adaptResponse(MvcResult mvcResult) {
.path(cookie.getPath())
.secure(cookie.getSecure())
.httpOnly(cookie.isHttpOnly())
.sameSite(cookie.getAttribute("samesite"))
.build();
clientResponse.getCookies().add(httpCookie.getName(), httpCookie);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,37 @@ void parseHeaderWithAttributesCaseSensitivity() {
assertThat(cookie.getSameSite()).isEqualTo("Lax");
}

@Test
void setSameSiteShouldSetAttribute() {
MockCookie cookie = new MockCookie("SESSION", "123");
cookie.setSameSite("Strict");

assertThat(cookie.getAttribute("samesite")).isEqualTo("Strict");
}

@Test
void setExpiresShouldSetAttribute() {
MockCookie cookie = new MockCookie("SESSION", "123");
cookie.setExpires(ZonedDateTime.parse("Tue, 8 Oct 2019 19:50:00 GMT",
DateTimeFormatter.RFC_1123_DATE_TIME));

assertThat(cookie.getAttribute("expires")).isEqualTo("Tue, 8 Oct 2019 19:50:00 GMT");
}

@Test
void setAttributeSameSiteShouldSetSameSite() {
MockCookie cookie = new MockCookie("SESSION", "123");
cookie.setAttribute("samesite", "Lax");

assertThat(cookie.getSameSite()).isEqualTo("Lax");
}

@Test
void setAttributeExpiresShouldSetExpires() {
MockCookie cookie = new MockCookie("SESSION", "123");
cookie.setAttribute("expires", "Tue, 8 Oct 2019 19:50:00 GMT");

assertThat(cookie.getExpires()).isEqualTo(ZonedDateTime.parse("Tue, 8 Oct 2019 19:50:00 GMT",
DateTimeFormatter.RFC_1123_DATE_TIME));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public void setup() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setCookieDomain("domain");
localeResolver.setCookieHttpOnly(true);
localeResolver.setCookieSameSite("Strict");

client = MockMvcWebTestClient.bindToController(new SimpleController())
.interceptors(new LocaleChangeInterceptor())
Expand Down Expand Up @@ -107,6 +108,10 @@ public void testHttpOnly() {
client.get().uri("/").exchange().expectCookie().httpOnly(COOKIE_NAME, true);
}

@Test
public void testSameSite() {
client.get().uri("/").exchange().expectCookie().sameSite(COOKIE_NAME, "Strict");
}

@Controller
private static class SimpleController {
Expand Down