]> WPIA git - gigi.git/blob - tests/org/cacert/gigi/testUtils/ManagedTest.java
Fix test for csrf.
[gigi.git] / tests / org / cacert / gigi / testUtils / ManagedTest.java
1 package org.cacert.gigi.testUtils;
2
3 import static org.junit.Assert.assertNotEquals;
4 import static org.junit.Assert.assertTrue;
5
6 import java.io.BufferedReader;
7 import java.io.DataOutputStream;
8 import java.io.FileInputStream;
9 import java.io.IOException;
10 import java.io.InputStreamReader;
11 import java.io.OutputStream;
12 import java.io.UnsupportedEncodingException;
13 import java.net.HttpURLConnection;
14 import java.net.InetSocketAddress;
15 import java.net.URL;
16 import java.net.URLConnection;
17 import java.net.URLEncoder;
18 import java.nio.file.Files;
19 import java.nio.file.Paths;
20 import java.sql.PreparedStatement;
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23 import java.util.Properties;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27 import org.cacert.gigi.DevelLauncher;
28 import org.cacert.gigi.database.DatabaseConnection;
29 import org.cacert.gigi.testUtils.TestEmailReciever.TestMail;
30 import org.cacert.gigi.util.DatabaseManager;
31 import org.junit.After;
32 import org.junit.AfterClass;
33 import org.junit.BeforeClass;
34
35 public class ManagedTest {
36         private final String registerService = "/register";
37
38         private static TestEmailReciever ter;
39         private static Process gigi;
40         private static String url = "localhost:4443";
41
42         public static String getServerName() {
43                 return url;
44         }
45
46         static Properties testProps = new Properties();
47         static {
48                 InitTruststore.run();
49                 HttpURLConnection.setFollowRedirects(false);
50         }
51
52         @BeforeClass
53         public static void connectToServer() {
54                 try {
55                         testProps.load(new FileInputStream("config/test.properties"));
56                         if (!DatabaseConnection.isInited()) {
57                                 DatabaseConnection.init(testProps);
58                         }
59                         System.out.println("... purging Database");
60                         DatabaseManager.run(new String[] { testProps.getProperty("sql.driver"), testProps.getProperty("sql.url"),
61                                         testProps.getProperty("sql.user"), testProps.getProperty("sql.password") });
62
63                         String type = testProps.getProperty("type");
64                         if (type.equals("local")) {
65                                 url = testProps.getProperty("name.www") + ":" + testProps.getProperty("serverPort");
66                                 String[] parts = testProps.getProperty("mail").split(":", 2);
67                                 ter = new TestEmailReciever(new InetSocketAddress(parts[0], Integer.parseInt(parts[1])));
68                                 return;
69                         }
70                         url = testProps.getProperty("name.www") + ":" + testProps.getProperty("serverPort");
71                         gigi = Runtime.getRuntime().exec(testProps.getProperty("java"));
72                         DataOutputStream toGigi = new DataOutputStream(gigi.getOutputStream());
73                         System.out.println("... starting server");
74                         Properties mainProps = new Properties();
75                         mainProps.setProperty("host", "127.0.0.1");
76                         mainProps.setProperty("name.secure", testProps.getProperty("name.secure"));
77                         mainProps.setProperty("name.www", testProps.getProperty("name.www"));
78                         mainProps.setProperty("name.static", testProps.getProperty("name.static"));
79
80                         mainProps.setProperty("port", testProps.getProperty("serverPort"));
81                         mainProps.setProperty("emailProvider", "org.cacert.gigi.email.TestEmailProvider");
82                         mainProps.setProperty("emailProvider.port", "8473");
83                         mainProps.setProperty("sql.driver", testProps.getProperty("sql.driver"));
84                         mainProps.setProperty("sql.url", testProps.getProperty("sql.url"));
85                         mainProps.setProperty("sql.user", testProps.getProperty("sql.user"));
86                         mainProps.setProperty("sql.password", testProps.getProperty("sql.password"));
87
88                         byte[] cacerts = Files.readAllBytes(Paths.get("config/cacerts.jks"));
89                         byte[] keystore = Files.readAllBytes(Paths.get("config/keystore.pkcs12"));
90
91                         DevelLauncher.writeGigiConfig(toGigi, "changeit".getBytes(), "changeit".getBytes(), mainProps, cacerts,
92                                 keystore);
93                         toGigi.flush();
94
95                         final BufferedReader br = new BufferedReader(new InputStreamReader(gigi.getErrorStream()));
96                         String line;
97                         while ((line = br.readLine()) != null && !line.contains("Server:main: Started")) {
98                         }
99                         new Thread() {
100                                 @Override
101                                 public void run() {
102                                         String line;
103                                         try {
104                                                 while ((line = br.readLine()) != null) {
105                                                         System.err.println(line);
106                                                 }
107                                         } catch (IOException e) {
108                                                 e.printStackTrace();
109                                         }
110                                 }
111                         }.start();
112                         if (line == null) {
113                                 throw new Error("Server startup failed");
114                         }
115                         ter = new TestEmailReciever(new InetSocketAddress("localhost", 8473));
116                 } catch (IOException e) {
117                         throw new Error(e);
118                 } catch (ClassNotFoundException e1) {
119                         e1.printStackTrace();
120                 } catch (SQLException e1) {
121                         e1.printStackTrace();
122                 }
123
124         }
125
126         @AfterClass
127         public static void tearDownServer() {
128                 String type = testProps.getProperty("type");
129                 ter.destroy();
130                 if (type.equals("local")) {
131                         return;
132                 }
133                 gigi.destroy();
134         }
135
136         @After
137         public void removeMails() {
138                 ter.reset();
139         }
140
141         public TestMail waitForMail() {
142                 try {
143                         return ter.recieve();
144                 } catch (InterruptedException e) {
145                         throw new Error(e);
146                 }
147         }
148
149         public static TestEmailReciever getMailReciever() {
150                 return ter;
151         }
152
153         public String runRegister(String param) throws IOException {
154                 URL regist = new URL("https://" + getServerName() + registerService);
155                 HttpURLConnection uc = (HttpURLConnection) regist.openConnection();
156                 HttpURLConnection csrfConn = (HttpURLConnection) regist.openConnection();
157
158                 String headerField = csrfConn.getHeaderField("Set-Cookie");
159                 headerField = headerField.substring(0, headerField.indexOf(';'));
160
161                 String csrf = getCSRF(csrfConn);
162                 uc.addRequestProperty("Cookie", headerField);
163                 uc.setDoOutput(true);
164                 uc.getOutputStream().write((param + "&csrf=" + csrf).getBytes());
165                 String d = IOUtils.readURL(uc);
166                 return d;
167         }
168
169         public String fetchStartErrorMessage(String d) throws IOException {
170                 String formFail = "<div class='formError'>";
171                 int idx = d.indexOf(formFail);
172                 assertNotEquals(-1, idx);
173                 String startError = d.substring(idx + formFail.length(), idx + 100).trim();
174                 return startError;
175         }
176
177         public void registerUser(String firstName, String lastName, String email, String password) {
178                 try {
179                         String query = "fname=" + URLEncoder.encode(firstName, "UTF-8") + "&lname="
180                                 + URLEncoder.encode(lastName, "UTF-8") + "&email=" + URLEncoder.encode(email, "UTF-8") + "&pword1="
181                                 + URLEncoder.encode(password, "UTF-8") + "&pword2=" + URLEncoder.encode(password, "UTF-8")
182                                 + "&day=1&month=1&year=1910&cca_agree=1";
183                         String data = fetchStartErrorMessage(runRegister(query));
184                         assertTrue(data, data.startsWith("</div>"));
185                 } catch (UnsupportedEncodingException e) {
186                         throw new Error(e);
187                 } catch (IOException e) {
188                         throw new Error(e);
189                 }
190         }
191
192         public int createVerifiedUser(String firstName, String lastName, String email, String password) {
193                 registerUser(firstName, lastName, email, password);
194                 try {
195                         TestMail tm = ter.recieve();
196                         String verifyLink = tm.extractLink();
197                         String[] parts = verifyLink.split("\\?");
198                         URL u = new URL("https://" + getServerName() + "/verify?" + parts[1]);
199                         u.openStream().close();
200                         ;
201                         PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id FROM users where email=?");
202                         ps.setString(1, email);
203                         ResultSet rs = ps.executeQuery();
204                         if (rs.next()) {
205                                 return rs.getInt(1);
206                         }
207                         throw new Error();
208                 } catch (InterruptedException e) {
209                         throw new Error(e);
210                 } catch (IOException e) {
211                         throw new Error(e);
212                 } catch (SQLException e) {
213                         throw new Error(e);
214                 }
215         }
216
217         /**
218          * Creates a new user with 100 Assurance points given by an (invalid)
219          * assurance.
220          * 
221          * @param firstName
222          *            the first name
223          * @param lastName
224          *            the last name
225          * @param email
226          *            the email
227          * @param password
228          *            the password
229          * @return a new userid.
230          */
231         public int createAssuranceUser(String firstName, String lastName, String email, String password) {
232                 int uid = createVerifiedUser(firstName, lastName, email, password);
233                 try {
234                         PreparedStatement ps = DatabaseConnection.getInstance().prepare(
235                                 "INSERT INTO `cats_passed` SET `user_id`=?, `variant_id`=?");
236                         ps.setInt(1, uid);
237                         ps.setInt(2, 0);
238                         ps.execute();
239                         ps = DatabaseConnection.getInstance().prepare("INSERT INTO `notary` SET `from`=?, `to`=?, points='100'");
240                         ps.setInt(1, uid);
241                         ps.setInt(2, uid);
242                         ps.execute();
243
244                 } catch (SQLException e) {
245                         throw new Error(e);
246                 }
247                 return uid;
248         }
249
250         static int count = 0;
251
252         public String createUniqueName() {
253                 return "test" + System.currentTimeMillis() + "a" + (count++);
254         }
255
256         public String login(String email, String pw) throws IOException {
257                 URL u = new URL("https://" + getServerName() + "/login");
258                 HttpURLConnection huc = (HttpURLConnection) u.openConnection();
259                 huc.setDoOutput(true);
260                 OutputStream os = huc.getOutputStream();
261                 String data = "username=" + URLEncoder.encode(email, "UTF-8") + "&password=" + URLEncoder.encode(pw, "UTF-8");
262                 os.write(data.getBytes());
263                 os.flush();
264                 String headerField = huc.getHeaderField("Set-Cookie");
265                 headerField = headerField.substring(0, headerField.indexOf(';'));
266                 return headerField;
267         }
268
269         public String getCSRF(URLConnection u) throws IOException {
270                 String content = IOUtils.readURL(u);
271                 Pattern p = Pattern.compile("<input type='hidden' name='csrf' value='([^']+)'>");
272                 Matcher m = p.matcher(content);
273                 if (!m.find()) {
274                         throw new Error("No CSRF Token");
275                 }
276                 return m.group(1);
277         }
278 }