]> WPIA git - gigi.git/commitdiff
fix: correct validation of minimum and maximum ages
authorFelix Dörre <felix@dogcraft.de>
Sat, 22 Jul 2017 21:12:25 +0000 (23:12 +0200)
committerFelix Dörre <felix@dogcraft.de>
Sun, 6 Aug 2017 22:43:34 +0000 (00:43 +0200)
Instead of mapping a DayDate to a single point in time, introduce the
concept of an “earliest start” and “latest end” of a date, and use the
appropriate one in various places.

Change-Id: Idbc2aa2daadf15fbdbc99e5079eb98dc7aaca92d

src/club/wpia/gigi/dbObjects/User.java
src/club/wpia/gigi/pages/main/Signup.java
src/club/wpia/gigi/util/CalendarUtil.java
src/club/wpia/gigi/util/DayDate.java
src/club/wpia/gigi/util/Notary.java
tests/club/wpia/gigi/TestCalendarUtil.java
tests/club/wpia/gigi/pages/account/TestMyDetailsEdit.java

index b65dbc5a027f5edee63c301b3dd12cd42f661957..cdd00d6f3533b2ba7656203a960f4014aad426d7 100644 (file)
@@ -167,7 +167,7 @@ public class User extends CertificateOwner {
                 throw new GigiApiException("Entered date of birth is below the restricted age requirements.");
             }
 
-            if (CalendarUtil.isOfAge(dob, User.MAXIMUM_PLAUSIBLE_AGE)) {
+            if (CalendarUtil.isYearsInFuture(dob.end(), User.MAXIMUM_PLAUSIBLE_AGE)) {
                 throw new GigiApiException("Entered date of birth exceeds the maximum age set in our policies. Please check your DoB is correct and contact support if the issue persists.");
             }
             this.dob = dob;
index 8c070782278a9dafcaca76fd0d1dcdf9d0919454..746fd803a6bee2790cd6f37c2ac4070ee8a47fde 100644 (file)
@@ -120,7 +120,7 @@ public class Signup extends Form {
             ga.mergeInto(new GigiApiException("Entered date of birth is below the restricted age requirements."));
         }
 
-        if (CalendarUtil.isOfAge(myDoB.getDate(), User.MAXIMUM_PLAUSIBLE_AGE)) {
+        if (CalendarUtil.isYearsInFuture(myDoB.getDate().end(), User.MAXIMUM_PLAUSIBLE_AGE)) {
             ga.mergeInto(new GigiApiException("Entered date of birth exceeds the maximum age set in our policies. Please check your DoB is correct and contact support if the issue persists."));
         }
 
index 6ff7bb291d8a6f2d5a6a5f5262a8dfb4cbb1e265..c7b2bb0faef15015a59545606417692db72f7a8b 100644 (file)
@@ -16,12 +16,12 @@ public class CalendarUtil {
     }
 
     public static boolean isOfAge(DayDate dob, int age) {
+        return isYearsInFuture(dob.start(), age);
+    }
+
+    public static boolean isYearsInFuture(Date dt, int age) {
         Calendar c = Calendar.getInstance();
-        c.setTimeInMillis(dob.getTime());
-        int year = c.get(Calendar.YEAR);
-        int month = c.get(Calendar.MONTH);
-        int day = c.get(Calendar.DAY_OF_MONTH);
-        c.set(year, month, day);
+        c.setTime(dt);
         c.add(Calendar.YEAR, age);
 
         return System.currentTimeMillis() >= c.getTime().getTime();
index 8ade34270b444839aa9549f72e746ce17d54460d..85473eccdf1b7999e51542be10655b84ced0d648 100644 (file)
@@ -8,7 +8,9 @@ import java.sql.Date;
  */
 public class DayDate {
 
-    public static final long MILLI_DAY = 24 * 60 * 60 * 1000;
+    private static final int MILLI_HOUR = 60 * 60 * 1000;
+
+    public static final long MILLI_DAY = 24 * MILLI_HOUR;
 
     private long time;
 
@@ -75,4 +77,24 @@ public class DayDate {
     public java.util.Date toDate() {
         return new java.util.Date(time);
     }
+
+    // Timezones currently reach from UTC-12 to UTC+14 that allows us to define
+    // the "earliest start" and "latest end" of a Date.
+    /**
+     * Gets this date's starting point.
+     * 
+     * @return The earliest point in time where this date was in any timezone
+     */
+    public java.util.Date start() {
+        return new java.util.Date(time - 12 * MILLI_HOUR);
+    }
+
+    /**
+     * Gets this date's ending point.
+     * 
+     * @return The latest point in time where this Date was any timezone
+     */
+    public java.util.Date end() {
+        return new java.util.Date(time + 14 * MILLI_HOUR + 24 * MILLI_HOUR);
+    }
 }
index 36f1fa48c3c603c3c1dd5ed7ab3a30437bf5d2a1..c349a0f92ad61f5fa8049f9c71e0643c28325b13 100644 (file)
@@ -3,7 +3,6 @@ package club.wpia.gigi.util;
 import java.io.IOException;
 import java.text.ParseException;
 import java.util.Calendar;
-import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.Map;
@@ -93,13 +92,11 @@ public class Notary {
             gae.mergeInto(new GigiApiException("You must enter the date when you met the applicant."));
         } else {
             try {
-                Date d = DateSelector.getDateFormat().parse(date);
-                Calendar gc = GregorianCalendar.getInstance();
-                gc.setTimeInMillis(System.currentTimeMillis());
-                gc.add(Calendar.HOUR_OF_DAY, 12);
-                if (d.getTime() > gc.getTimeInMillis()) {
+                DayDate d = new DayDate(DateSelector.getDateFormat().parse(date).getTime());
+                if (d.start().getTime() > System.currentTimeMillis()) {
                     gae.mergeInto(new GigiApiException("You must not enter a date in the future."));
                 }
+                Calendar gc = GregorianCalendar.getInstance();
                 gc.setTimeInMillis(System.currentTimeMillis());
                 gc.add(Calendar.MONTH, -LIMIT_MAX_MONTHS_VERIFICATION);
                 if (d.getTime() < gc.getTimeInMillis()) {
index 5bed6e56305561ba7c18ed7502771c9fa64f7ccd..25685e7a576205d1b37ad360a917a4bcf02375d9 100644 (file)
@@ -47,8 +47,11 @@ public class TestCalendarUtil {
         assertTrue(CalendarUtil.isOfAge(dob, 13));
 
         assertTrue(CalendarUtil.isOfAge(dob, 14));
-
-        dob = CalendarUtil.getDateFromComponents(year - 14, month, days + 1);
+        // We need one day as safety margin. Between 10:00 and 23:59 UTC there
+        // is a place on earth (UTC+1 to UTC+14) where a person having
+        // birthday "tomorrow" is already of that age. So we need the day after
+        // tomorrow for doing this check the easy way.
+        dob = CalendarUtil.getDateFromComponents(year - 14, month, days + 2);
         assertFalse(CalendarUtil.isOfAge(dob, 14));
 
     }
index 7f2a811ff3fecc68f05177433e0508cf40afd4ed..d5b1cf33f7c4da0390ab4ad8f5b962f92ab23099 100644 (file)
@@ -17,9 +17,8 @@ import club.wpia.gigi.GigiApiException;
 import club.wpia.gigi.dbObjects.Group;
 import club.wpia.gigi.dbObjects.Name;
 import club.wpia.gigi.dbObjects.NamePart;
-import club.wpia.gigi.dbObjects.User;
 import club.wpia.gigi.dbObjects.NamePart.NamePartType;
-import club.wpia.gigi.pages.account.MyDetails;
+import club.wpia.gigi.dbObjects.User;
 import club.wpia.gigi.testUtils.ManagedTest;
 
 public class TestMyDetailsEdit extends ManagedTest {
@@ -83,11 +82,19 @@ public class TestMyDetailsEdit extends ManagedTest {
         assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "day=1&month=1&year=test&action=updateDoB", 0));
     }
 
+    /**
+     * Tests that changing the date of birth to a too recent one results in an
+     * error.
+     * 
+     * @throws IOException
+     *             when web interactions fail.
+     * @see club.wpia.gigi.TestCalendarUtil#testIsOfAge()
+     */
     @Test
     public void testChangeTooYoung() throws IOException {
         Calendar c = GregorianCalendar.getInstance();
         c.add(Calendar.YEAR, -User.MINIMUM_AGE);
-        c.add(Calendar.DAY_OF_MONTH, +1);
+        c.add(Calendar.DAY_OF_MONTH, +2);
         assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "day=" + c.get(Calendar.DAY_OF_MONTH) + "&month=" + (c.get(Calendar.MONTH) + 1) + "&year=" + c.get(Calendar.YEAR) + "&action=updateDoB", 0));
     }
 
@@ -95,7 +102,7 @@ public class TestMyDetailsEdit extends ManagedTest {
     public void testChangeTooOld() throws IOException {
         Calendar c = GregorianCalendar.getInstance();
         c.add(Calendar.YEAR, -User.MAXIMUM_PLAUSIBLE_AGE);
-        c.add(Calendar.DAY_OF_MONTH, -1);
+        c.add(Calendar.DAY_OF_MONTH, -2);
         assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "day=" + c.get(Calendar.DAY_OF_MONTH) + "&month=" + (c.get(Calendar.MONTH) + 1) + "&year=" + c.get(Calendar.YEAR) + "&action=updateDoB", 0));
     }