]> WPIA git - gigi.git/commitdiff
add: residence country for user account
authorINOPIAE <m.maengel@inopiae.de>
Fri, 12 Aug 2016 17:27:19 +0000 (19:27 +0200)
committerBenny Baumann <BenBE1987@gmx.net>
Sun, 14 Aug 2016 19:14:43 +0000 (21:14 +0200)
fixes issue #79

Change-Id: I8fc77689a6a0effcf27e2621b9802b8b04e15cb1

12 files changed:
doc/Data.uxf
src/org/cacert/gigi/database/DatabaseConnection.java
src/org/cacert/gigi/database/tableStructure.sql
src/org/cacert/gigi/database/upgrade/from_22.sql [new file with mode: 0644]
src/org/cacert/gigi/dbObjects/User.java
src/org/cacert/gigi/pages/account/MyDetailsForm.java
src/org/cacert/gigi/pages/account/MyDetailsForm.templ
src/org/cacert/gigi/pages/account/MyDetailsFormAssured.templ
src/org/cacert/gigi/pages/main/Signup.java
src/org/cacert/gigi/pages/main/Signup.templ
tests/org/cacert/gigi/testUtils/BusinessTest.java
util-testing/org/cacert/gigi/pages/Manager.java

index 225ae2d2436606b9a3e3a48382b9c8738c24ef16..0c554642480e4b4377622c5f80347394469e3b0c 100644 (file)
@@ -96,6 +96,7 @@ administers&gt;</panel_attributes>
 -primaryEmail: String
 -locale: Locale
 -Name
 -primaryEmail: String
 -locale: Locale
 -Name
+-country: varchar(2)
 --
 +hasPassedCATS(): boolean
 +isInGroup(:Group): boolean
 --
 +hasPassedCATS(): boolean
 +isInGroup(:Group): boolean
index d9febb087fc2bdbe0a570246b994428551cd7672..b5684edd8bf8d4b0db46b2cbe500df7327ce1d2f 100644 (file)
@@ -122,7 +122,7 @@ public class DatabaseConnection {
 
     }
 
 
     }
 
-    public static final int CURRENT_SCHEMA_VERSION = 22;
+    public static final int CURRENT_SCHEMA_VERSION = 23;
 
     public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
 
 
     public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
 
index a8d92f57dca3879a8c39aa2ddd5bb51c5b956598..947b09edac5f4c4378f47a1a522593c760855537 100644 (file)
@@ -16,6 +16,7 @@ CREATE TABLE "users" (
   "dob" date NOT NULL,
   "verified" boolean NOT NULL DEFAULT 'false',
   "language" varchar(5) NOT NULL DEFAULT '',
   "dob" date NOT NULL,
   "verified" boolean NOT NULL DEFAULT 'false',
   "language" varchar(5) NOT NULL DEFAULT '',
+  "country" varchar(2) NULL,
   PRIMARY KEY ("id")
 );
 CREATE INDEX ON "users" ("email");
   PRIMARY KEY ("id")
 );
 CREATE INDEX ON "users" ("email");
@@ -373,7 +374,7 @@ CREATE TABLE "schemeVersion" (
   "version" smallint NOT NULL,
   PRIMARY KEY ("version")
 );
   "version" smallint NOT NULL,
   PRIMARY KEY ("version")
 );
-INSERT INTO "schemeVersion" (version)  VALUES(22);
+INSERT INTO "schemeVersion" (version)  VALUES(23);
 
 DROP TABLE IF EXISTS `passwordResetTickets`;
 CREATE TABLE `passwordResetTickets` (
 
 DROP TABLE IF EXISTS `passwordResetTickets`;
 CREATE TABLE `passwordResetTickets` (
diff --git a/src/org/cacert/gigi/database/upgrade/from_22.sql b/src/org/cacert/gigi/database/upgrade/from_22.sql
new file mode 100644 (file)
index 0000000..14623b8
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE "users" ADD COLUMN  "country" varchar(2) NULL;
\ No newline at end of file
index a6e1d3f13c3abb43a776cdbdde0e4b5b4839cb0e..83a89fa6252d9fd56872c6864af263b684eee127 100644 (file)
@@ -66,6 +66,8 @@ public class User extends CertificateOwner {
 
     private Name preferredName;
 
 
     private Name preferredName;
 
+    private CountryCode residenceCountry;
+
     protected User(GigiResultSet rs) {
         super(rs.getInt("id"));
         updateName(rs);
     protected User(GigiResultSet rs) {
         super(rs.getInt("id"));
         updateName(rs);
@@ -76,6 +78,14 @@ public class User extends CertificateOwner {
         email = rs.getString("email");
         preferredName = Name.getById(rs.getInt("preferredName"));
 
         email = rs.getString("email");
         preferredName = Name.getById(rs.getInt("preferredName"));
 
+        try {
+            if (rs.getString("Country") != null) {
+                residenceCountry = CountryCode.getCountryCode(rs.getString("Country"), CountryCode.CountryCodeType.CODE_2_CHARS);
+            }
+        } catch (GigiApiException e) {
+            throw new Error(e);
+        }
+
         String localeStr = rs.getString("language");
         if (localeStr == null || localeStr.equals("")) {
             locale = Locale.getDefault();
         String localeStr = rs.getString("language");
         if (localeStr == null || localeStr.equals("")) {
             locale = Locale.getDefault();
@@ -94,18 +104,19 @@ public class User extends CertificateOwner {
         }
     }
 
         }
     }
 
-    public User(String email, String password, DayDate dob, Locale locale, NamePart... preferred) throws GigiApiException {
+    public User(String email, String password, DayDate dob, Locale locale, CountryCode residenceCountry, NamePart... preferred) throws GigiApiException {
         this.email = email;
         this.dob = dob;
         this.locale = locale;
         this.preferredName = new Name(this, preferred);
         this.email = email;
         this.dob = dob;
         this.locale = locale;
         this.preferredName = new Name(this, preferred);
-        try (GigiPreparedStatement query = new GigiPreparedStatement("INSERT INTO `users` SET `email`=?, `password`=?, `dob`=?, `language`=?, id=?, `preferredName`=?")) {
+        try (GigiPreparedStatement query = new GigiPreparedStatement("INSERT INTO `users` SET `email`=?, `password`=?, `dob`=?, `language`=?, id=?, `preferredName`=?, `country` = ?")) {
             query.setString(1, email);
             query.setString(2, PasswordHash.hash(password));
             query.setDate(3, dob.toSQLDate());
             query.setString(4, locale.toString());
             query.setInt(5, getId());
             query.setInt(6, preferredName.getId());
             query.setString(1, email);
             query.setString(2, PasswordHash.hash(password));
             query.setDate(3, dob.toSQLDate());
             query.setString(4, locale.toString());
             query.setInt(5, getId());
             query.setInt(6, preferredName.getId());
+            query.setString(7, residenceCountry == null ? null : residenceCountry.getCountryCode());
             query.execute();
         }
         new EmailAddress(this, email, locale);
             query.execute();
         }
         new EmailAddress(this, email, locale);
@@ -617,4 +628,20 @@ public class User extends CertificateOwner {
 
     private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {}
 
 
     private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {}
 
+    public CountryCode getResidenceCountry() {
+        return residenceCountry;
+    }
+
+    public void setResidenceCountry(CountryCode residenceCountry) {
+        this.residenceCountry = residenceCountry;
+        rawUpdateCountryData();
+    }
+
+    private void rawUpdateCountryData() {
+        try (GigiPreparedStatement update = new GigiPreparedStatement("UPDATE users SET country=? WHERE id=?")) {
+            update.setString(1, residenceCountry == null ? null : residenceCountry.getCountryCode());
+            update.setInt(2, getId());
+            update.executeUpdate();
+        }
+    }
 }
 }
index fd329ffdecaeb191f23b1fd78deb5f13c6372cd0..a8ca49fc5d471e377fc0224b989604f744302482 100644 (file)
@@ -10,6 +10,7 @@ import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.ArrayIterable;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.ArrayIterable;
+import org.cacert.gigi.output.CountrySelector;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.NameInput;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.NameInput;
 import org.cacert.gigi.output.template.Form;
@@ -30,12 +31,20 @@ public class MyDetailsForm extends Form {
 
     private NameInput ni;
 
 
     private NameInput ni;
 
+    private CountrySelector cs;
+
     public MyDetailsForm(HttpServletRequest hsr, User target) {
         super(hsr);
         this.target = target;
         ni = new NameInput();
 
         this.ds = new DateSelector("day", "month", "year", target.getDoB());
     public MyDetailsForm(HttpServletRequest hsr, User target) {
         super(hsr);
         this.target = target;
         ni = new NameInput();
 
         this.ds = new DateSelector("day", "month", "year", target.getDoB());
+
+        if (target.getResidenceCountry() == null) {
+            this.cs = new CountrySelector("residenceCountry", true);
+        } else {
+            this.cs = new CountrySelector("residenceCountry", true, target.getResidenceCountry());
+        }
     }
 
     @Override
     }
 
     @Override
@@ -82,6 +91,10 @@ public class MyDetailsForm extends Form {
                 ds.update(req);
                 target.setDoB(ds.getDate());
             }
                 ds.update(req);
                 target.setDoB(ds.getDate());
             }
+            if ("updateResidenceCountry".equals(action)) {
+                cs.update(req);
+                target.setResidenceCountry(cs.getCountry());
+            }
         } catch (GigiApiException e) {
             e.format(out, Page.getLanguage(req));
             return false;
         } catch (GigiApiException e) {
             e.format(out, Page.getLanguage(req));
             return false;
@@ -119,6 +132,7 @@ public class MyDetailsForm extends Form {
         });
         vars.put("name", ni);
         names.output(out, l, vars);
         });
         vars.put("name", ni);
         names.output(out, l, vars);
+        vars.put("residenceCountry", cs);
         if (target.getReceivedAssurances().length == 0) {
             vars.put("DoB", ds);
             templ.output(out, l, vars);
         if (target.getReceivedAssurances().length == 0) {
             vars.put("DoB", ds);
             templ.output(out, l, vars);
index 55b9162856a45fa49a0e531b15648e18a4ab5cdd..aa6191e255b5b960e6c0fb77225bafd5a6aa1c2b 100644 (file)
@@ -5,4 +5,11 @@
    <button class="btn btn-primary pull-right" name="action" value="updateDoB"><?=_Update Date of Birth?></button>
   </div>
 </div>
    <button class="btn btn-primary pull-right" name="action" value="updateDoB"><?=_Update Date of Birth?></button>
   </div>
 </div>
+<div class="panel panel-default">
+  <div class="panel-heading"><?=_Residence Country?></div>
+  <div class="panel-body">
+   <?=$residenceCountry?>
+   <button class="btn btn-primary pull-right" name="action" value="updateResidenceCountry"><?=_Update Residence Country?></button>
+  </div>
+</div>
 <a href="/account/history"><?=_Show account history?></a>
 <a href="/account/history"><?=_Show account history?></a>
index 904e04b56ddb152e497934a884d071e366afcaac..0b436d66ad6559faceda1233d092f8d576ba1c4c 100644 (file)
@@ -4,4 +4,11 @@
    <?=$DoB?>
   </div>
 </div>
    <?=$DoB?>
   </div>
 </div>
+<div class="panel panel-default">
+  <div class="panel-heading"><?=_Residence Country?></div>
+  <div class="panel-body">
+   <?=$residenceCountry?>
+   <button class="btn btn-primary pull-right" name="action" value="updateResidenceCountry"><?=_Update Residence Country?></button>
+  </div>
+</div>
 <a href="/account/history"><?=_Show account history?></a>
 <a href="/account/history"><?=_Show account history?></a>
index a10a68d745beb6f3f73fd78af7191ed91c038a03..819bfd5b08286215aa3ce144195f80c03378f7e7 100644 (file)
@@ -13,6 +13,7 @@ import org.cacert.gigi.database.GigiResultSet;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.localisation.Language;
+import org.cacert.gigi.output.CountrySelector;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.NameInput;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.NameInput;
 import org.cacert.gigi.output.template.Form;
@@ -36,9 +37,12 @@ public class Signup extends Form {
 
     private boolean general = true, country = true, regional = true, radius = true;
 
 
     private boolean general = true, country = true, regional = true, radius = true;
 
+    private CountrySelector cs;
+
     public Signup(HttpServletRequest hsr) {
         super(hsr);
         ni = new NameInput();
     public Signup(HttpServletRequest hsr) {
         super(hsr);
         ni = new NameInput();
+        cs = new CountrySelector("residenceCountry", true);
     }
 
     private DateSelector myDoB = new DateSelector("day", "month", "year");
     }
 
     private DateSelector myDoB = new DateSelector("day", "month", "year");
@@ -56,6 +60,7 @@ public class Signup extends Form {
         vars.put("helpOnNames", String.format(l.getTranslation("Help on Names %sin the wiki%s"), "<a href=\"//wiki.cacert.org/FAQ/HowToEnterNamesInJoinForm\" target=\"_blank\">", "</a>"));
         vars.put("csrf", getCSRFToken());
         vars.put("dobmin", User.MINIMUM_AGE + "");
         vars.put("helpOnNames", String.format(l.getTranslation("Help on Names %sin the wiki%s"), "<a href=\"//wiki.cacert.org/FAQ/HowToEnterNamesInJoinForm\" target=\"_blank\">", "</a>"));
         vars.put("csrf", getCSRFToken());
         vars.put("dobmin", User.MINIMUM_AGE + "");
+        vars.put("countryCode", cs);
         t.output(out, l, vars);
     }
 
         t.output(out, l, vars);
     }
 
@@ -78,9 +83,13 @@ public class Signup extends Form {
         } catch (GigiApiException e) {
             problems.mergeInto(e);
         }
         } catch (GigiApiException e) {
             problems.mergeInto(e);
         }
+
+        cs.update(r);
+
         if ( !problems.isEmpty()) {
             throw problems;
         }
         if ( !problems.isEmpty()) {
             throw problems;
         }
+
     }
 
     @Override
     }
 
     @Override
@@ -178,7 +187,7 @@ public class Signup extends Form {
     }
 
     private void run(HttpServletRequest req, String password) throws GigiApiException {
     }
 
     private void run(HttpServletRequest req, String password) throws GigiApiException {
-        User u = new User(email, password, myDoB.getDate(), Page.getLanguage(req).getLocale(), ni.getNameParts());
+        User u = new User(email, password, myDoB.getDate(), Page.getLanguage(req).getLocale(), cs.getCountry(), ni.getNameParts());
 
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `alerts` SET `memid`=?," + " `general`=?, `country`=?, `regional`=?, `radius`=?")) {
             ps.setInt(1, u.getId());
 
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `alerts` SET `memid`=?," + " `general`=?, `country`=?, `regional`=?, `radius`=?")) {
             ps.setInt(1, u.getId());
@@ -189,6 +198,6 @@ public class Signup extends Form {
             ps.execute();
         }
         Notary.writeUserAgreement(u, "ToS", "account creation", "", true, 0);
             ps.execute();
         }
         Notary.writeUserAgreement(u, "ToS", "account creation", "", true, 0);
-
     }
     }
+
 }
 }
index a078f5b82bc5afac8a7b2345b60af97c784e729b..f590e45800c668c312b2aa8163edc07f50e4c59b 100644 (file)
@@ -4,21 +4,29 @@
     <th colspan="3"><?=_My Details?></th>
   </tr>
   </thead>
     <th colspan="3"><?=_My Details?></th>
   </tr>
   </thead>
+
   <tbody>
   <tr>
     <td><?=_Name?>: </td>
     <td><?=$name?></td>
     <td rowspan="4"><?=$!helpOnNames?></td>
   </tr>
   <tbody>
   <tr>
     <td><?=_Name?>: </td>
     <td><?=$name?></td>
     <td rowspan="4"><?=$!helpOnNames?></td>
   </tr>
+
   <tr>
   <tr>
-    <td><?=_Date of Birth (minimum age: ${dobmin} years)?><br>
+    <td><?=_Date of Birth?>:<br>
         (<?=_yyyy-mm-dd?>)</td>
     <td><?=$dob?></td>
         (<?=_yyyy-mm-dd?>)</td>
     <td><?=$dob?></td>
-    <td>&nbsp;</td>
+    <td><?=_The required minimum age is ${dobmin} years.?></td>
   </tr>
 
   <tr>
   </tr>
 
   <tr>
-    <td><?=_Email Address?>: </td>
+    <td><?=_Residence Country?>:</td>
+    <td><?=$countryCode?></td>
+    <td><?=_The country in which you currently reside. This information is optional and used for statistical purposes only.?></td>
+  </tr>
+
+  <tr>
+    <td><?=_Email Address?>:</td>
     <td><input type="text" name="email" size="30" value="<?=$email?>" autocomplete="off"></td>
     <td><?=_I own or am authorised to control this email address?></td>
   </tr>
     <td><input type="text" name="email" size="30" value="<?=$email?>" autocomplete="off"></td>
     <td><?=_I own or am authorised to control this email address?></td>
   </tr>
@@ -28,6 +36,7 @@
     <td><input class="form-control" type="password" name="pword1" size="30" autocomplete="off"></td>
     <td rowspan="2">&nbsp;</td>
   </tr>
     <td><input class="form-control" type="password" name="pword1" size="30" autocomplete="off"></td>
     <td rowspan="2">&nbsp;</td>
   </tr>
+
   <tr>
     <td><?=_Pass Phrase Again?><font color="red">*</font>: </td>
     <td><input class="form-control" type="password" name="pword2" size="30" autocomplete="off"></td>
   <tr>
     <td><?=_Pass Phrase Again?><font color="red">*</font>: </td>
     <td><input class="form-control" type="password" name="pword2" size="30" autocomplete="off"></td>
index b78b37263eddccb3299688963f1c972b6c8c412b..cc095e30091a0f827c842917cb3ef564ec0e665a 100644 (file)
@@ -119,7 +119,7 @@ public abstract class BusinessTest extends ConfiguredTest {
         c.set(1950, 1, 1, 0, 0, 0);
         c.set(Calendar.MILLISECOND, 0);
 
         c.set(1950, 1, 1, 0, 0, 0);
         c.set(Calendar.MILLISECOND, 0);
 
-        User u = new User(createUniqueName() + "@email.com", TEST_PASSWORD, new DayDate(c.getTimeInMillis()), Locale.ENGLISH, //
+        User u = new User(createUniqueName() + "@email.com", TEST_PASSWORD, new DayDate(c.getTimeInMillis()), Locale.ENGLISH, null, //
                 new NamePart(NamePartType.FIRST_NAME, "a"), new NamePart(NamePartType.FIRST_NAME, "m"), new NamePart(NamePartType.LAST_NAME, "c"));
         InVMEmail.getInstance().mails.poll().verify();
         return u;
                 new NamePart(NamePartType.FIRST_NAME, "a"), new NamePart(NamePartType.FIRST_NAME, "m"), new NamePart(NamePartType.LAST_NAME, "c"));
         InVMEmail.getInstance().mails.poll().verify();
         return u;
@@ -140,7 +140,7 @@ public abstract class BusinessTest extends ConfiguredTest {
         c.set(1950, 1, 1, 0, 0, 0);
         c.set(Calendar.MILLISECOND, 0);
 
         c.set(1950, 1, 1, 0, 0, 0);
         c.set(Calendar.MILLISECOND, 0);
 
-        User u = new User(mail, pw, new DayDate(c.getTimeInMillis()), Locale.ENGLISH,//
+        User u = new User(mail, pw, new DayDate(c.getTimeInMillis()), Locale.ENGLISH, null, //
                 new NamePart(NamePartType.FIRST_NAME, f), new NamePart(NamePartType.LAST_NAME, l));
         return u;
     }
                 new NamePart(NamePartType.FIRST_NAME, f), new NamePart(NamePartType.LAST_NAME, l));
         return u;
     }
index f599fcd6b2835cc44bb3f7a039c25bc0c40a7535..52d25be6f1f92ef1a51d00e002ec0dc41d660e33 100644 (file)
@@ -227,7 +227,7 @@ public class Manager extends Page {
         Calendar gc = GregorianCalendar.getInstance();
         gc.setTimeInMillis(0);
         gc.set(1990, 0, 1);
         Calendar gc = GregorianCalendar.getInstance();
         gc.setTimeInMillis(0);
         gc.set(1990, 0, 1);
-        User u = new User(email, "xvXV12°§", new DayDate(gc.getTime().getTime()), Locale.ENGLISH, //
+        User u = new User(email, "xvXV12°§", new DayDate(gc.getTime().getTime()), Locale.ENGLISH, null, //
                 new NamePart(NamePartType.FIRST_NAME, "Först"), new NamePart(NamePartType.FIRST_NAME, "Müddle"),//
                 new NamePart(NamePartType.LAST_NAME, "Läst"), new NamePart(NamePartType.SUFFIX, "Süffix"));
         EmailAddress ea = u.getEmails()[0];
                 new NamePart(NamePartType.FIRST_NAME, "Först"), new NamePart(NamePartType.FIRST_NAME, "Müddle"),//
                 new NamePart(NamePartType.LAST_NAME, "Läst"), new NamePart(NamePartType.SUFFIX, "Süffix"));
         EmailAddress ea = u.getEmails()[0];