From 265b98aed618c4b153f9c96580fb619ab7ce70ec Mon Sep 17 00:00:00 2001 From: INOPIAE Date: Sat, 23 Jul 2016 18:11:41 +0200 Subject: [PATCH] add: check that verification date is not far in the past fixes issue #82 Change-Id: I5a57faba57b652dc096a48d50a0044088835d108 --- src/org/cacert/gigi/util/Notary.java | 11 ++++ tests/org/cacert/gigi/TestUser.java | 2 +- .../cacert/gigi/dbObjects/TestAssureName.java | 8 +-- .../cacert/gigi/pages/wot/TestAssurance.java | 55 ++++++++++++++----- .../cacert/gigi/testUtils/ConfiguredTest.java | 13 +++++ tests/org/cacert/gigi/util/TestNotary.java | 34 ++++++------ 6 files changed, 87 insertions(+), 36 deletions(-) diff --git a/src/org/cacert/gigi/util/Notary.java b/src/org/cacert/gigi/util/Notary.java index 0ecc14e4..952f7c4e 100644 --- a/src/org/cacert/gigi/util/Notary.java +++ b/src/org/cacert/gigi/util/Notary.java @@ -17,8 +17,14 @@ import org.cacert.gigi.output.template.SprintfCommand; public class Notary { + // minimum date range between 2 verifications of the RA-Agent to the same + // Applicant public final static int LIMIT_DAYS_VERIFICATION = 90; // conf.getProperty("limit_days_verification"); + // maximum date range from date when the verification took place and the + // entering to the system + public final static int LIMIT_MAX_MONTHS_VERIFICATION = 24; // conf.getProperty("limit_max_months_verification"); + public static void writeUserAgreement(User member, String document, String method, String comment, boolean active, int secmemid) { try (GigiPreparedStatement q = new GigiPreparedStatement("INSERT INTO `user_agreements` SET `memid`=?, `secmemid`=?," + " `document`=?,`date`=NOW(), `active`=?,`method`=?,`comment`=?")) { q.setInt(1, member.getId()); @@ -85,6 +91,11 @@ public class Notary { if (d.getTime() > gc.getTimeInMillis()) { gae.mergeInto(new GigiApiException("You must not enter a date in the future.")); } + gc.setTimeInMillis(System.currentTimeMillis()); + gc.add(Calendar.MONTH, -LIMIT_MAX_MONTHS_VERIFICATION); + if (d.getTime() < gc.getTimeInMillis()) { + gae.mergeInto(new GigiApiException(SprintfCommand.createSimple("Verifications older than {0} months are not accepted.", LIMIT_MAX_MONTHS_VERIFICATION))); + } } catch (ParseException e) { gae.mergeInto(new GigiApiException("You must enter the date in this format: YYYY-MM-DD.")); } diff --git a/tests/org/cacert/gigi/TestUser.java b/tests/org/cacert/gigi/TestUser.java index d4810af9..f665a7a6 100644 --- a/tests/org/cacert/gigi/TestUser.java +++ b/tests/org/cacert/gigi/TestUser.java @@ -109,7 +109,7 @@ public class TestUser extends BusinessTest { User[] us = new User[5]; for (int i = 0; i < us.length; i++) { us[i] = User.getById(createAssuranceUser("f", "l", createUniqueName() + "@email.com", TEST_PASSWORD)); - Notary.assure(us[i], u, u.getPreferredName(), u.getDoB(), 10, "here", "2000-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(us[i], u, u.getPreferredName(), u.getDoB(), 10, "here", validVerificationDateString(), AssuranceType.FACE_TO_FACE); } assertTrue(u.isValidName("aä b")); diff --git a/tests/org/cacert/gigi/dbObjects/TestAssureName.java b/tests/org/cacert/gigi/dbObjects/TestAssureName.java index 9296e35c..03df9a3c 100644 --- a/tests/org/cacert/gigi/dbObjects/TestAssureName.java +++ b/tests/org/cacert/gigi/dbObjects/TestAssureName.java @@ -19,13 +19,13 @@ public class TestAssureName extends ClientBusinessTest { Name n4 = new Name(u, new NamePart(NamePartType.SINGLE_NAME, "Testiaac")); assertEquals(0, n0.getAssurancePoints()); - Notary.assure(u0, u, n0, u.getDoB(), 10, "test mgr", "2010-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(u0, u, n0, u.getDoB(), 10, "test mgr", validVerificationDateString(), AssuranceType.FACE_TO_FACE); assertEquals(10, n0.getAssurancePoints()); - Notary.assure(u0, u, n2, u.getDoB(), 10, "test mgr", "2010-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(u0, u, n2, u.getDoB(), 10, "test mgr", validVerificationDateString(), AssuranceType.FACE_TO_FACE); assertEquals(10, n2.getAssurancePoints()); - Notary.assure(u0, u, n3, u.getDoB(), 10, "test mgr", "2010-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(u0, u, n3, u.getDoB(), 10, "test mgr", validVerificationDateString(), AssuranceType.FACE_TO_FACE); assertEquals(10, n3.getAssurancePoints()); - Notary.assure(u0, u, n4, u.getDoB(), 10, "test mgr", "2010-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(u0, u, n4, u.getDoB(), 10, "test mgr", validVerificationDateString(), AssuranceType.FACE_TO_FACE); assertEquals(10, n4.getAssurancePoints()); assertEquals(10, u.getMaxAssurePoints()); } diff --git a/tests/org/cacert/gigi/pages/wot/TestAssurance.java b/tests/org/cacert/gigi/pages/wot/TestAssurance.java index 2a68173d..eb488e5d 100644 --- a/tests/org/cacert/gigi/pages/wot/TestAssurance.java +++ b/tests/org/cacert/gigi/pages/wot/TestAssurance.java @@ -22,6 +22,7 @@ import org.cacert.gigi.pages.account.MyDetails; import org.cacert.gigi.testUtils.IOUtils; import org.cacert.gigi.testUtils.ManagedTest; import org.cacert.gigi.util.DayDate; +import org.cacert.gigi.util.Notary; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Test; @@ -92,16 +93,16 @@ public class TestAssurance extends ManagedTest { @Test public void testAssureForm() throws IOException { - executeSuccess("date=2000-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10"); + executeSuccess("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10"); } @Test public void testAssureFormContanisData() throws IOException { URLConnection uc = buildupAssureFormConnection(true); - uc.getOutputStream().write(("assuredName=" + assureeName + "&date=2000-01-01&location=testcase&rules=1&assertion=1&points=10").getBytes("UTF-8")); + uc.getOutputStream().write(("assuredName=" + assureeName + "&date=" + validVerificationDateString() + "&location=testcase&rules=1&assertion=1&points=10").getBytes("UTF-8")); uc.getOutputStream().flush(); String data = IOUtils.readURL(uc); - assertThat(data, containsString("2000-01-01")); + assertThat(data, containsString(validVerificationDateString())); assertThat(data, containsString("testcase")); } @@ -109,7 +110,7 @@ public class TestAssurance extends ManagedTest { public void testAssureFormNoCSRF() throws IOException { // override csrf HttpURLConnection uc = (HttpURLConnection) buildupAssureFormConnection(false); - uc.getOutputStream().write(("date=2000-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8")); + uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8")); uc.getOutputStream().flush(); assertEquals(500, uc.getResponseCode()); } @@ -118,7 +119,7 @@ public class TestAssurance extends ManagedTest { public void testAssureFormWrongCSRF() throws IOException { // override csrf HttpURLConnection uc = (HttpURLConnection) buildupAssureFormConnection(false); - uc.getOutputStream().write(("date=2000-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10&csrf=aragc").getBytes("UTF-8")); + uc.getOutputStream().write(("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10&csrf=aragc").getBytes("UTF-8")); uc.getOutputStream().flush(); assertEquals(500, uc.getResponseCode()); } @@ -141,7 +142,7 @@ public class TestAssurance extends ManagedTest { assertNull(executeBasicWebInteraction(assureeCookie, MyDetails.PATH, newDob + "&action=updateDoB", 0)); - uc.getOutputStream().write(("assuredName=" + assureeName + "&date=2000-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8")); + uc.getOutputStream().write(("assuredName=" + assureeName + "&date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8")); uc.getOutputStream().flush(); String error = fetchStartErrorMessage(IOUtils.readURL(uc)); if (succeed) { @@ -169,10 +170,36 @@ public class TestAssurance extends ManagedTest { executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&certify=1&rules=1&assertion=1&points=10"); } + @Test + public void testAssureFormPastInRange() throws IOException { + executeSuccess("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=1&points=10"); + } + + @Test + public void testAssureFormPastOnLimit() throws IOException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(System.currentTimeMillis()); + c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION); + c.add(Calendar.DAY_OF_MONTH, 1); + + executeSuccess("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&certify=1&rules=1&assertion=1&points=10"); + } + + @Test + public void testAssureFormPastOutOfRange() throws IOException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(System.currentTimeMillis()); + c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION); + + executeFails("date=" + sdf.format(new Date(c.getTimeInMillis())) + "&location=testcase&certify=1&rules=1&assertion=1&points=10"); + } + @Test public void testAssureFormNoLoc() throws IOException { - executeFails("date=2000-01-01&location=a&certify=1&rules=1&assertion=1&points=10"); - executeFails("date=2000-01-01&location=&certify=1&rules=1&assertion=1&points=10"); + executeFails("date=" + validVerificationDateString() + "&location=a&certify=1&rules=1&assertion=1&points=10"); + executeFails("date=" + validVerificationDateString() + "&location=&certify=1&rules=1&assertion=1&points=10"); } @Test @@ -183,15 +210,15 @@ public class TestAssurance extends ManagedTest { @Test public void testAssureFormBoxes() throws IOException { - executeFails("date=2000-01-01&location=testcase&certify=0&rules=1&assertion=1&points=10"); - executeFails("date=2000-01-01&location=testcase&certify=1&rules=&assertion=1&points=10"); - executeFails("date=2000-01-01&location=testcase&certify=1&rules=1&assertion=z&points=10"); + executeFails("date=" + validVerificationDateString() + "&location=testcase&certify=0&rules=1&assertion=1&points=10"); + executeFails("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=&assertion=1&points=10"); + executeFails("date=" + validVerificationDateString() + "&location=testcase&certify=1&rules=1&assertion=z&points=10"); } @Test public void testAssureListingValid() throws IOException { String uniqueLoc = createUniqueName(); - execute("date=2000-01-01&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10"); + execute("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10"); String cookie = login(assureeM, TEST_PASSWORD); URLConnection url = get(cookie, MyPoints.PATH); @@ -203,7 +230,7 @@ public class TestAssurance extends ManagedTest { @Test public void testAssurerListingValid() throws IOException { String uniqueLoc = createUniqueName(); - executeSuccess("date=2000-01-01&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10"); + executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10"); String cookie = login(assurerM, TEST_PASSWORD); URLConnection url = get(cookie, MyPoints.PATH); String resp = IOUtils.readURL(url); @@ -268,7 +295,7 @@ public class TestAssurance extends ManagedTest { // enter second entry String uniqueLoc = createUniqueName(); - executeSuccess("date=2000-01-01&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10"); + executeSuccess("date=" + validVerificationDateString() + "&location=" + uniqueLoc + "&certify=1&rules=1&assertion=1&points=10"); // enter third entry on the same day URLConnection uc = get(cookie, AssurePage.PATH); diff --git a/tests/org/cacert/gigi/testUtils/ConfiguredTest.java b/tests/org/cacert/gigi/testUtils/ConfiguredTest.java index 5ab20079..dcd39906 100644 --- a/tests/org/cacert/gigi/testUtils/ConfiguredTest.java +++ b/tests/org/cacert/gigi/testUtils/ConfiguredTest.java @@ -13,6 +13,9 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Signature; import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; import java.util.Properties; import java.util.TimeZone; import java.util.regex.Matcher; @@ -30,6 +33,7 @@ import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.testUtils.TestEmailReceiver.TestMail; import org.cacert.gigi.util.DatabaseManager; import org.cacert.gigi.util.DomainAssessment; +import org.cacert.gigi.util.Notary; import org.cacert.gigi.util.PEM; import org.cacert.gigi.util.ServerConstants; import org.junit.BeforeClass; @@ -213,4 +217,13 @@ public abstract class ConfiguredTest { } System.out.println("Database reset complete in " + (System.currentTimeMillis() - ms) + " ms."); } + + public static String validVerificationDateString() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(System.currentTimeMillis()); + c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION + 1); + return sdf.format(new Date(c.getTimeInMillis())); + } + } diff --git a/tests/org/cacert/gigi/util/TestNotary.java b/tests/org/cacert/gigi/util/TestNotary.java index 38f8582f..862e7bfe 100644 --- a/tests/org/cacert/gigi/util/TestNotary.java +++ b/tests/org/cacert/gigi/util/TestNotary.java @@ -31,7 +31,7 @@ public class TestNotary extends BusinessTest { }; try { - Notary.assure(assurer, users[0], users[0].getPreferredName(), users[0].getDoB(), -1, "test-notary", "2014-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(assurer, users[0], users[0].getPreferredName(), users[0].getDoB(), -1, "test-notary", validVerificationDateString(), AssuranceType.FACE_TO_FACE); fail("This shouldn't have passed"); } catch (GigiApiException e) { // expected @@ -39,9 +39,9 @@ public class TestNotary extends BusinessTest { for (int i = 0; i < result.length; i++) { assertEquals(result[i], assurer.getMaxAssurePoints()); - assuranceFail(assurer, users[i], result[i] + 1, "test-notary", "2014-01-01"); - Notary.assure(assurer, users[i], users[i].getPreferredName(), users[i].getDoB(), result[i], "test-notary", "2014-01-01", AssuranceType.FACE_TO_FACE); - assuranceFail(assurer, users[i], result[i], "test-notary", "2014-01-01"); + assuranceFail(assurer, users[i], result[i] + 1, "test-notary", validVerificationDateString()); + Notary.assure(assurer, users[i], users[i].getPreferredName(), users[i].getDoB(), result[i], "test-notary", validVerificationDateString(), AssuranceType.FACE_TO_FACE); + assuranceFail(assurer, users[i], result[i], "test-notary", validVerificationDateString()); } assertEquals(35, assurer.getMaxAssurePoints()); @@ -74,12 +74,12 @@ public class TestNotary extends BusinessTest { ObjectCache.clearAllCaches(); // reload values from db User assurer = User.getById(id); for (int i = 0; i < users.length; i++) { - assuranceFail(assurer, users[i], -1, "test-notary", "2014-01-01"); - assuranceFail(assurer, users[i], 11, "test-notary", "2014-01-01"); + assuranceFail(assurer, users[i], -1, "test-notary", validVerificationDateString()); + assuranceFail(assurer, users[i], 11, "test-notary", validVerificationDateString()); if (User.POJAM_ENABLED) { - Notary.assure(assurer, users[i], users[i].getPreferredName(), users[i].getDoB(), 10, "test-notary", "2014-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(assurer, users[i], users[i].getPreferredName(), users[i].getDoB(), 10, "test-notary", validVerificationDateString(), AssuranceType.FACE_TO_FACE); } - assuranceFail(assurer, users[i], 10, "test-notary", "2014-01-01"); + assuranceFail(assurer, users[i], 10, "test-notary", validVerificationDateString()); } } @@ -95,28 +95,28 @@ public class TestNotary extends BusinessTest { // null date assuranceFail(assuranceUser, assuree, 10, "notary-junit-test", null); // null location - assuranceFail(assuranceUser, assuree, 10, null, "2014-01-01"); + assuranceFail(assuranceUser, assuree, 10, null, validVerificationDateString()); // empty location - assuranceFail(assuranceUser, assuree, 10, "", "2014-01-01"); + assuranceFail(assuranceUser, assuree, 10, "", validVerificationDateString()); // date in the future assuranceFail(assuranceUser, assuree, 10, "notary-junit-test", DateSelector.getDateFormat().format(new Date(System.currentTimeMillis() + 2 * 24 * 60 * 60 * 1000))); // location too short - assuranceFail(assuranceUser, assuree, 10, "n", "2014-01-01"); + assuranceFail(assuranceUser, assuree, 10, "n", validVerificationDateString()); // points too low - assuranceFail(assuranceUser, assuree, -1, "notary-junit-test", "2014-01-01"); + assuranceFail(assuranceUser, assuree, -1, "notary-junit-test", validVerificationDateString()); // points too high - assuranceFail(assuranceUser, assuree, 11, "notary-junit-test", "2014-01-01"); + assuranceFail(assuranceUser, assuree, 11, "notary-junit-test", validVerificationDateString()); // assure oneself - assuranceFail(assuranceUser, assuranceUser, 10, "notary-junit-test", "2014-01-01"); + assuranceFail(assuranceUser, assuranceUser, 10, "notary-junit-test", validVerificationDateString()); // not an assurer - assuranceFail(assuree, assuranceUser, 10, "notary-junit-test", "2014-01-01"); + assuranceFail(assuree, assuranceUser, 10, "notary-junit-test", validVerificationDateString()); // valid - Notary.assure(assuranceUser, assuree, assuree.getPreferredName(), assuree.getDoB(), 10, "notary-junit-test", "2014-01-01", AssuranceType.FACE_TO_FACE); + Notary.assure(assuranceUser, assuree, assuree.getPreferredName(), assuree.getDoB(), 10, "notary-junit-test", validVerificationDateString(), AssuranceType.FACE_TO_FACE); // assure double - assuranceFail(assuranceUser, assuree, 10, "notary-junit-test", "2014-01-01"); + assuranceFail(assuranceUser, assuree, 10, "notary-junit-test", validVerificationDateString()); } } -- 2.39.2