Repository navigation
Expand file tree
/
Copy pathSetupAuthTest.java
More file actions
179 lines (152 loc) · 6.12 KB
/
Copy pathSetupAuthTest.java
File metadata and controls
179 lines (152 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package servlets;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import dbProcs.Constants;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import testUtils.TestProperties;
/** Regression tests for GHSA-m4gj-wcx8-jjr7: the setup token check and the installed-state gate. */
public class SetupAuthTest {
private static final Logger log = LogManager.getLogger(SetupAuthTest.class);
private static final String TOKEN = "3f1c2a9e-6b0d-4c8e-9a51-7d2e4b6f8c10";
private static final ResourceBundle bundle =
ResourceBundle.getBundle("i18n.text", Locale.ENGLISH);
@BeforeAll
public static void initAll() {
TestProperties.setTestPropertiesFileDirectory(log);
}
@BeforeEach
public void setUp() throws IOException {
Files.createDirectories(Paths.get(Constants.CATALINA_CONF));
// Without database.properties, doPost takes the fresh-install path and connects to the
// database given in the request: reaching that connection means the token check passed
TestProperties.deleteMysqlResource();
deleteAuthFile();
Setup.resetInstalledCache();
}
@AfterEach
public void tearDown() {
deleteAuthFile();
Setup.resetInstalledCache();
}
private static void deleteAuthFile() {
FileUtils.deleteQuietly(new File(Constants.SETUP_AUTH));
}
private static void writeAuthFile(String content) throws IOException {
Files.write(Paths.get(Constants.SETUP_AUTH), content.getBytes(StandardCharsets.UTF_8));
}
private static void markInstalled() throws ReflectiveOperationException {
Field installed = Setup.class.getDeclaredField("installedCached");
installed.setAccessible(true);
installed.set(null, Boolean.TRUE);
}
/** A setup request against a closed local port, so any connection attempt fails quickly. */
private static MockHttpServletRequest setupRequest(String dbAuth) {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/setup");
request.addParameter("dbhost", "127.0.0.1");
request.addParameter("dbport", "1");
request.addParameter("dbuser", "root");
request.addParameter("dbpass", "");
request.addParameter("dboverride", "override");
request.addParameter("mhost", "127.0.0.1");
request.addParameter("mport", "27017");
if (dbAuth != null) {
request.addParameter("dbauth", dbAuth);
}
return request;
}
private static MockHttpServletResponse post(MockHttpServletRequest request) throws Exception {
MockHttpServletResponse response = new MockHttpServletResponse();
new Setup().doPost(request, response);
return response;
}
private static void assertRejectedBeforeConnecting(MockHttpServletResponse response)
throws IOException {
String body = response.getContentAsString();
assertTrue(
body.contains(bundle.getString("generic.text.setup.authentication.failed")),
"Expected an authentication failure, got: " + body);
assertFalse(
body.contains(bundle.getString("generic.text.setup.connection.failed")),
"Setup tried to connect to the database without a valid token: " + body);
}
@Test
public void isValidSetupAuth_noTokenFile_failsClosed() {
assertFalse(Setup.isValidSetupAuth(""));
assertFalse(Setup.isValidSetupAuth(null));
assertFalse(Setup.isValidSetupAuth(TOKEN));
}
@Test
public void isValidSetupAuth_emptyTokenFile_failsClosed() throws IOException {
writeAuthFile("\n");
assertFalse(Setup.isValidSetupAuth(""));
assertFalse(Setup.isValidSetupAuth(" "));
assertFalse(Setup.isValidSetupAuth(null));
}
@Test
public void isValidSetupAuth_matchesOnlyTheToken() throws IOException {
writeAuthFile(TOKEN + "\n");
assertTrue(Setup.isValidSetupAuth(TOKEN));
assertFalse(Setup.isValidSetupAuth(""));
assertFalse(Setup.isValidSetupAuth(TOKEN.substring(1)));
assertFalse(Setup.isValidSetupAuth(TOKEN + "0"));
}
@Test
public void doPost_emptyAuthAndNoTokenFile_isRejectedBeforeConnecting() throws Exception {
assertRejectedBeforeConnecting(post(setupRequest("")));
}
@Test
public void doPost_missingAuthAndNoTokenFile_isRejectedBeforeConnecting() throws Exception {
assertRejectedBeforeConnecting(post(setupRequest(null)));
}
@Test
public void doPost_emptyAuthAndEmptyTokenFile_isRejectedBeforeConnecting() throws Exception {
writeAuthFile("");
assertRejectedBeforeConnecting(post(setupRequest("")));
}
@Test
public void doPost_wrongAuth_isRejectedBeforeConnecting() throws Exception {
writeAuthFile(TOKEN);
assertRejectedBeforeConnecting(post(setupRequest("not-the-token")));
}
@Test
public void doPost_correctAuth_triesToConnect() throws Exception {
writeAuthFile(TOKEN);
String body = post(setupRequest(TOKEN)).getContentAsString();
assertTrue(
body.contains(bundle.getString("generic.text.setup.connection.failed")),
"Expected a connection attempt with the right token, got: " + body);
}
@Test
public void doPost_installed_isRefusedEvenWithCorrectAuth() throws Exception {
writeAuthFile(TOKEN);
markInstalled();
MockHttpServletResponse response = post(setupRequest(TOKEN));
assertEquals(404, response.getStatus());
assertFalse(
response
.getContentAsString()
.contains(bundle.getString("generic.text.setup.connection.failed")));
}
@Test
public void doPost_installedWithEmptyAuth_isRefused() throws Exception {
markInstalled();
assertEquals(404, post(setupRequest("")).getStatus());
}
}