1 package org.cacert.gigi.pages.wot;
3 import static org.hamcrest.CoreMatchers.*;
4 import static org.junit.Assert.*;
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;
19 import org.cacert.gigi.database.GigiPreparedStatement;
20 import org.cacert.gigi.dbObjects.User;
21 import org.cacert.gigi.pages.account.MyDetails;
22 import org.cacert.gigi.testUtils.IOUtils;
23 import org.cacert.gigi.testUtils.ManagedTest;
24 import org.cacert.gigi.util.DayDate;
25 import org.cacert.gigi.util.Notary;
26 import org.hamcrest.Matcher;
27 import org.junit.Before;
28 import org.junit.Test;
30 public class TestAssurance extends ManagedTest {
32 private String assurerM;
34 private String assureeM;
36 private int assureeName;
38 private String cookie;
41 public void setup() throws IOException {
43 assurerM = createUniqueName() + "@cacert-test.org";
44 assureeM = createUniqueName() + "@cacert-test.org";
46 createAssuranceUser("a", "b", assurerM, TEST_PASSWORD);
47 int assureeId = createVerifiedUser("a", "c", assureeM, TEST_PASSWORD);
48 assureeName = User.getById(assureeId).getPreferredName().getId();
50 cookie = login(assurerM, TEST_PASSWORD);
53 private Matcher<String> isAssuranceForm() {
54 return containsString("<select name=\"assuranceType\">");
58 public void testAssureSearch() throws IOException {
59 String loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1910");
60 assertThat(loc, isAssuranceForm());
64 public void testAssureSearchEmail() throws IOException {
65 String loc = search("email=1" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1910");
66 assertThat(loc, not(isAssuranceForm()));
70 public void testAssureSearchDobInvalid() throws IOException {
71 String loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=mal");
72 assertThat(loc, not(isAssuranceForm()));
76 public void testAssureSearchDob() throws IOException {
77 String loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=2&month=1&year=1910");
78 assertThat(loc, not(isAssuranceForm()));
79 loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=2&year=1910");
80 assertThat(loc, not(isAssuranceForm()));
81 loc = search("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1911");
82 assertThat(loc, not(isAssuranceForm()));
85 private String search(String query) throws MalformedURLException, IOException, UnsupportedEncodingException {
86 URLConnection uc = get(cookie, AssurePage.PATH);
88 uc.getOutputStream().write(("search&" + query).getBytes("UTF-8"));
89 uc.getOutputStream().flush();
91 return IOUtils.readURL(uc);
95 public void testAssureForm() throws IOException {
96 executeSuccess("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10");
100 public void testAssureFormEmpty() throws IOException {
101 URLConnection uc = buildupAssureFormConnection(true);
102 uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&rules=1&assertion=1&points=10").getBytes("UTF-8"));
103 uc.getOutputStream().flush();
104 String data = IOUtils.readURL(uc);
105 assertThat(data, hasError());
109 public void testAssureFormContanisData() throws IOException {
110 URLConnection uc = buildupAssureFormConnection(true);
111 uc.getOutputStream().write(("assuredName=" + assureeName + "&date=" + validVerificationDateString() + "&location=testcase&rules=1&assertion=1&points=10").getBytes("UTF-8"));
112 uc.getOutputStream().flush();
113 String data = IOUtils.readURL(uc);
114 assertThat(data, containsString(validVerificationDateString()));
115 assertThat(data, containsString("testcase"));
119 public void testAssureFormNoCSRF() throws IOException {
121 HttpURLConnection uc = (HttpURLConnection) buildupAssureFormConnection(false);
122 uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
123 uc.getOutputStream().flush();
124 assertEquals(500, uc.getResponseCode());
128 public void testAssureFormWrongCSRF() throws IOException {
130 HttpURLConnection uc = (HttpURLConnection) buildupAssureFormConnection(false);
131 uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10&csrf=aragc").getBytes("UTF-8"));
132 uc.getOutputStream().flush();
133 assertEquals(500, uc.getResponseCode());
137 public void testAssureFormRaceDoB() throws IOException, SQLException {
138 testAssureFormRace(false);
142 public void testAssureFormRaceDoBBlind() throws IOException, SQLException {
143 testAssureFormRace(true);
146 public void testAssureFormRace(boolean succeed) throws IOException, SQLException {
147 URLConnection uc = buildupAssureFormConnection(true);
149 String assureeCookie = login(assureeM, TEST_PASSWORD);
150 String newDob = "day=1&month=1&year=" + ( !succeed ? 1911 : 1910);
152 assertNull(executeBasicWebInteraction(assureeCookie, MyDetails.PATH, newDob + "&action=updateDoB", 0));
154 uc.getOutputStream().write(("assuredName=" + assureeName + "&date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
155 uc.getOutputStream().flush();
156 String error = fetchStartErrorMessage(IOUtils.readURL(uc));
160 assertTrue(error, !error.startsWith("</div>"));
161 assertThat(error, containsString("changed his personal details"));
166 public void testAssureFormFuture() throws IOException {
167 SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
168 int year = Integer.parseInt(sdf.format(new Date(System.currentTimeMillis()))) + 2;
169 executeFails("date=" + year + "-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10");
173 public void testAssureFormFutureOK() throws IOException {
174 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
175 Calendar c = Calendar.getInstance();
176 c.setTimeInMillis(System.currentTimeMillis());
177 c.add(Calendar.HOUR_OF_DAY, 12);
179 executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&certify=1&rules=1&assertion=1&points=10");
183 public void testAssureFormPastInRange() throws IOException {
184 executeSuccess("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10");
188 public void testAssureFormPastOnLimit() throws IOException {
189 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
190 Calendar c = Calendar.getInstance();
191 c.setTimeInMillis(System.currentTimeMillis());
192 c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION);
193 c.add(Calendar.DAY_OF_MONTH, 1);
195 executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&certify=1&rules=1&assertion=1&points=10");
199 public void testAssureFormPastOutOfRange() throws IOException {
200 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
201 Calendar c = Calendar.getInstance();
202 c.setTimeInMillis(System.currentTimeMillis());
203 c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION);
205 executeFails("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&certify=1&rules=1&assertion=1&points=10");
209 public void testAssureFormNoLoc() throws IOException {
210 executeFails("date=" + validVerificationDateString() + "&location=a&certify=1&rules=1&assertion=1&points=10");
211 executeFails("date=" + validVerificationDateString() + "&location=&certify=1&rules=1&assertion=1&points=10");
215 public void testAssureFormInvalDate() throws IOException {
216 executeFails("date=20000101&location=testcase&certify=1&rules=1&assertion=1&points=10");
217 executeFails("date=&location=testcase&certify=1&rules=1&assertion=1&points=10");
221 public void testAssureFormBoxes() throws IOException {
222 executeFails("date=" + validVerificationDateString() + "&location=testcase&certify=0&rules=1&assertion=1&points=10");
223 executeFails("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=&assertion=1&points=10");
224 executeFails("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=z&points=10");
228 public void testAssureListingValid() throws IOException {
229 String uniqueLoc = createUniqueName();
230 execute("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10");
232 String cookie = login(assureeM, TEST_PASSWORD);
233 URLConnection url = get(cookie, MyPoints.PATH);
234 String resp = IOUtils.readURL(url);
235 resp = resp.split(Pattern.quote("</table>"))[0];
236 assertThat(resp, containsString(uniqueLoc));
240 public void testAssurerListingValid() throws IOException {
241 String uniqueLoc = createUniqueName();
242 executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10");
243 String cookie = login(assurerM, TEST_PASSWORD);
244 URLConnection url = get(cookie, MyPoints.PATH);
245 String resp = IOUtils.readURL(url);
246 resp = resp.split(Pattern.quote("</table>"))[1];
247 assertThat(resp, containsString(uniqueLoc));
250 private void executeFails(String query) throws MalformedURLException, IOException {
251 assertThat(execute(query), hasError());
255 private void executeSuccess(String query) throws MalformedURLException, IOException {
256 assertThat(execute(query), hasNoError());
260 private String execute(String query) throws MalformedURLException, IOException {
261 URLConnection uc = buildupAssureFormConnection(true);
262 uc.getOutputStream().write(("assuredName=" + assureeName + "&" + query).getBytes("UTF-8"));
263 uc.getOutputStream().flush();
264 return IOUtils.readURL(uc);
267 private URLConnection buildupAssureFormConnection(boolean doCSRF) throws MalformedURLException, IOException {
268 return buildupAssureFormConnection(cookie, assureeM, doCSRF);
271 public static URLConnection buildupAssureFormConnection(String cookie, String email, boolean doCSRF) throws MalformedURLException, IOException {
272 URLConnection uc = get(cookie, AssurePage.PATH);
273 uc.setDoOutput(true);
274 uc.getOutputStream().write(("email=" + URLEncoder.encode(email, "UTF-8") + "&day=1&month=1&year=1910&search").getBytes("UTF-8"));
276 String csrf = getCSRF(uc);
277 uc = get(cookie, AssurePage.PATH);
278 uc.setDoOutput(true);
280 uc.getOutputStream().write(("csrf=" + csrf + "&").getBytes("UTF-8"));
286 public void testMultipleAssurance() throws IOException {
288 User users[] = User.findByEmail(assurerM);
289 int agentID = users[0].getId();
291 users = User.findByEmail(assureeM);
292 int applicantID = users[0].getId();
294 // enter first entry 200 days in the past
295 try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `when`=? ")) {
296 ps.setInt(1, agentID);
297 ps.setInt(2, applicantID);
299 ps.setString(4, "test-location");
300 ps.setString(5, "2010-01-01");
301 ps.setTimestamp(6, new Timestamp(System.currentTimeMillis() - DayDate.MILLI_DAY * 200));
305 // enter second entry
306 String uniqueLoc = createUniqueName();
307 executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10");
309 // enter third entry on the same day
310 URLConnection uc = get(cookie, AssurePage.PATH);
311 uc.setDoOutput(true);
312 uc.getOutputStream().write(("email=" + URLEncoder.encode(assureeM, "UTF-8") + "&day=1&month=1&year=1910&search").getBytes("UTF-8"));
313 assertThat(IOUtils.readURL(uc), hasError());