package org.cacert.gigi.dbObjects;
-import java.sql.Date;
-
import org.cacert.gigi.GigiApiException;
import org.cacert.gigi.database.GigiPreparedStatement;
import org.cacert.gigi.dbObjects.Certificate.CertificateStatus;
+import org.cacert.gigi.util.DayDate;
public class SupportedUser {
return true;
}
- public boolean setDob(Date dob) throws GigiApiException {
- if (dob.toString().equals(target.getDoB().toString())) {
+ public boolean setDob(DayDate dob) throws GigiApiException {
+ if (dob.equals(target.getDoB())) {
return false;
}
writeSELog("SE dob change");
package org.cacert.gigi.dbObjects;
-import java.sql.Date;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import org.cacert.gigi.database.GigiResultSet;
import org.cacert.gigi.localisation.Language;
import org.cacert.gigi.output.DateSelector;
+import org.cacert.gigi.util.DayDate;
import org.cacert.gigi.util.Notary;
import org.cacert.gigi.util.PasswordHash;
import org.cacert.gigi.util.PasswordStrengthChecker;
private Name name = new Name(null, null, null, null);
- private Date dob;
+ private DayDate dob;
private String email;
private void updateName(GigiResultSet rs) {
name = new Name(rs.getString("fname"), rs.getString("lname"), rs.getString("mname"), rs.getString("suffix"));
- dob = rs.getDate("dob");
+ dob = new DayDate(rs.getDate("dob"));
email = rs.getString("email");
String localeStr = rs.getString("language");
}
}
- public User(String email, String password, Name name, Date dob, Locale locale) throws GigiApiException {
+ public User(String email, String password, Name name, DayDate dob, Locale locale) throws GigiApiException {
this.email = email;
this.dob = dob;
this.name = name;
query.setString(4, name.getMname());
query.setString(5, name.getLname());
query.setString(6, name.getSuffix());
- query.setDate(7, dob);
+ query.setDate(7, dob.toSQLDate());
query.setString(8, locale.toString());
query.setInt(9, getId());
query.execute();
return name;
}
- public Date getDoB() {
+ public DayDate getDoB() {
return dob;
}
- public void setDoB(Date dob) {
+ public void setDoB(DayDate dob) {
this.dob = dob;
}
public boolean isOfAge(int desiredAge) {
Calendar c = Calendar.getInstance();
- c.setTime(dob);
+ c.setTimeInMillis(dob.getTime());
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
update.setString(2, name.getLname());
update.setString(3, name.getMname());
update.setString(4, name.getSuffix());
- update.setDate(5, getDoB());
+ update.setDate(5, getDoB().toSQLDate());
update.setInt(6, getId());
update.executeUpdate();
}
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
-import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.TimeZone;
import org.cacert.gigi.GigiApiException;
import org.cacert.gigi.localisation.Language;
import org.cacert.gigi.output.template.Outputable;
+import org.cacert.gigi.util.DayDate;
import org.cacert.gigi.util.HTMLEncoder;
public class DateSelector implements Outputable {
private String[] names;
- public DateSelector(String day, String month, String year, Date date) {
+ public DateSelector(String day, String month, String year, DayDate date) {
this(day, month, year);
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTF"));
- cal.setTime(date);
+ cal.setTimeInMillis(date.getTime());
this.day = cal.get(Calendar.DAY_OF_MONTH);
this.month = cal.get(Calendar.MONTH) + 1;
this.year = cal.get(Calendar.YEAR);
return "DateSelector [names=" + Arrays.toString(names) + ", day=" + day + ", month=" + month + ", year=" + year + "]";
}
- public java.sql.Date getDate() {
+ public DayDate getDate() {
Calendar gc = GregorianCalendar.getInstance();
- gc.set(year, month - 1, day);
- return new java.sql.Date(gc.getTime().getTime());
+ gc.set(year, month - 1, day, 0, 0, 0);
+ gc.set(Calendar.MILLISECOND, 0);
+ return new DayDate(gc.getTime().getTime());
}
public static SimpleDateFormat getDateFormat() {
import org.cacert.gigi.localisation.Language;
import org.cacert.gigi.output.DateSelector;
+import org.cacert.gigi.util.DayDate;
import org.cacert.gigi.util.HTMLEncoder;
public class Template implements Outputable {
}
if (s instanceof Outputable) {
((Outputable) s).output(out, l, vars);
- } else if (s instanceof java.sql.Date) {
- out.print(DateSelector.getDateFormat().format(s));
+ } else if (s instanceof DayDate) {
+ out.print(DateSelector.getDateFormat().format(((DayDate) s).toDate()));
} else if (s instanceof Date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
out.print(sdf.format(s));
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import org.cacert.gigi.output.template.Template;
import org.cacert.gigi.pages.Page;
import org.cacert.gigi.pages.PasswordResetPage;
+import org.cacert.gigi.util.DayDate;
import org.cacert.gigi.util.Notary;
import org.cacert.gigi.util.RandomToken;
import org.cacert.gigi.util.ServerConstants;
private Name assureeName;
- private Date dob;
+ private DayDate dob;
private String location = "";
res.put("nameExplicit", assuree.getName());
res.put("name", assuree.getName().toString());
res.put("maxpoints", assurer.getMaxAssurePoints());
- res.put("dob", sdf.format(assuree.getDoB()));
- res.put("dobFmt2", sdf2.format(assuree.getDoB()));
+ res.put("dob", sdf.format(assuree.getDoB().toDate()));
+ res.put("dobFmt2", sdf2.format(assuree.getDoB().toDate()));
res.put("location", location);
res.put("date", date);
res.put("aword", aword);
--- /dev/null
+package org.cacert.gigi.util;
+
+import java.sql.Date;
+
+/**
+ * This Class consists of a millisecond timestamp that is only interesting up to
+ * day-precision.
+ */
+public class DayDate {
+
+ public static final long MILLI_DAY = 24 * 60 * 60 * 1000;
+
+ private long time;
+
+ /**
+ * Creates a new {@link DayDate} from the SQL Day-exact variant {@link Date}
+ * .
+ *
+ * @see #toSQLDate()
+ */
+ public DayDate(Date date) {
+ this(date.getTime());
+ }
+
+ /**
+ * Creates a new {@link DayDate} based on the given millisecond timestamp.
+ *
+ * @param millis
+ * the timestamp to create the Date from.
+ * @throws IllegalArgumentException
+ * if the parameter contains more precision than needed.
+ */
+ public DayDate(long millis) {
+ this.time = millis;
+ if (millis % MILLI_DAY != 0) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Gets the enclosed timestamp.
+ *
+ * @return the enclosed timestamp.
+ */
+ public long getTime() {
+ return time;
+ }
+
+ /**
+ * Converts this DayDate to an {@link Date}.
+ *
+ * @return the corresponding {@link Date}
+ * @see #DayDate(Date)
+ */
+ public Date toSQLDate() {
+ return new Date(time);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof DayDate)) {
+ throw new Error("You may not compare this date somthing other than a DayDate");
+ }
+ return ((DayDate) obj).time == time;
+ }
+
+ public java.util.Date toDate() {
+ return new java.util.Date(time);
+ }
+}
* @throws GigiApiException
* if the assurance fails (for various reasons)
*/
- public synchronized static void assure(User assurer, User assuree, Name assureeName, Date dob, int awarded, String location, String date, AssuranceType type) throws GigiApiException {
+ public synchronized static void assure(User assurer, User assuree, Name assureeName, DayDate dob, int awarded, String location, String date, AssuranceType type) throws GigiApiException {
may(assurer, assuree, AssuranceType.FACE_TO_FACE);
GigiApiException gae = new GigiApiException();
if ( !gae.isEmpty()) {
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
-import java.sql.Date;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Locale;
import org.cacert.gigi.dbObjects.Name;
import org.cacert.gigi.dbObjects.User;
import org.cacert.gigi.testUtils.ManagedTest;
+import org.cacert.gigi.util.DayDate;
import org.junit.Test;
public class TestObjectCache extends ManagedTest {
assertThat(User.getById(uid), is(sameInstance(User.getById(uid))));
Calendar c = Calendar.getInstance();
- c.set(1950, 1, 1);
- User u = new User(createUniqueName() + "@example.org", TEST_PASSWORD, new Name("fname", "lname", "mname", "suffix"), new Date(c.getTime().getTime()), Locale.ENGLISH);
+ c.set(1950, 1, 1, 0, 0, 0);
+ c.set(Calendar.MILLISECOND, 0);
+ User u = new User(createUniqueName() + "@example.org", TEST_PASSWORD, new Name("fname", "lname", "mname", "suffix"), new DayDate(c.getTime().getTime()), Locale.ENGLISH);
assertThat(u, is(sameInstance(User.getById(u.getId()))));
assertThat(User.getById(u.getId()), is(sameInstance(User.getById(u.getId()))));
import static org.junit.Assert.*;
import java.io.IOException;
-import java.sql.Date;
import java.sql.SQLException;
import java.util.Locale;
import org.cacert.gigi.dbObjects.Name;
import org.cacert.gigi.dbObjects.User;
import org.cacert.gigi.testUtils.ManagedTest;
+import org.cacert.gigi.util.DayDate;
import org.junit.Test;
public class TestUser extends ManagedTest {
public void testStoreAndLoad() throws SQLException, GigiApiException {
long dob = System.currentTimeMillis();
dob -= dob % (1000 * 60 * 60 * 24);
- User u = new User(createUniqueName() + "a@email.org", "password", new Name("user", "last", "", ""), new java.sql.Date(dob), Locale.ENGLISH);
+ User u = new User(createUniqueName() + "a@email.org", "password", new Name("user", "last", "", ""), new DayDate(dob), Locale.ENGLISH);
int id = u.getId();
User u2 = User.getById(id);
assertEquals(u.getName(), u2.getName());
@Test
public void testDoubleInsert() throws GigiApiException {
- User u = new User(createUniqueName() + "@example.org", TEST_PASSWORD, new Name("f", "k", "m", "s"), new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 365), Locale.ENGLISH);
+ long d = System.currentTimeMillis();
+ d -= d % DayDate.MILLI_DAY;
+ User u = new User(createUniqueName() + "@example.org", TEST_PASSWORD, new Name("f", "k", "m", "s"), new DayDate(d + 1000L * 60 * 60 * 24 * 365), Locale.ENGLISH);
Assurance[] ma = u.getMadeAssurances();
Assurance[] ma2 = u.getMadeAssurances();
Assurance[] ra = u.getReceivedAssurances();
cal.set(Calendar.DAY_OF_MONTH, Calendar.FEBRUARY);
cal.set(Calendar.MONTH, 1);
Date d = new Date(cal.getTimeInMillis());
- assertEquals(d.toString(), u.getDoB().toString());
+ assertEquals(d.toString(), u.getDoB().toSQLDate().toString());
}
@Test
@Test
public void testAssureFormRaceName() throws IOException, SQLException {
- testAssureFormRace(true);
+ testAssureFormRace(true, false);
}
@Test
public void testAssureFormRaceDoB() throws IOException, SQLException {
- testAssureFormRace(false);
+ testAssureFormRace(false, false);
}
- public void testAssureFormRace(boolean name) throws IOException, SQLException {
+ @Test
+ public void testAssureFormRaceNameBlind() throws IOException, SQLException {
+ testAssureFormRace(true, true);
+ }
+
+ @Test
+ public void testAssureFormRaceDoBBlind() throws IOException, SQLException {
+ testAssureFormRace(false, true);
+ }
+
+ public void testAssureFormRace(boolean name, boolean succeed) throws IOException, SQLException {
URLConnection uc = buildupAssureFormConnection(true);
String assureeCookie = login(assureeM, TEST_PASSWORD);
- String newName = "lname=" + (name ? "c" : "a") + "&fname=a&mname=&suffix=";
- String newDob = "day=1&month=1&year=" + (name ? 1910 : 1911);
+ String newName = "lname=" + (name && !succeed ? "a" : "c") + "&fname=a&mname=&suffix=";
+ String newDob = "day=1&month=1&year=" + ( !name && !succeed ? 1911 : 1910);
assertNull(executeBasicWebInteraction(assureeCookie, MyDetails.PATH, newName + "&" + newDob + "&processDetails", 0));
uc.getOutputStream().write(("date=2000-01-01&location=testcase&certify=1&rules=1&CCAAgreed=1&assertion=1&points=10").getBytes("UTF-8"));
uc.getOutputStream().flush();
String error = fetchStartErrorMessage(IOUtils.readURL(uc));
- assertTrue(error, !error.startsWith("</div>"));
+ if (succeed) {
+ assertNull(error);
+ } else {
+ assertTrue(error, !error.startsWith("</div>"));
+ assertThat(error, containsString("changed his personal details"));
+ }
}
@Test
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
-import java.sql.Date;
import java.util.Base64;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.cacert.gigi.ping.DomainPinger;
import org.cacert.gigi.ping.PingerDaemon;
import org.cacert.gigi.util.AuthorizationContext;
+import org.cacert.gigi.util.DayDate;
import org.cacert.gigi.util.Notary;
import sun.security.x509.X509Key;
private void createUser(String email) throws GigiApiException, IllegalAccessException {
Calendar gc = GregorianCalendar.getInstance();
gc.set(1990, 0, 1);
- User u = new User(email, "xvXV12°§", new Name("Först", "Läst", "Müddle", "Süffix"), new Date(gc.getTime().getTime()), Locale.ENGLISH);
+ User u = new User(email, "xvXV12°§", new Name("Först", "Läst", "Müddle", "Süffix"), new DayDate(gc.getTime().getTime()), Locale.ENGLISH);
EmailAddress ea = u.getEmails()[0];
if (f == null) {
System.out.println("verification failed");