View Javadoc
1   /*
2    * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.transport;
11  
12  import static org.hamcrest.MatcherAssert.assertThat;
13  
14  import java.io.File;
15  import java.io.IOException;
16  import java.net.HttpCookie;
17  import java.time.Instant;
18  import java.util.Arrays;
19  import java.util.Collections;
20  import java.util.Date;
21  import java.util.LinkedHashSet;
22  import java.util.Set;
23  
24  import org.eclipse.jgit.internal.transport.http.NetscapeCookieFile;
25  import org.eclipse.jgit.lib.Config;
26  import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
27  import org.eclipse.jgit.transport.http.HttpConnection;
28  import org.eclipse.jgit.util.http.HttpCookiesMatcher;
29  import org.junit.Assert;
30  import org.junit.Before;
31  import org.junit.Test;
32  import org.mockito.ArgumentMatchers;
33  import org.mockito.Mockito;
34  
35  public class TransportHttpTest extends SampleDataRepositoryTestCase {
36  	private URIish uri;
37  	private File cookieFile;
38  
39  	@Override
40  	@Before
41  	public void setUp() throws Exception {
42  		super.setUp();
43  		uri = new URIish("https://everyones.loves.git/u/2");
44  
45  		final Config config = db.getConfig();
46  		config.setBoolean("http", null, "saveCookies", true);
47  		cookieFile = createTempFile();
48  		config.setString("http", null, "cookieFile",
49  				cookieFile.getAbsolutePath());
50  	}
51  
52  	@Test
53  	public void testMatchesCookieDomain() {
54  		Assert.assertTrue(TransportHttp.matchesCookieDomain("example.com",
55  				"example.com"));
56  		Assert.assertTrue(TransportHttp.matchesCookieDomain("Example.Com",
57  				"example.cOM"));
58  		Assert.assertTrue(TransportHttp.matchesCookieDomain(
59  				"some.subdomain.example.com", "example.com"));
60  		Assert.assertFalse(TransportHttp
61  				.matchesCookieDomain("someotherexample.com", "example.com"));
62  		Assert.assertFalse(TransportHttp.matchesCookieDomain("example.com",
63  				"example1.com"));
64  		Assert.assertFalse(TransportHttp
65  				.matchesCookieDomain("sub.sub.example.com", ".example.com"));
66  		Assert.assertTrue(TransportHttp.matchesCookieDomain("host.example.com",
67  				"example.com"));
68  		Assert.assertTrue(TransportHttp.matchesCookieDomain(
69  				"something.example.com", "something.example.com"));
70  		Assert.assertTrue(TransportHttp.matchesCookieDomain(
71  				"host.something.example.com", "something.example.com"));
72  	}
73  
74  	@Test
75  	public void testMatchesCookiePath() {
76  		Assert.assertTrue(
77  				TransportHttp.matchesCookiePath("/some/path", "/some/path"));
78  		Assert.assertTrue(TransportHttp.matchesCookiePath("/some/path/child",
79  				"/some/path"));
80  		Assert.assertTrue(TransportHttp.matchesCookiePath("/some/path/child",
81  				"/some/path/"));
82  		Assert.assertFalse(TransportHttp.matchesCookiePath("/some/pathother",
83  				"/some/path"));
84  		Assert.assertFalse(
85  				TransportHttp.matchesCookiePath("otherpath", "/some/path"));
86  	}
87  
88  	@Test
89  	public void testProcessResponseCookies() throws IOException {
90  		HttpConnection connection = Mockito.mock(HttpConnection.class);
91  		Mockito.when(
92  				connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie")))
93  				.thenReturn(Arrays.asList(
94  						"id=a3fWa; Expires=Fri, 01 Jan 2100 11:00:00 GMT; Secure; HttpOnly",
95  						"sessionid=38afes7a8; HttpOnly; Path=/"));
96  		Mockito.when(
97  				connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie2")))
98  				.thenReturn(Collections
99  						.singletonList("cookie2=some value; Max-Age=1234; Path=/"));
100 
101 		try (TransportHttp transportHttp = new TransportHttp(db, uri)) {
102 			Date creationDate = new Date();
103 			transportHttp.processResponseCookies(connection);
104 
105 			// evaluate written cookie file
106 			Set<HttpCookie> expectedCookies = new LinkedHashSet<>();
107 
108 			HttpCookie cookie = new HttpCookie("id", "a3fWa");
109 			cookie.setDomain("everyones.loves.git");
110 			cookie.setPath("/u/2/");
111 
112 			cookie.setMaxAge(
113 					(Instant.parse("2100-01-01T11:00:00.000Z").toEpochMilli()
114 							- creationDate.getTime()) / 1000);
115 			cookie.setSecure(true);
116 			cookie.setHttpOnly(true);
117 			expectedCookies.add(cookie);
118 
119 			cookie = new HttpCookie("cookie2", "some value");
120 			cookie.setDomain("everyones.loves.git");
121 			cookie.setPath("/");
122 			cookie.setMaxAge(1234);
123 			expectedCookies.add(cookie);
124 
125 			assertThat(
126 					new NetscapeCookieFile(cookieFile.toPath())
127 							.getCookies(true),
128 					HttpCookiesMatcher.containsInOrder(expectedCookies, 5));
129 		}
130 	}
131 
132 	@Test
133 	public void testProcessResponseCookiesNotPersistingWithSaveCookiesFalse()
134 			throws IOException {
135 		HttpConnection connection = Mockito.mock(HttpConnection.class);
136 		Mockito.when(
137 				connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie")))
138 				.thenReturn(Arrays.asList(
139 						"id=a3fWa; Expires=Thu, 21 Oct 2100 11:00:00 GMT; Secure; HttpOnly",
140 						"sessionid=38afes7a8; HttpOnly; Path=/"));
141 		Mockito.when(
142 				connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie2")))
143 				.thenReturn(Collections.singletonList(
144 						"cookie2=some value; Max-Age=1234; Path=/"));
145 
146 		// tweak config
147 		final Config config = db.getConfig();
148 		config.setBoolean("http", null, "saveCookies", false);
149 
150 		try (TransportHttp transportHttp = new TransportHttp(db, uri)) {
151 			transportHttp.processResponseCookies(connection);
152 
153 			// evaluate written cookie file
154 			Assert.assertFalse("Cookie file was not supposed to be written!",
155 					cookieFile.exists());
156 		}
157 	}
158 }