]> WPIA git - gigi.git/blob - tests/org/cacert/gigi/pages/wot/TestAssurance.java
fix: ResultSet.getDate is often wrong as it fetches day-precision times
[gigi.git] / tests / org / cacert / gigi / pages / wot / TestAssurance.java
1 package org.cacert.gigi.pages.wot;
2
3 import static org.hamcrest.CoreMatchers.*;
4 import static org.junit.Assert.*;
5
6 import java.io.IOException;
7 import java.io.UnsupportedEncodingException;
8 import java.net.HttpURLConnection;
9 import java.net.MalformedURLException;
10 import java.net.URLConnection;
11 import java.net.URLEncoder;
12 import java.sql.SQLException;
13 import java.sql.Timestamp;
14 import java.text.SimpleDateFormat;
15 import java.util.Calendar;
16 import java.util.Date;
17 import java.util.regex.Pattern;
18
19 import org.cacert.gigi.GigiApiException;
20 import org.cacert.gigi.database.GigiPreparedStatement;
21 import org.cacert.gigi.dbObjects.Country;
22 import org.cacert.gigi.dbObjects.Group;
23 import org.cacert.gigi.dbObjects.User;
24 import org.cacert.gigi.pages.account.MyDetails;
25 import org.cacert.gigi.testUtils.IOUtils;
26 import org.cacert.gigi.testUtils.ManagedTest;
27 import org.cacert.gigi.testUtils.TestEmailReceiver.TestMail;
28 import org.cacert.gigi.util.DayDate;
29 import org.cacert.gigi.util.Notary;
30 import org.hamcrest.Matcher;
31 import org.junit.Before;
32 import org.junit.Test;
33
34 public class TestAssurance extends ManagedTest {
35
36     private String assurerM;
37
38     private String assureeM;
39
40     private int assureeName;
41
42     private String cookie;
43
44     @Before
45     public void setup() throws IOException {
46         clearCaches();
47         assurerM = createUniqueName() + "@cacert-test.org";
48         assureeM = createUniqueName() + "@cacert-test.org";
49
50         createAssuranceUser("a", "b", assurerM, TEST_PASSWORD);
51         int assureeId = createVerifiedUser("a", "c", assureeM, TEST_PASSWORD);
52         assureeName = User.getById(assureeId).getPreferredName().getId();
53
54         cookie = login(assurerM, TEST_PASSWORD);
55     }
56
57     private Matcher<String> isAssuranceForm() {
58         return containsString("<select name=\"assuranceType\">");
59     }
60
61     @Test
62     public void testAssureSearch() throws IOException {
63         String loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1910");
64         assertThat(loc, isAssuranceForm());
65     }
66
67     @Test
68     public void testAssureSearchEmail() throws IOException {
69         String loc = search("email=1" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1910");
70         assertThat(loc, not(isAssuranceForm()));
71     }
72
73     @Test
74     public void testAssureSearchDobInvalid() throws IOException {
75         String loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=mal");
76         assertThat(loc, not(isAssuranceForm()));
77     }
78
79     @Test
80     public void testAssureSearchDob() throws IOException {
81         String loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=2&month=1&year=1910");
82         assertThat(loc, not(isAssuranceForm()));
83         loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=2&year=1910");
84         assertThat(loc, not(isAssuranceForm()));
85         loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1911");
86         assertThat(loc, not(isAssuranceForm()));
87     }
88
89     private String search(String query) throws MalformedURLException, IOException, UnsupportedEncodingException {
90         URLConnection uc = get(cookie, AssurePage.PATH);
91         uc.setDoOutput(true);
92         uc.getOutputStream().write(("search&" + query).getBytes("UTF-8"));
93         uc.getOutputStream().flush();
94
95         return IOUtils.readURL(uc);
96     }
97
98     @Test
99     public void testAssureForm() throws IOException {
100         executeSuccess("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
101     }
102
103     @Test
104     public void testAssureFormEmpty() throws IOException {
105         URLConnection uc = buildupAssureFormConnection(true);
106         uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&rules=1&assertion=1&points=10").getBytes("UTF-8"));
107         uc.getOutputStream().flush();
108         String data = IOUtils.readURL(uc);
109         assertThat(data, hasError());
110     }
111
112     @Test
113     public void testAssureFormContanisData() throws IOException {
114         URLConnection uc = buildupAssureFormConnection(true);
115         uc.getOutputStream().write(("assuredName=" + assureeName + "&date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&rules=1&assertion=1&points=10").getBytes("UTF-8"));
116         uc.getOutputStream().flush();
117         String data = IOUtils.readURL(uc);
118         assertThat(data, containsString(validVerificationDateString()));
119         assertThat(data, containsString("testcase"));
120     }
121
122     @Test
123     public void testAssureFormNoCSRF() throws IOException {
124         // override csrf
125         HttpURLConnection uc = (HttpURLConnection) buildupAssureFormConnection(false);
126         uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
127         uc.getOutputStream().flush();
128         assertEquals(500, uc.getResponseCode());
129     }
130
131     @Test
132     public void testAssureFormWrongCSRF() throws IOException {
133         // override csrf
134         HttpURLConnection uc = (HttpURLConnection) buildupAssureFormConnection(false);
135         uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10&csrf=aragc").getBytes("UTF-8"));
136         uc.getOutputStream().flush();
137         assertEquals(500, uc.getResponseCode());
138     }
139
140     @Test
141     public void testAssureFormRaceDoB() throws IOException, SQLException {
142         testAssureFormRace(false);
143     }
144
145     @Test
146     public void testAssureFormRaceDoBBlind() throws IOException, SQLException {
147         testAssureFormRace(true);
148     }
149
150     public void testAssureFormRace(boolean succeed) throws IOException, SQLException {
151         URLConnection uc = buildupAssureFormConnection(true);
152
153         String assureeCookie = login(assureeM, TEST_PASSWORD);
154         String newDob = "day=1&month=1&year=" + ( !succeed ? 1911 : 1910);
155
156         assertNull(executeBasicWebInteraction(assureeCookie, MyDetails.PATH, newDob + "&action=updateDoB", 0));
157
158         uc.getOutputStream().write(("assuredName=" + assureeName + "&date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
159         uc.getOutputStream().flush();
160         String error = fetchStartErrorMessage(IOUtils.readURL(uc));
161         if (succeed) {
162             assertNull(error);
163         } else {
164             assertTrue(error, !error.startsWith("</div>"));
165             assertThat(error, containsString("changed his personal details"));
166         }
167     }
168
169     @Test
170     public void testAssureFormFuture() throws IOException {
171         SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
172         int year = Integer.parseInt(sdf.format(new Date(System.currentTimeMillis()))) + 2;
173         executeFails("date=" + year + "-01-01&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
174     }
175
176     @Test
177     public void testAssureFormFutureOK() throws IOException {
178         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
179         Calendar c = Calendar.getInstance();
180         c.setTimeInMillis(System.currentTimeMillis());
181         c.add(Calendar.HOUR_OF_DAY, 12);
182
183         executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
184     }
185
186     @Test
187     public void testAssureFormPastInRange() throws IOException {
188         executeSuccess("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
189     }
190
191     @Test
192     public void testAssureFormPastOnLimit() throws IOException {
193         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
194         Calendar c = Calendar.getInstance();
195         c.setTimeInMillis(System.currentTimeMillis());
196         c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION);
197         c.add(Calendar.DAY_OF_MONTH, 1);
198
199         executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
200     }
201
202     @Test
203     public void testAssureFormPastOutOfRange() throws IOException {
204         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
205         Calendar c = Calendar.getInstance();
206         c.setTimeInMillis(System.currentTimeMillis());
207         c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION);
208
209         executeFails("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
210     }
211
212     @Test
213     public void testAssureFormNoLoc() throws IOException {
214         executeFails("date=" + validVerificationDateString() + "&location=a&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
215         executeFails("date=" + validVerificationDateString() + "&location=&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
216     }
217
218     @Test
219     public void testAssureFormInvalDate() throws IOException {
220         executeFails("date=20000101&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
221         executeFails("date=&location=testcase&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
222     }
223
224     @Test
225     public void testAssureFormBoxes() throws IOException {
226         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=0&rules=1&assertion=1&points=10");
227         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=&assertion=1&points=10");
228         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=DE&certify=1&rules=1&assertion=z&points=10");
229     }
230
231     @Test
232     public void testAssureListingValid() throws IOException, GigiApiException {
233         String uniqueLoc = createUniqueName();
234         execute("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
235
236         String cookie = login(assureeM, TEST_PASSWORD);
237         URLConnection url = get(cookie, Points.PATH);
238         String resp = IOUtils.readURL(url);
239         resp = resp.split(Pattern.quote("</table>"))[1];
240         assertThat(resp, containsString(uniqueLoc));
241         assertThat(resp, containsString(Country.getCountryByCode("DE", Country.CountryCodeType.CODE_2_CHARS).getName()));
242     }
243
244     @Test
245     public void testAssurerListingValid() throws IOException, GigiApiException {
246         String uniqueLoc = createUniqueName();
247         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
248         String cookie = login(assurerM, TEST_PASSWORD);
249         URLConnection url = get(cookie, Points.PATH);
250         String resp = IOUtils.readURL(url);
251         resp = resp.split(Pattern.quote("</table>"))[2];
252         assertThat(resp, containsString(uniqueLoc));
253         assertThat(resp, containsString(Country.getCountryByCode("DE", Country.CountryCodeType.CODE_2_CHARS).getName()));
254     }
255
256     private void executeFails(String query) throws MalformedURLException, IOException {
257         assertThat(execute(query), hasError());
258
259     }
260
261     private void executeSuccess(String query) throws MalformedURLException, IOException {
262         assertThat(execute(query), hasNoError());
263
264     }
265
266     private String execute(String query) throws MalformedURLException, IOException {
267         URLConnection uc = buildupAssureFormConnection(true);
268         uc.getOutputStream().write(("assuredName=" + assureeName + "&" + query).getBytes("UTF-8"));
269         uc.getOutputStream().flush();
270         return IOUtils.readURL(uc);
271     }
272
273     private URLConnection buildupAssureFormConnection(boolean doCSRF) throws MalformedURLException, IOException {
274         return buildupAssureFormConnection(cookie, assureeM, doCSRF);
275     }
276
277     public static URLConnection buildupAssureFormConnection(String cookie, String email, boolean doCSRF) throws MalformedURLException, IOException {
278         URLConnection uc = get(cookie, AssurePage.PATH);
279         uc.setDoOutput(true);
280         uc.getOutputStream().write(("email=" + URLEncoder.encode(email, "UTF-8") + "&day=1&month=1&year=1910&search").getBytes("UTF-8"));
281
282         String csrf = getCSRF(uc);
283         uc = get(cookie, AssurePage.PATH);
284         uc.setDoOutput(true);
285         if (doCSRF) {
286             uc.getOutputStream().write(("csrf=" + csrf + "&").getBytes("UTF-8"));
287         }
288         return uc;
289     }
290
291     @Test
292     public void testMultipleAssurance() throws IOException {
293
294         User users[] = User.findByEmail(assurerM);
295         int agentID = users[0].getId();
296
297         users = User.findByEmail(assureeM);
298         int applicantID = users[0].getId();
299
300         // enter first entry 200 days in the past
301         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `when`=? ")) {
302             ps.setInt(1, agentID);
303             ps.setInt(2, applicantID);
304             ps.setInt(3, 10);
305             ps.setString(4, "test-location");
306             ps.setString(5, "2010-01-01");
307             ps.setTimestamp(6, new Timestamp(System.currentTimeMillis() - DayDate.MILLI_DAY * 200));
308             ps.execute();
309         }
310
311         // enter second entry
312         String uniqueLoc = createUniqueName();
313         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
314
315         // enter third entry on the same day
316         URLConnection uc = get(cookie, AssurePage.PATH);
317         uc.setDoOutput(true);
318         uc.getOutputStream().write(("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1910&search").getBytes("UTF-8"));
319         assertThat(IOUtils.readURL(uc), hasError());
320
321     }
322
323     @Test
324     public void testAssureFormNoCountry() throws IOException {
325         executeFails("date=" + validVerificationDateString() + "&location=testcase&countryCode=&certify=1&rules=1&assertion=1&points=10");
326     }
327
328     @Test
329     public void testRANotificationSet() throws IOException, GigiApiException {
330         getMailReceiver().clearMails();
331
332         User users[] = User.findByEmail(assurerM);
333         assertTrue("user RA Agent not found", users != null && users.length > 0);
334
335         User u = users[0];
336         u.grantGroup(u, Group.VERIFY_NOTIFICATION);
337         clearCaches();
338         cookie = login(assurerM, TEST_PASSWORD);
339
340         String targetMail = u.getEmail();
341
342         // enter verification
343         String uniqueLoc = createUniqueName();
344         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
345         TestMail tm;
346
347         do {
348             tm = getMailReceiver().receive();
349         } while ( !tm.getTo().equals(targetMail));
350         assertThat(tm.getMessage(), containsString("You entered a verification for the account with email address " + assureeM));
351
352     }
353
354     @Test
355     public void testRANotificationNotSet() throws IOException, GigiApiException {
356         getMailReceiver().clearMails();
357
358         User users[] = User.findByEmail(assurerM);
359         assertTrue("user RA Agent not found", users != null && users.length > 0);
360
361         User u = users[0];
362         u.revokeGroup(u, Group.VERIFY_NOTIFICATION);
363         clearCaches();
364         cookie = login(assurerM, TEST_PASSWORD);
365
366         // enter verification
367         String uniqueLoc = createUniqueName();
368         executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&countryCode=DE&certify=1&rules=1&assertion=1&points=10");
369
370         TestMail tm;
371
372         tm = getMailReceiver().receive();
373         assertThat(tm.getMessage(), not(containsString("You entered a verification for the account with email address " + assureeM)));
374
375     }
376 }